- 1. 论文概述
- 2. 背景:CNN主导的Computer Vision时代
- 3. 核心思想:将图像转换为patch序列
- 4. 架构详细分析
- 5. 数学分析:从patch到预测
- 6. 模型变体:ViT-Base、Large、Huge
- 7. 训练策略
- 8. 实验结果
- 9. 核心发现与洞察
- 10. PyTorch核心实现
- 11. 后续研究全面梳理
- 12. ViT vs CNN vs Hybrid对比
- 13. Computer Vision的未来:Foundation Models
- 14. References
1. 论文概述
《An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale》是2020年10月由Google Research的Alexey Dosovitskiy、Lucas Beyer、Alexander Kolesnikov等人发表、并在ICLR 2021正式收录的论文。该论文证明了在NLP领域取得压倒性成功的Transformer架构,几乎无需修改,即可直接应用于Computer Vision的图像分类任务。
核心思想简单得惊人:将图像分割成固定大小的patch,把每个patch当作NLP中的token来处理,输入标准的Transformer Encoder。论文标题本身就直观地说明了这一点——一张图像由16x16大小的单词组成。
结果具有颠覆性。在JFT-300M这一大规模数据集上预训练的ViT-H/14模型,在ImageNet上达到了88.55% top-1 accuracy,超越了现有基于CNN的SOTA(State-of-the-Art)模型BiT(Big Transfer)与Noisy Student。更重要的是,达到这一结果所需的训练成本远低于现有方法这一点。
这篇论文在Computer Vision领域引发了一场范式转移(paradigm shift)。ViT之后,DeiT、Swin Transformer、BEiT、MAE、DINO等无数后续研究相继涌现,「Vision Transformer」这一全新研究领域由此诞生。
2. 背景:CNN主导的Computer Vision时代
2.1 Convolutional Neural Network的黄金时代
2012年AlexNet在ImageNet Challenge夺冠之后,CNN事实上成为了Computer Vision领域唯一的架构。从VGGNet(2014)、GoogLeNet/Inception(2014)、ResNet(2015)、DenseNet(2017)到EfficientNet(2019),这一脉络都共享Convolution运算作为核心。
CNN之所以能在Vision任务中取得成功,根本原因在于两种Inductive Bias(归纳偏置)。
第一,Locality(局部性)。 Convolution Filter只处理输入的局部区域,这在架构层面内置了「图像中相邻像素具有强相关性」这一事实。
第二,Translation Equivariance(平移等变性)。 由于相同的filter被共享应用于图像的所有位置,无论物体位于图像中的什么位置,都能提取相同的特征。
得益于这两种偏置,CNN即使用相对较少的数据也能有效学习视觉模式。
2.2 NLP中的Transformer革命
2017年《Attention Is All You Need》论文发表后,NLP领域发生了彻底的变革。从BERT(2018)、GPT-2(2019)、T5(2019)到GPT-3(2020),基于Transformer的模型几乎横扫了所有NLP基准测试。
Transformer的核心优势如下:
- 通过Self-Attention实现Global Receptive Field:序列内任意两个位置之间都可以直接交互
- 出色的并行处理能力:与RNN不同,可以同时处理序列中的所有位置
- 卓越的可扩展性(Scalability):模型规模和数据量增加时,性能会持续提升,呈现出Scaling Law
2.3 将Transformer应用于Vision的早期尝试
在ViT之前,也有一些将Attention机制引入Vision的尝试,代表性的包括:
- Non-local Neural Networks(Wang et al., 2018):在CNN内部插入Self-Attention模块,以捕捉Long-range Dependency
- Stand-Alone Self-Attention(Ramachandran et al., 2019):用Local Self-Attention替代Convolution
- DETR(Carion et al., 2020):在Object Detection中使用Transformer Decoder
不过,这些方法要么将CNN与Attention进行混合(hybrid),要么使用了特殊设计的Attention。ViT的创新之处在于,没有做出这样的折中,而是将标准Transformer以最小的修改直接应用于Vision。
3. 核心思想:将图像转换为patch序列
3.1 为什么不能把图像直接输入Transformer
标准Transformer接收1D token序列作为输入。假设把图像按像素逐个输入Transformer:224x224分辨率的图像有50,176个像素。Self-Attention的计算复杂度相对于序列长度 为 ,因此对50,176个token做Self-Attention大约需要25亿次运算,这在现实中是不可行的。
3.2 通过分割patch缩短序列长度
ViT的解法既优雅又直观:将图像分割为固定大小的patch,把每个patch当作一个token处理。
将224x224的图像分割为16x16大小的patch,patch数量如下:
不再需要处理50,176个像素,只需处理196个patch token。Self-Attention的复杂度为 ,相比像素级别减少了约65,000倍。
这一转换的核心前提是:一个16x16的patch可以作为与NLP中的一个单词(word)等价的语义单位来发挥作用。 正如自然语言是由单词这种离散token组成的序列一样,图像也可以表示为由patch这种视觉token组成的序列。
3.3 与NLP的对应关系
| NLP | Vision(ViT) |
|---|---|
| 句子(Sentence) | 图像(Image) |
| 单词(Word/Token) | 图像patch(Patch) |
| 词汇(Vocabulary) | 可能的patch模式空间 |
| Token Embedding | Patch Embedding (Linear Projection) |
| Position Embedding | Position Embedding (1D Learnable) |
| [CLS] Token | [CLS] Token |
| Transformer Encoder | Transformer Encoder(相同) |
这一对应关系几乎可以说就是ViT的全部。将NLP Transformer中已验证的结构照搬过来,且只做了最小的改动,这正是ViT的本质。
4. 架构详细分析
4.1 整体流程概览
ViT的整体处理过程如下:
- 将输入图像分割为固定大小的patch
- 将每个patch展平(flatten)为1D向量
- 通过Linear Projection将patch向量转换为D维Embedding
- 在序列开头添加可学习的[CLS] token
- 加上Position Embedding以注入位置信息
- 输入标准Transformer Encoder
- 用[CLS] token的最终输出进行分类
输入图像 (224x224x3)
|
v
patch分割 (196个16x16x3的patch)
|
v
Flatten (196个768维向量)
|
v
Linear Projection (196个D维Embedding)
|
v
[CLS] Token Prepend (197个D维向量)
|
v
加上Position Embedding (197个D维向量)
|
v
Transformer Encoder (L个block)
|
v
提取[CLS] Token输出
|
v
Classification Head (MLP) → 类别预测
4.2 Patch Embedding:将图像转为token
4.2.1 patch分割与展平
输入图像 被分割为 大小的patch。每个patch被展平为 。
例如,将224x224x3(RGB)的图像分割为16x16的patch时:
- patch数量:
- 每个patch展平后的向量维度:
4.2.2 Linear Projection
对展平后的每个patch向量,应用可学习的Linear Projection ,将其映射到D维Embedding空间。
这里的 是Transformer的Hidden Dimension。对ViT-Base而言 ,因此这里的Linear Projection是一个768x768的矩阵。
有趣的是,这个Linear Projection实际上等价于stride与patch size相同的Convolution运算。也就是说,它在数学上与Conv2d(in_channels=3, out_channels=D, kernel_size=P, stride=P)完全相同。实际实现中这种方式效率更高,因此通常采用Convolution来实现。
4.3 [CLS] Token与Classification Head
4.3.1 [CLS] Token
这是借用自BERT的概念:在patch Embedding序列的最前面,添加一个可学习的特殊token 。
这个[CLS] token通过Transformer的Self-Attention与所有patch token交互,从而学习到整张图像的全局表示(global representation)。Transformer Encoder最后一层中,这个[CLS] token的输出 被用作代表整张图像的向量。
4.3.2 Classification Head
在预训练(pre-training)阶段,会在[CLS] token输出后接一个带有1个Hidden Layer的MLP Head。在微调(fine-tuning)阶段,则只使用一个Linear Layer。
论文中也实验了用patch token的Global Average Pooling(GAP)代替[CLS] token的方法,报告称其性能与[CLS] token相近。之所以将[CLS] token作为默认选择,是为了与NLP Transformer保持一致性。
4.4 Position Embedding:注入位置信息
4.4.1 为什么需要Position Embedding
Self-Attention本质上是顺序不变(permutation invariant)的:即便打乱输入token的顺序,输出也只会被同样地重新排列。但在图像中,patch的空间位置是重要信息——图像左上角的patch和右下角的patch具有不同的空间意义。
4.4.2 1D Learnable Position Embedding
ViT使用可学习的1D Position Embedding ,其中 是包含[CLS] token在内的整个序列长度。
论文中比较了2D Position Embedding(分别编码patch的行/列位置)的实验,发现1D与2D Position Embedding之间没有显著的性能差异。这说明ViT可以从1D Position Embedding中自行学习到2D空间结构。
实际将学习到的Position Embedding可视化后(论文Figure 7)可以看到,空间上相近的patch的Position Embedding呈现出较高的余弦相似度,行与列的结构也自然地显现出来。这是一个令人印象深刻的结果,表明模型从数据中自动学习到了2D位置关系。
4.5 Transformer Encoder
4.5.1 结构
ViT直接使用标准的Transformer Encoder。每个block的结构如下:
其中:
- LN:Layer Normalization(Pre-norm方式,与原始Transformer的Post-norm不同)
- MSA:Multi-head Self-Attention
- MLP:Feed-Forward Network
- Residual Connection:将输入加到每个子block的输出上
ViT与原始Transformer的不同之处在于采用了Pre-norm。在原始的《Attention Is All You Need》中,Layer Normalization应用在Sub-layer输出之后(Post-norm),而ViT则应用在Sub-layer输入之前(Pre-norm)。已知Pre-norm具有更高的训练稳定性。
4.5.2 Multi-head Self-Attention (MSA)
MSA将输入分割为 个Head,各自独立执行Self-Attention后再合并。
每个Head的维度为 。在ViT-Base中,,,因此 。
4.5.3 MLP(Feed-Forward Network)
MLP由两个Linear Layer和GELU激活函数组成。
Hidden Dimension通常设置为Embedding Dimension 的4倍()。ViT-Base的情况下为 。
之所以用GELU(Gaussian Error Linear Unit)代替原始Transformer使用的ReLU,是沿用了BERT的设计。
5. 数学分析:从patch到预测
将整个过程用数学方式整理如下。
5.1 输入处理
给定图像 :
Step 1. patch分割与展平:
Step 2. Patch Embedding + [CLS] Token + Position Embedding:
其中 ,
5.2 Transformer Encoder
Step 3. 重复 个Transformer block:
5.3 输出
Step 4. 用[CLS] token输出进行分类:
5.4 计算复杂度分析
对于序列长度 、Embedding维度 ,主要运算的复杂度如下。
| 运算 | 复杂度 |
|---|---|
| Patch Embedding | |
| Self-Attention(生成QKV) | |
| Self-Attention(计算Attention) | |
| MLP | |
| 整个Transformer Block |
序列长度 对应的 复杂度,是限制ViT分辨率可扩展性的核心瓶颈。这也是后来Swin Transformer等引入Windowed Attention的动机。
6. 模型变体:ViT-Base、Large、Huge
ViT沿用了BERT的设计惯例,定义了三种规模的模型。模型名称斜杠后的数字表示patch大小(例如ViT-B/16表示使用16x16的patch)。
| 项目 | ViT-Base (ViT-B) | ViT-Large (ViT-L) | ViT-Huge (ViT-H) |
|---|---|---|---|
| Layers () | 12 | 24 | 32 |
| Hidden Dim () | 768 | 1024 | 1280 |
| MLP Dim | 3072 | 4096 | 5120 |
| Attention Heads () | 12 | 16 | 16 |
| Parameters | ~86M | ~307M | ~632M |
| Head Dim () | 64 | 64 | 80 |
6.1 按patch大小划分的变体
即便架构相同,patch大小不同也会导致性能与计算量出现较大差异。
| 模型 | patch大小 | 序列长度 (224x224) | 序列长度 (384x384) |
|---|---|---|---|
| ViT-B/32 | 32x32 | 49 | 144 |
| ViT-B/16 | 16x16 | 196 | 576 |
| ViT-L/16 | 16x16 | 196 | 576 |
| ViT-H/14 | 14x14 | 256 | 784 |
patch越小,越能捕捉细粒度(fine-grained)的视觉信息,但序列长度增加会使计算成本以 急剧上升。ViT-H/14的14x14 patch产生的序列长度,约是ViT-B/32的32x32 patch的27倍。
6.2 Hybrid模型
论文中也实验了结合CNN与Transformer的Hybrid模型:用ResNet的中间Feature Map代替patch Embedding。例如,将ResNet-50 stage 4的输出(14x14 Feature Map)当作1x1的patch输入Transformer。
实验结果显示,当预训练数据较少时,Hybrid模型优于纯ViT;但当数据规模足够大时,纯ViT便追上了Hybrid模型。
7. 训练策略
7.1 预训练(Pre-training)
ViT的训练策略沿用了NLP中「预训练+微调」的范式。
数据集:
- ImageNet-1K:约130万张图像,1,000个类别
- ImageNet-21K:约1,400万张图像,21,843个类别
- JFT-300M:Google内部数据集,约3亿张图像,18,291个类别
预训练设置:
- Optimizer:Adam(,)
- Batch Size:4,096
- Weight Decay:0.1
- Linear Learning Rate Warmup + Cosine Decay
- 分辨率:224x224
论文的核心发现之一是:预训练数据的规模对ViT的性能起决定性作用。仅用ImageNet-1K时不敌CNN,但在JFT-300M规模下则超越了CNN。
7.2 微调(Fine-tuning)
微调时会移除预训练好的Classification Head,附加一个适配目标任务的新Linear Layer。
高分辨率微调的核心技巧:
在比预训练(224x224)更高的分辨率(384x384或512x512)下微调,可以提升性能。但分辨率变化会导致patch数量(序列长度)发生变化,因此预训练好的Position Embedding无法直接沿用。
为解决这一问题,需要应用2D插值(Interpolation)。先将预训练好的Position Embedding还原为原始的2D网格形式,再按照新的分辨率通过Bicubic Interpolation调整大小。
示例:224x224预训练(14x14网格)→ 384x384微调(24x24网格)
预训练Position Embedding (14x14 = 196个)
|
v
重构为2D网格 (14 x 14)
|
v
Bicubic Interpolation → (24 x 24)
|
v
重新展平为1D (24x24 = 576个)
这种Position Embedding插值方法,此后几乎被所有Vision Transformer采纳为标准技巧。
7.3 训练成本
| 模型 | 预训练数据 | TPUv3-core-days |
|---|---|---|
| ViT-B/16 | JFT-300M | 未提供 |
| ViT-L/16 | JFT-300M | 未提供 |
| ViT-H/14 | JFT-300M | 2,500 |
| BiT-L (ResNet152x4) | JFT-300M | 9,900 |
| Noisy Student (EfficientNet-L2) | JFT-300M + ImageNet | 12,300 |
ViT-H/14所需的训练成本,约为BiT-L的1/4、Noisy Student的1/5,却取得了更高的性能。这体现了Transformer出色的扩展效率。
8. 实验结果
8.1 主要基准测试结果
论文Table 2中报告的核心结果整理如下。
| 模型 | Pre-train | ImageNet | ImageNet-ReaL | CIFAR-10 | CIFAR-100 | Oxford Pets | Oxford Flowers |
|---|---|---|---|---|---|---|---|
| ViT-H/14 | JFT-300M | 88.55 | 90.72 | 99.50 | 94.55 | 97.56 | 99.68 |
| ViT-L/16 | JFT-300M | 87.76 | 90.54 | 99.42 | 93.90 | 97.32 | 99.74 |
| ViT-L/16 | ImageNet-21K | 85.30 | 88.62 | 99.15 | 93.25 | 94.67 | 99.61 |
| BiT-L (ResNet152x4) | JFT-300M | 87.54 | 90.54 | 99.37 | 93.51 | 96.62 | 99.63 |
| Noisy Student | JFT-300M | 88.4 | 90.55 | - | - | - | - |
8.2 VTAB基准测试
VTAB(Visual Task Adaptation Benchmark)将19种多样化的Vision任务划分为Natural、Specialized、Structured三个类别。每个任务仅使用1,000个训练样本来评估模型的泛化能力。
| 模型 | Natural | Specialized | Structured | 整体 |
|---|---|---|---|---|
| ViT-H/14 (JFT) | 79.39 | 84.23 | 69.27 | 77.63 |
| ViT-L/16 (JFT) | 76.28 | 83.36 | 64.72 | 74.78 |
| BiT-L (JFT) | 76.29 | 84.92 | 66.51 | 75.90 |
ViT-H/14在Natural和Structured类别中表现最佳,在Specialized类别中则与BiT-L基本持平。整体VTAB得分77.63,在当时是最高纪录。
8.3 预训练数据规模与性能的关系
论文中最重要的实验之一,是分析了性能随预训练数据规模变化的情况(Figure 3、4)。
| 预训练数据 | ViT-L/16 ImageNet Acc | BiT-L ImageNet Acc | 胜者 |
|---|---|---|---|
| ImageNet-1K (~1.3M) | ~76.5% (scratch) | ~80% (scratch) | BiT (CNN) |
| ImageNet-21K (~14M) | 85.30% | 84.02% | ViT |
| JFT-300M (~303M) | 87.76% | 87.54% | ViT |
这一结果展现了明确的规律:
- 小规模数据:CNN的Inductive Bias(Locality、Translation Equivariance)发挥有利作用,CNN获胜
- 大规模数据:Transformer直接从数据中学习到这些模式,超越CNN
9. 核心发现与洞察
9.1 Inductive Bias的双刃剑
CNN的Inductive Bias——Locality与Translation Equivariance——在小规模数据下起到了有效的正则化(regularization)作用,因为它能引导模型即便用少量数据也能学到正确的特征。
但当数据足够多时,这种Inductive Bias反而成为限制模型表达能力的枷锁。Transformer无需任何特殊的结构假设,就能通过Self-Attention从数据中学习到包括Locality和Translation Equivariance在内的更通用、更灵活的模式。
这再次印证了AI领域一条古老的教训:只要有足够的数据,更通用(less biased)的模型就会超越更特化(more biased)的模型。
9.2 Attention Map可视化
9.2.1 Position Embedding相似度
将学习到的Position Embedding的余弦相似度可视化后(论文Figure 7左侧)可以看到,每个patch位置的Embedding与空间上相近的patch之间呈现出较高的相似度。进一步地,处于同一行或同一列的patch之间,也呈现出明显的相似度规律。
这表明,尽管只使用了1D Position Embedding,模型依然自动学习到了2D空间结构。
9.2.2 Attention Distance
论文Figure 7右侧分析了每个Transformer层中,各Attention Head的平均Attention Distance。Attention Distance是指用Attention Weight加权后,Query-Key patch之间的平均像素距离。
核心发现:
- 底层(Lower Layers):部分Head关注相邻patch,部分Head关注较远的patch——与CNN早期层类似的Local模式与Global模式并存
- 高层(Higher Layers):大部分Head将注意力分散到更广的范围——实现Global信息的整合
这表明,ViT从第一层开始就能利用Global信息,这一点与CNN有根本性的不同。在CNN中,Receptive Field要随着层数加深才逐渐扩大,而ViT从第一层起就能对整张图像进行Attention。
9.3 Representation质量分析
在Linear Probing(仅在冻结的Feature上训练Linear Classifier)实验中,ViT的性能相对低于CNN,但在Fine-tuning中却取得了更高的性能。这说明ViT学习到的是不同类型的Feature表示——ViT的Feature可能蕴含着通过Fine-tuning才能被激活的更丰富的信息。
10. PyTorch核心实现
用PyTorch实现ViT的核心结构如下。这里尽量忠实地还原了论文的实现,同时也照顾了可读性。
10.1 Patch Embedding
import torch
import torch.nn as nn
class PatchEmbedding(nn.Module):
"""将图像分割为patch,并通过Linear Projection做Embedding。"""
def __init__(
self,
img_size: int = 224,
patch_size: int = 16,
in_channels: int = 3,
embed_dim: int = 768,
):
super().__init__()
self.img_size = img_size
self.patch_size = patch_size
self.num_patches = (img_size // patch_size) ** 2
# 使用Conv2d实现Patch Embedding
# 将stride设为patch_size,即与Linear Projection等价
self.projection = nn.Conv2d(
in_channels,
embed_dim,
kernel_size=patch_size,
stride=patch_size,
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# x: (B, C, H, W)
# projection output: (B, embed_dim, H/P, W/P)
x = self.projection(x)
# flatten spatial dims and transpose: (B, num_patches, embed_dim)
x = x.flatten(2).transpose(1, 2)
return x
10.2 Multi-head Self-Attention
class MultiHeadSelfAttention(nn.Module):
"""Multi-Head Self-Attention模块。"""
def __init__(self, embed_dim: int = 768, num_heads: int = 12, dropout: float = 0.0):
super().__init__()
self.num_heads = num_heads
self.head_dim = embed_dim // num_heads
self.scale = self.head_dim ** -0.5 # 1/sqrt(d_k)
# 一次性生成Q, K, V
self.qkv = nn.Linear(embed_dim, embed_dim * 3)
self.proj = nn.Linear(embed_dim, embed_dim)
self.attn_dropout = nn.Dropout(dropout)
self.proj_dropout = nn.Dropout(dropout)
def forward(self, x: torch.Tensor) -> torch.Tensor:
B, N, D = x.shape
# 生成QKV: (B, N, 3*D) -> (B, N, 3, num_heads, head_dim)
qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim)
qkv = qkv.permute(2, 0, 3, 1, 4) # (3, B, num_heads, N, head_dim)
q, k, v = qkv.unbind(0) # 各为 (B, num_heads, N, head_dim)
# Scaled Dot-Product Attention
attn = (q @ k.transpose(-2, -1)) * self.scale # (B, num_heads, N, N)
attn = attn.softmax(dim=-1)
attn = self.attn_dropout(attn)
# 与Value做加权求和
x = (attn @ v).transpose(1, 2).reshape(B, N, D) # (B, N, D)
x = self.proj(x)
x = self.proj_dropout(x)
return x
10.3 Transformer Encoder Block
class TransformerBlock(nn.Module):
"""ViT Transformer Encoder Block (Pre-norm)。"""
def __init__(
self,
embed_dim: int = 768,
num_heads: int = 12,
mlp_ratio: float = 4.0,
dropout: float = 0.0,
):
super().__init__()
self.norm1 = nn.LayerNorm(embed_dim)
self.attn = MultiHeadSelfAttention(embed_dim, num_heads, dropout)
self.norm2 = nn.LayerNorm(embed_dim)
self.mlp = nn.Sequential(
nn.Linear(embed_dim, int(embed_dim * mlp_ratio)),
nn.GELU(),
nn.Dropout(dropout),
nn.Linear(int(embed_dim * mlp_ratio), embed_dim),
nn.Dropout(dropout),
)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# Pre-norm + MSA + Residual
x = x + self.attn(self.norm1(x))
# Pre-norm + MLP + Residual
x = x + self.mlp(self.norm2(x))
return x
10.4 完整ViT模型
class VisionTransformer(nn.Module):
"""Vision Transformer (ViT) 完整模型。"""
def __init__(
self,
img_size: int = 224,
patch_size: int = 16,
in_channels: int = 3,
num_classes: int = 1000,
embed_dim: int = 768,
depth: int = 12,
num_heads: int = 12,
mlp_ratio: float = 4.0,
dropout: float = 0.0,
):
super().__init__()
self.patch_embed = PatchEmbedding(img_size, patch_size, in_channels, embed_dim)
num_patches = self.patch_embed.num_patches
# 可学习的[CLS] Token
self.cls_token = nn.Parameter(torch.zeros(1, 1, embed_dim))
# 可学习的Position Embedding ([CLS] + patches)
self.pos_embed = nn.Parameter(torch.zeros(1, num_patches + 1, embed_dim))
self.pos_dropout = nn.Dropout(dropout)
# Transformer Encoder
self.blocks = nn.Sequential(
*[
TransformerBlock(embed_dim, num_heads, mlp_ratio, dropout)
for _ in range(depth)
]
)
self.norm = nn.LayerNorm(embed_dim)
# Classification Head
self.head = nn.Linear(embed_dim, num_classes)
# 初始化
nn.init.trunc_normal_(self.pos_embed, std=0.02)
nn.init.trunc_normal_(self.cls_token, std=0.02)
self.apply(self._init_weights)
def _init_weights(self, m: nn.Module):
if isinstance(m, nn.Linear):
nn.init.trunc_normal_(m.weight, std=0.02)
if m.bias is not None:
nn.init.zeros_(m.bias)
elif isinstance(m, nn.LayerNorm):
nn.init.ones_(m.weight)
nn.init.zeros_(m.bias)
def forward(self, x: torch.Tensor) -> torch.Tensor:
B = x.shape[0]
# Step 1: Patch Embedding
x = self.patch_embed(x) # (B, num_patches, embed_dim)
# Step 2: [CLS] Token Prepend
cls_tokens = self.cls_token.expand(B, -1, -1) # (B, 1, embed_dim)
x = torch.cat([cls_tokens, x], dim=1) # (B, num_patches + 1, embed_dim)
# Step 3: Position Embedding
x = x + self.pos_embed
x = self.pos_dropout(x)
# Step 4: Transformer Encoder
x = self.blocks(x)
x = self.norm(x)
# Step 5: 用[CLS] Token进行分类
cls_output = x[:, 0] # (B, embed_dim)
logits = self.head(cls_output) # (B, num_classes)
return logits
# 生成各模型变体的函数
def vit_base_patch16_224(**kwargs):
return VisionTransformer(
img_size=224, patch_size=16, embed_dim=768,
depth=12, num_heads=12, **kwargs,
)
def vit_large_patch16_224(**kwargs):
return VisionTransformer(
img_size=224, patch_size=16, embed_dim=1024,
depth=24, num_heads=16, **kwargs,
)
def vit_huge_patch14_224(**kwargs):
return VisionTransformer(
img_size=224, patch_size=14, embed_dim=1280,
depth=32, num_heads=16, **kwargs,
)
10.5 使用示例
# 创建ViT-Base/16模型
model = vit_base_patch16_224(num_classes=1000)
# 查看参数量
total_params = sum(p.numel() for p in model.parameters())
print(f"Total parameters: {total_params:,}")
# 输出: Total parameters: 86,567,656
# 推理
dummy_input = torch.randn(1, 3, 224, 224)
output = model(dummy_input)
print(f"Output shape: {output.shape}")
# 输出: Output shape: torch.Size([1, 1000])
11. 后续研究全面梳理
ViT成为了Vision Transformer这一庞大研究浪潮的起点。以下按时间顺序整理其后出现的主要后续研究。
11.1 DeiT: Data-efficient Image Transformers (2020.12)
论文:《Training data-efficient image transformers & distillation through attention》(Touvron et al., Facebook AI)
核心贡献:克服了ViT最大的局限——对大规模数据的依赖——提出了仅用ImageNet-1K就能有效训练ViT的方法。
主要技巧:
- Knowledge Distillation Token:在[CLS] token之外额外添加一个Distillation Token,从而有效传递Teacher模型(CNN)的知识
- Hard Distillation:使用Teacher的Hard Label(argmax预测)来训练Student
- 有趣的是,CNN Teacher比Transformer Teacher更有效——CNN的Inductive Bias通过Distillation被传递给了Transformer
结果:
- DeiT-B:在ImageNet-1K上取得83.1% top-1 accuracy(未使用外部数据)
- DeiT-B distilled:85.2%(使用RegNetY-16GF Teacher)
- 未使用任何外部数据,就超越了ViT-B/16 JFT-300M pre-trained的84.15%
11.2 Swin Transformer (2021.03)
论文:《Swin Transformer: Hierarchical Vision Transformer using Shifted Windows》(Liu et al., Microsoft Research)
核心贡献:同时解决了ViT的两个根本性局限—— 复杂度与Single-scale Feature。
主要技巧:
- Window-based Self-Attention:将图像分割为固定大小的窗口(7x7 patch),仅在窗口内部执行Self-Attention,使复杂度从 降至 (相对于图像尺寸呈线性)
- Shifted Window:在连续的层之间移动窗口位置,使窗口之间可以交换信息
- Hierarchical Feature Map:随着层数加深,通过合并patch(Patch Merging)将分辨率减半、通道数翻倍,提供类似CNN Feature Pyramid的multi-scale feature
结果:
- Swin-L:在ImageNet-1K上取得87.3% top-1 accuracy(经ImageNet-22K预训练)
- COCO Object Detection:58.7 box AP、51.1 mask AP
- ADE20K Semantic Segmentation:53.5 mIoU
Swin Transformer成为了比ViT更通用的Backbone,广泛用于Object Detection、Semantic Segmentation等Dense Prediction任务。
11.3 BEiT: BERT Pre-Training of Image Transformers (2021.06)
论文:《BEiT: BERT Pre-Training of Image Transformers》(Bao et al., Microsoft Research)
核心贡献:首次将NLP中BERT风格的Masked Language Modeling成功应用于Vision。
主要技巧:
- Masked Image Modeling (MIM):遮蔽(mask)图像patch的一部分(约40%),预测被遮蔽patch的Visual Token
- Visual Tokenizer:使用dVAE(discrete Variational Autoencoder)将图像转换为离散的Visual Token——相当于NLP中的词汇(vocabulary)
- 两种视角(View):原始图像patch(输入)与Visual Token(预测目标)
结果:
- BEiT-B:在ImageNet-1K上取得83.2%(Self-supervised pre-training + Fine-tuning)
- BEiT-L:在ImageNet-1K上取得86.3%(仅使用ImageNet-1K数据)
- 相较DeiT-B的81.8%提升了+1.4%(相同的Base模型规模)
11.4 MAE: Masked Autoencoders (2021.11)
论文:《Masked Autoencoders Are Scalable Vision Learners》(He et al., Facebook AI Research)
核心贡献:将Self-supervised Vision Pre-training的效率与可扩展性发挥到极致,提出了简单却强大的预训练框架。
主要技巧:
- 高遮蔽比例:遮蔽输入patch的75%——远高于NLP(15%),原因在于图像具有更高的信息冗余度
- 非对称Encoder-Decoder:Encoder只处理未被遮蔽的patch(全部的25%)以最大化效率,再用轻量的Decoder重建被遮蔽的像素
- 像素级重建:与BEiT不同,不使用Visual Tokenizer,而是直接重建被遮蔽patch的原始像素值
结果:
- MAE(ViT-H):在ImageNet-1K上取得87.8%(仅使用ImageNet-1K数据)
- 训练效率:由于Encoder仅处理全部patch的25%,训练时间缩短3倍以上
- 远优于不做预训练、直接从头训练ViT的效果
11.5 DINO / DINOv2 (2021.04 / 2023.04)
DINO论文:《Emerging Properties in Self-Supervised Vision Transformers》(Caron et al., Facebook AI Research)
DINOv2论文:《DINOv2: Learning Robust Visual Features without Supervision》(Oquab et al., Meta AI)
DINO核心技巧:
- Self-Distillation:Teacher与Student拥有完全相同的网络结构,Teacher是Student的Exponential Moving Average(EMA)
- Multi-crop策略:交替输入Global View(完整图像)与Local View(较小的裁剪区域)
- 发现:Self-supervised ViT的Self-Attention Map无需显式训练,就能获得Object Segmentation能力
DINOv2核心技巧:
- 自动构建大规模Curated Dataset(LVD-142M)的流水线
- 先训练一个1B参数的Teacher模型,再通过Knowledge Distillation蒸馏到较小的Student模型
- 不使用文本、不使用标签,学习通用的视觉表示(Universal Visual Feature)
结果:
- DINO(ViT-B):在ImageNet Linear Probing上取得80.1%
- DINOv2:在大多数基准测试中超越OpenCLIP的通用Visual Feature
11.6 EVA / EVA-02 (2022 / 2023)
EVA论文:《EVA: Exploring the Limits of Masked Visual Representation Learning at Scale》(Fang et al., BAAI)
EVA-02论文:《EVA-02: A Visual Representation for Neon Genesis》(Fang et al., BAAI)
核心技巧:
- Masked Image Modeling + 以CLIP Feature作为重建目标
- 学习Language-aligned Visual Feature,在Vision-Language任务中也表现出色
- 提出了高效训练大规模ViT的技巧
结果:
- EVA(ViT-g):在ImageNet上取得89.6%(336x336)
- EVA-02:以304M参数在ImageNet上取得90.0%(仅使用公开数据)
- EVA-02-CLIP:Zero-shot ImageNet 80.4%(参数量仅为此前最佳CLIP的1/6)
11.7 ConvNeXt:CNN的反击 (2022.01)
论文:《A ConvNet for the 2020s》(Liu et al., Facebook AI Research / UC Berkeley)
核心贡献:证明了把Transformer的设计原则系统性地应用于纯CNN之后,CNN也能取得与Transformer相当的性能。这是对「CNN真的逊色吗?」这一问题的有力反驳。
应用于ResNet的Transformer设计要素:
- Macro Design:调整Stage Ratio(ResNet的3:4:6:3 → Swin-T的1:1:3:1)
- 将Stem替换为Patchify(4x4 Conv, stride 4)
- ResNeXt-style Grouped Convolution → Depthwise Convolution
- Inverted Bottleneck(MobileNetV2风格)
- 7x7 Large Kernel(对应Swin Transformer的7x7 Window)
- BN → LayerNorm、ReLU → GELU等激活/归一化方式的调整
结果:
- ConvNeXt-B:在ImageNet-1K上取得85.1%(较Swin-B的84.5%提升+0.6%,推理速度快12.5%)
- ConvNeXt-L:经ImageNet-22K预训练后取得87.8%
- 不仅性能,处理量(throughput)也与Swin Transformer相当或更优
12. ViT vs CNN vs Hybrid对比
12.1 综合对比表
| 特性 | CNN(ResNet系列) | ViT(纯Transformer) | Hybrid(CNN + Transformer) |
|---|---|---|---|
| Inductive Bias | 强(Locality、Translation Equivariance) | 几乎没有 | 中等(部分借用自CNN) |
| 小规模数据性能 | 优秀 | 较差 | 优秀 |
| 大规模数据性能 | 良好 | 最佳 | 非常好 |
| 计算复杂度(相对分辨率) | |||
| Multi-scale Feature | 天然具备(Feature Pyramid) | 缺乏(Single-scale) | 多样 |
| Global Receptive Field | 需堆叠多层才能获得 | 从第一层起即可获得 | CNN之后可获得 |
| Dense Prediction适用性 | 高 | 低(需要后处理) | 中~高 |
| 训练效率(按FLOPs计的性能) | 良好 | 大规模下最佳 | 良好 |
| 实现与优化成熟度 | 非常高 | 快速走向成熟 | 中等 |
| 代表模型 | ResNet、EfficientNet、ConvNeXt | ViT、DeiT、BEiT | Swin Transformer、CoAtNet |
12.2 各任务推荐架构(截至2026年)
| 任务 | 推荐架构 | 依据 |
|---|---|---|
| Image Classification(大规模) | ViT + MAE/DINO pre-training | 在大规模数据下性能最佳 |
| Image Classification(小规模) | DeiT(Distillation)或ConvNeXt | 数据效率高 |
| Object Detection | Swin Transformer + FPN系列 | 必须具备Multi-scale Feature |
| Semantic Segmentation | Swin / SegFormer / DINOv2 | 适合Dense Prediction |
| Vision-Language | ViT + CLIP-style pre-training | 具备Language-aligned Feature |
| Edge/Mobile部署 | EfficientNet / MobileViT | 需要轻量化 |
| Self-supervised Pre-training | MAE / DINOv2 | 无需标签、可扩展性强 |
13. Computer Vision的未来:Foundation Models
13.1 Vision Foundation Model的出现
ViT所引发的这场范式转移,最终催生了Vision Foundation Model。正如NLP领域中GPT-3、GPT-4这类Foundation Model用单一模型处理各种任务一样,Vision领域也正朝着同样的方向发展。
主要的Vision Foundation Models:
- SAM(Segment Anything Model):基于ViT-H,用单一模型处理各类Segmentation
- DINOv2:Self-supervised ViT,通用Visual Feature Extractor
- CLIP/SigLIP:Vision-Language对齐,支持Zero-shot Classification与Retrieval
- Florence/Intern:大规模多任务Vision-Language模型
13.2 未来的研究方向
效率提升:
- 通过FlashAttention、Linear Attention等方法克服 瓶颈
- 通过Token Pruning/Merging去除不必要的patch
- 通过Knowledge Distillation生成轻量模型
训练范式:
- Self-supervised Pre-training的普及(MAE、DINO系列)
- Vision-Language Alignment(CLIP系列)
- 基于强化学习的视觉决策(VLM + RL)
架构创新:
- Mamba / State Space Model在Vision中的应用(Vision Mamba、VMamba)
- 利用Mixture of Experts(MoE)实现高效扩展
- 持续研究融合CNN与Transformer优点的Hybrid架构
13.3 ViT的历史意义
ViT留下的最重要的教训是架构的通用性(universality)。单一架构(Transformer)能够应用于文本、图像、语音、视频、代码等所有模态,这在AI历史上是极为特殊的事件。
在ViT之前,NLP与Vision拥有完全不同的架构生态。ViT之后,Transformer真正成为了通用架构(Universal Architecture),这正是如今多模态Foundation Model(GPT-4V、Gemini、Claude等)得以实现的技术基础。
「An Image is Worth 16x16 Words」——这个标题不仅仅是一个比喻,而是一句深刻的宣言:Vision与Language可以在同一个框架内实现统一。
14. References
-
Dosovitskiy, A., Beyer, L., Kolesnikov, A., Weissenborn, D., Zhai, X., Unterthiner, T., ... & Houlsby, N. (2020). An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale. ICLR 2021. arXiv:2010.11929
-
Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., ... & Polosukhin, I. (2017). Attention Is All You Need. NeurIPS 2017. arXiv:1706.03762
-
Touvron, H., Cord, M., Douze, M., Massa, F., Sablayrolles, A., & Jegou, H. (2021). Training data-efficient image transformers & distillation through attention (DeiT). ICML 2021. arXiv:2012.12877
-
Liu, Z., Lin, Y., Cao, Y., Hu, H., Wei, Y., Zhang, Z., ... & Guo, B. (2021). Swin Transformer: Hierarchical Vision Transformer using Shifted Windows. ICCV 2021. arXiv:2103.14030
-
Bao, H., Dong, L., Piao, S., & Wei, F. (2021). BEiT: BERT Pre-Training of Image Transformers. ICLR 2022. arXiv:2106.08254
-
He, K., Chen, X., Xie, S., Li, Y., Dollar, P., & Girshick, R. (2022). Masked Autoencoders Are Scalable Vision Learners (MAE). CVPR 2022. arXiv:2111.06377
-
Caron, M., Touvron, H., Misra, I., Jegou, H., Mairal, J., Bojanowski, P., & Joulin, A. (2021). Emerging Properties in Self-Supervised Vision Transformers (DINO). ICCV 2021. arXiv:2104.14294
-
Oquab, M., Darcet, T., Moutakanni, T., Vo, H., Szafraniec, M., Khalidov, V., ... & Bojanowski, P. (2023). DINOv2: Learning Robust Visual Features without Supervision. arXiv:2304.07193
-
Fang, Y., Wang, W., Xie, B., Sun, Q., Wu, L., Wang, X., ... & Cao, Y. (2023). EVA: Exploring the Limits of Masked Visual Representation Learning at Scale. CVPR 2023. arXiv:2211.07636
-
Fang, Y., Sun, Q., Wang, X., Huang, T., Wang, X., & Cao, Y. (2023). EVA-02: A Visual Representation for Neon Genesis. arXiv:2303.11331
-
Liu, Z., Mao, H., Wu, C. Y., Feichtenhofer, C., Darrell, T., & Xie, S. (2022). A ConvNet for the 2020s (ConvNeXt). CVPR 2022. arXiv:2201.03545
-
Devlin, J., Chang, M. W., Lee, K., & Toutanova, K. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. NAACL 2019. arXiv:1810.04805
-
He, K., Zhang, X., Ren, S., & Sun, J. (2016). Deep Residual Learning for Image Recognition (ResNet). CVPR 2016. arXiv:1512.03385
-
Kolesnikov, A., Beyer, L., Zhai, X., Puigcerver, J., Yung, J., Gelly, S., & Houlsby, N. (2020). Big Transfer (BiT): General Visual Representation Learning. ECCV 2020. arXiv:1912.11370
-
Radford, A., Kim, J. W., Hallacy, C., Ramesh, A., Goh, G., Agarwal, S., ... & Sutskever, I. (2021). Learning Transferable Visual Models From Natural Language Supervision (CLIP). ICML 2021. arXiv:2103.00020
-
Kirillov, A., Mintun, E., Ravi, N., Mao, H., Rolland, C., Gustafson, L., ... & Girshick, R. (2023). Segment Anything (SAM). ICCV 2023. arXiv:2304.02643
현재 단락 (1/533)
《An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale》是2020年10月由Google Researc...