一、ViT 的主要版本概览
自 2020 年 Google Brain 提出原始 ViT 以来,该系列已经发展出众多变体。主要版本包括:原始 ViT、DeiT、Swin Transformer、BEiT、MAE、DINOv2、Swin V2、SAM 中的 ViT 骨干、ViT-22B 等。下面逐一介绍。
二、各版本网络架构详解
1. 原始 ViT(2020,Dosovitskiy et al., Google Brain)
论文:An Image is Worth 16×16 Words: Transformers for Image Recognition at Scale
这是整个系列的基础,核心思想是将图像视为一系列 patch 的序列,直接套用标准 Transformer Encoder。
完整数据流程如下:
① Patch 切分与线性嵌入(Patch Embedding)
给定输入图像x∈RH×W×Cx \in \mathbb{R}^{H \times W \times C}x∈RH×W×C,将其切分为若干固定大小的 patch(如 16×16)。共得到N=HWP2N = \frac{HW}{P^2}N=P2HW个 patch。每个 patch 展平后形状为RP2⋅C\mathbb{R}^{P^2 \cdot C}RP2⋅C,通过一个可学习的线性投影矩阵E∈R(P2⋅C)×DE \in \mathbb{R}^{(P^2 \cdot C) \times D}E∈R(P2⋅C)×D映射到 D 维嵌入空间,即 patch embedding。
② 加入 [CLS] Token 与位置编码
在序列最前面拼接一个可学习的分类 tokenxclsx_{\text{cls}}xcls,这个 token 在经过 Transformer 后承载全局特征信息,用于最终分类。同时加入可学习的一维位置编码Epos∈R(N+1)×DE_{\text{pos}} \in \mathbb{R}^{(N+1) \times D}Epos∈R(N+1)×D,弥补 Transformer 缺乏位置感知的缺陷。
③ Transformer Encoder(L 层堆叠)
每一层包含:LayerNorm(前置) → 多头自注意力(MSA) → 残差连接,然后 LayerNorm(前置) → MLP Block → 残差连接。MLP Block 由两个线性层 + GELU 激活构成,维度通常为 4D。这种 Pre-Norm 设计比 Post-Norm 训练更稳定。
④ 分类头
取最终输出序列中 [CLS] token 对应的向量,经过一个 MLP 分类头输出类别概率。
三种规模配置:
| 模型 | Transformer层数 | 隐藏维度 D | MLP维度 | 注意力头数 | 参数量 |
|---|---|---|---|---|---|
| ViT-B/16 | 12 | 768 | 3072 | 12 | ~86M |
| ViT-L/16 | 24 | 1024 | 4096 | 16 | ~307M |
| ViT-H/14 | 32 | 1280 | 5120 | 16 | ~632M |
核心局限:需要在超大数据集(JFT-300M)上预训练,在中小型数据集上效果不如 CNN,因为缺乏 CNN 固有的归纳偏置(局部性、平移不变性)。
2. DeiT(2021,Touvron et al., Facebook AI)
论文:Training>N+2N+2N+2。训练时,[CLS] token 对应真实标签的分类损失,distillation token 对应教师模型(通常是 RegNet 等 CNN)输出的软标签损失,两者加权求和。推理时可以只用 [CLS] token,也可以将两者平均。
训练策略强化:使用 RandAugment、Mixup、CutMix、Random Erasing 等大量数据增强,以及 Repeated Augmentation,使得模型无需海量数据也能收敛。
规模分为 DeiT-Ti(Tiny)、DeiT-S(Small)、DeiT-B(Base)。
3. Swin Transformer(2021,Liu et al., Microsoft Research Asia)
论文:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
Swin 是目前最重要的 ViT 变体之一,解决了原始 ViT 两个关键问题:计算复杂度随图像大小二次增长,以及缺乏多尺度特征(无法用于检测、分割等密集预测任务)。
核心设计①:层次化架构(Hierarchical Feature Map)
类似 CNN 的 4 阶段设计:
- Stage 1:4×4 的非重叠 patch 切分,每个 patch 嵌入到 C 维(C=96 for Swin-T)
- Stage 2:Patch Merging(将相邻 2×2 patch 合并,通道数变为 2C,分辨率减半)
- Stage 3:再次 Patch Merging,4C
- Stage 4:再次 Patch Merging,8C
这样就产生了类似 CNN Feature Pyramid 的多尺度特征图。
核心设计②:基于窗口的多头自注意力(W-MSA)与移位窗口(SW-MSA)
标准 ViT 的全局自注意力复杂度是O(N2)\mathcal{O}(N^2)O(N2),对于大分辨率图像代价极高。Swin 的解决方案是在固定大小的局部窗口内(默认 7×7 patch)计算自注意力,复杂度降为O(N)\mathcal{O}(N)O(N)(相对于图像大小线性)。
但纯粹的窗口注意力没有跨窗口的信息交流,因此 Swin 在相邻层交替使用W-MSA(正常窗口划分)和SW-MSA(将窗口向右下方移位⌊M/2⌋\lfloor M/2 \rfloor⌊M/2⌋个 patch,产生新的窗口划分)。移位操作使相邻窗口之间实现了间接的信息传递。为了保持移位后窗口数量不变,使用了 cyclic shift + masking 技巧。
相对位置偏置(Relative Position Bias):Swin 不用绝对位置编码,而是在注意力计算中加入可学习的相对位置偏置矩阵BBB,这对不同尺度的泛化更友好。
Swin-T/S/B/L 四种规模,参数量从 28M 到 197M。
理解
Swin Transformer 是一个骨干网络架构,目标是让 Transformer 能像 CNN 一样做各种视觉任务,不只是分类。
原始 ViT 有两个问题:特征图始终只有一个尺度没办法做检测和分割,以及全局自注意力计算量太大。Swin 同时解决了这两个问题。
结构上它模仿 CNN 的金字塔设计,通过 Patch Merging 逐层把特征图从大变小,产生多尺度特征,这样就可以同时检测大物体和小物体。
计算量上它把全局自注意力改成局部窗口内的自注意力,每个窗口只有 49 个 patch 互相做注意力,计算量和图像大小无关。为了让窗口之间也能交流信息,相邻两层之间会把窗口整体移位一次,让原来被隔离在不同窗口的 patch 能够间接交互。
和 CNN 最本质的区别是窗口内用的是自注意力而不是卷积,权重是根据当前输入内容动态计算的,而不是固定的。
一句话就是:Swin 是一个用自注意力代替卷积、同时保留 CNN 金字塔结构的通用视觉骨干网络
4. BEiT(2021,Bao et al., Microsoft Research)
论文:BEiT: BERT Pre-Training of Image Transformers
将 NLP 中 BERT 的掩码语言建模思想迁移到视觉:掩码图像建模(Masked Image Modeling, MIM)。
架构:Backbone 仍然是标准 ViT,区别在预训练策略。首先用一个离散 VAE(dVAE)将图像编码为离散视觉 token(visual tokens)作为重建目标。训练时随机遮盖约 40% 的 image patch,用 [MASK] token 替代,让模型预测被遮盖位置对应的离散视觉 token ID(分类任务)。下游微调时与标准 ViT 相同。
5. MAE(2022,He et al., Meta AI)
论文:Masked Autoencoders Are Scalable Vision Learners
MAE 是当前影响力最大的 ViT 预训练方法之一,核心亮点是非对称的编解码器设计,极大降低了预训练成本。
Encoder(重型):标准 ViT,只处理未被遮盖的 patch(约 25%)。由于大量 patch 被掩盖,Encoder 处理的序列很短,计算量大幅减少(约为处理完整图像的 1/4 ~ 1/8)。
Decoder(轻型):一个比 Encoder 窄得多的 Transformer。输入是 Encoder 输出的可见 patch 嵌入 + 被遮盖位置的 [MASK] token(可学习向量),加上位置编码后让 Decoder 重建被遮盖 patch 的原始像素值(像素级重建,MSE 损失)。Decoder 仅在预训练中使用,下游任务只用 Encoder。
为什么高遮盖率(75%)有效?图像相邻 patch 存在高度冗余,低遮盖率会使任务过于简单(靠周围 patch 插值即可),高遮盖率迫使模型学习真正有语义价值的特征。
MAE 的效率极高,ViT-L 在 ImageNet 上预训练速度比有监督训练快约 3 倍。
在做什么
MAE 是一个预训练框架,做的事情很简单:把图像 75% 的 patch 随机遮盖掉,让模型把被遮盖的像素还原出来。
整个网络分两部分。Encoder 是一个标准 ViT,只处理没被遮盖的 25% 的 patch,输出这些 patch 的 latent 特征。Decoder 是一个很小很轻的 Transformer,拿到 Encoder 的输出加上被遮盖位置的占位 token,负责重建原始像素。训练完之后 Decoder 直接扔掉,只留 Encoder。
遮盖率高达 75% 是关键设计,因为图像像素冗余度很高,遮盖少了靠插值就能糊弄,遮盖多了才能逼着模型真正理解语义,才能合理推断被遮盖区域应该长什么样子。
训练完的 Encoder 就是一个学到了丰富视觉特征的 ViT,拿去接分类头、检测头等做各种下游任务,效果很好。本质上就是视觉版的 BERT,重建像素只是手段,学到好特征才是目的。
6. DINOv2(2023,Oquab et al., Meta AI)
论文:DINOv2: Learning Robust Visual Features without Supervision
DINOv2 是一个纯自监督框架,结合了 DINO(teacher-student 自蒸馏)和 iBOT(掩码图像建模)损失。
架构:使用 ViT 作为 backbone(ViT-S/B/L/g),教师网络是学生网络参数的指数移动平均(EMA)。训练时同一张图像的不同裁剪分别送入教师网络和学生网络,通过最小化两者输出分布的差异来学习特征,无需任何标签。DINOv2 特别注重高质量数据筛选(从网络爬取 142M 图像并去重、筛选),其特征在许多下游任务上可以直接作为冻结特征使用。
核心思想
DINO 的核心思想其实很简单:用一个更稳定的自己来教一个更新的自己。
具体来说,有两个结构相同的 ViT,一个叫教师一个叫学生。教师的参数是学生参数的滑动平均,所以它变化很慢,始终比学生"稳定"一些。
训练时,把同一张图像裁剪成大块和小块。大块同时给教师和学生看,小块只给学生看。然后让学生的输出分布去匹配教师的输出分布,尤其是学生只看到小块时,也要输出和教师看完整大块时一样的分布。
这个任务逼着学生必须从局部片段中理解全局语义,比如只看到猫耳朵,也要理解这是一只猫。而且整个过程没有任何人工标签,教师产生目标,学生去追,学生更新完再慢慢带动教师进化,就这样一直自举下去。
训练完之后一个有趣的副产品是,[CLS] token 对各个 patch 的注意力图,天然地勾勒出了图像中物体的轮廓,因为物体轮廓正是在所有裁剪中语义最稳定的部分,模型不得不去关注它。
7. Swin Transformer V2(2022,Liu et al.)
在 Swin V1 基础上引入了三个改进:Residual Post-Norm(比 Pre-Norm 训练大模型更稳定)、Scaled Cosine Attention(用余弦相似度替代点积,避免极端值导致的梯度问题)、Log-spaced Continuous Position Bias(使模型在不同分辨率间迁移更顺畅)。最大版本 Swin-V2-G 达到 30亿参数。
8. ViT-22B(2023,Dehghani et al., Google)
目前最大的 ViT,220 亿参数。改进点在于将注意力层和 MLP 层并行计算(而非串行),提升了训练效率,同时更好地支持跨模态任务。
三、下游应用
图像分类:这是 ViT 的起源任务,各种规模的 ViT 都在 ImageNet 等基准上达到 SOTA 水平。
目标检测:Swin Transformer 由于有层次化多尺度特征,可以无缝替换 CNN 骨干网络,与 Faster RCNN、DETR 等检测框架结合,在 COCO 上刷新记录。ViTDet(He et al., 2022)则研究了如何用简单 ViT 搭配特征金字塔做检测。
语义/实例分割:Swin + Mask R-CNN 或 UperNet 在 ADE20K 等数据集表现优异。SAM(Segment Anything Model)使用 ViT-H 作为图像编码器,实现了通用分割能力。
多模态大模型:CLIP、ALIGN 等视觉-语言预训练模型使用 ViT 作为视觉编码器。LLaVA、GPT-4V、Gemini 等多模态 LLM 也普遍以 ViT(或 SigLIP 的 ViT 变体)作为视觉塔。
医学影像:TransUNet、Swin-UNet 等将 ViT 用于医学图像分割;ViT 对全局上下文的感知特别适合需要跨区域关联的病灶检测任务。
自动驾驶:BEVFormer 等使用 Transformer 处理多视角图像,生成鸟瞰图特征,用于 3D 目标检测。
视频理解:Video ViT(ViViT)、TimeSformer 等在时空维度上扩展注意力机制,用于动作识别和视频分类。
生成模型:DiT(Diffusion Transformer)用 ViT 替换 U-Net 作为扩散模型的骨干,Stable Diffusion 3、FLUX 等最新扩散模型均采用此架构。
四、面试常见问题与回答
Q1:ViT 相比 CNN 有哪些优缺点?
回答:
优点方面,ViT 通过自注意力机制天然地建模全局长距离依赖关系,每个 patch 在第一层就能与所有其他 patch 交互,而 CNN 需要堆叠多层才能获得大感受野。ViT 具有更强的可扩展性,在数据量和模型规模增大时收益更显著,而 CNN 更容易趋于饱和。此外 ViT 的归纳偏置更少,给模型更大的学习空间,理论上上限更高。
缺点方面,原始 ViT缺乏 CNN 固有的归纳偏置(局部连接、平移等变性),在小数据集上容易过拟合。自注意力的计算复杂度是序列长度的平方O(N2)\mathcal{O}(N^2)O(N2),对高分辨率图像代价很高。此外 ViT 缺乏多尺度特征,不适合直接用于目标检测和分割(Swin 等变体解决了这个问题)。
Q2:ViT 中为什么需要位置编码?有哪些类型?
回答:
自注意力操作本身是**置换不变(permutation invariant)**的,即将 patch 序列打乱顺序,每个 patch 的输出不变。但图像的空间结构信息对于理解图像内容至关重要,因此必须显式地注入位置信息。
常见的位置编码类型有:可学习的一维绝对位置编码(原始 ViT 使用,简单有效)、二维绝对位置编码(分别对行列编码再相加)、相对位置偏置(Swin Transformer 使用,在注意力矩阵上加入相对位置可学习偏置,对迁移到不同分辨率更友好)、条件位置编码(CPVT,基于输入动态生成),以及 RoPE(Rotary Position Embedding,在 LLM 中广泛使用,部分 ViT 变体也采用)。
原始 ViT 的消融实验表明,1D 和 2D 位置编码效果差别不大,说明模型可以从 1D 编码中自行学习 2D 空间关系。
Q3:Swin Transformer 的 Shifted Window 是如何工作的?为什么要做移位?
回答:
Swin 将 feature map 划分为不重叠的局部窗口(如 7×7 patch),在每个窗口内部独立计算自注意力,将复杂度从O(N2)\mathcal{O}(N^2)O(N2)降到与窗口数量线性相关的O(N)\mathcal{O}(N)O(N)。
但纯窗口注意力的问题是跨窗口没有信息交流,感受野永远被限制在窗口内。Shifted Window(移位窗口)的解决方案是:在相邻两个 Transformer 层交替使用两种窗口划分方式。偶数层用正常划分,奇数层将窗口向右下方移位⌊M/2⌋\lfloor M/2 \rfloor⌊M/2⌋个 patch。这样本来处于不同窗口中的 patch 在移位后就进入同一个窗口,实现了跨窗口的信息传递,使感受野随着层数增加逐渐扩大至全局。
移位后边缘会产生尺寸不同的小窗口,为了保持批处理效率(所有窗口尺寸一致),使用cyclic shift + attention mask技巧:将图像做循环移位,把边缘小块填充到对角,再通过 attention mask 防止本不相邻的区域相互关注。
Q4:MAE 为什么使用高达 75% 的遮盖率?为什么不像 BERT 那样只遮 15%?
回答:
这是图像和文本信息冗余程度不同决定的。自然语言中每个词都携带独特的语义信息,遮盖一个词通常无法从周围的词精确恢复。而图像中相邻 patch 之间存在极高的像素级冗余(相邻区域往往颜色和纹理相似),如果遮盖率很低,模型只需要简单地插值或复制周围 patch 就能完成重建,学不到有意义的特征。75% 的高遮盖率迫使模型真正理解图像的语义结构,才能从 25% 的可见 patch 中推断出遮盖区域的内容。此外,高遮盖率也使 Encoder 只需处理约 1/4 的 patch,训练速度提升 3 倍以上,是一种兼顾效果与效率的设计。
Q5:ViT 中 [CLS] token 的作用是什么?有没有替代方案?
回答:
[CLS] token 是一个可学习的向量,拼接在 patch 序列最前面,与所有 patch 一起参与自注意力计算。由于它没有对应任何图像区域,只能通过与其他 patch 的注意力交互来聚合全局信息,经过 L 层 Transformer 后,它的输出向量理论上包含了对整个图像的全局摘要,因此被用于分类。
替代方案包括:全局平均池化(GAP),直接对所有 patch 的最终输出取均值,原始 ViT 论文的消融实验表明 GAP 效果与 CLS token 相当;全局最大池化;以及一些工作提出用可学习的交叉注意力来聚合特征(如 Perceiver)。DINOv2 的推理时同时使用 [CLS] token 和 patch 特征,效果更好。
Q6:ViT 的自注意力复杂度是多少?有哪些优化方法?
回答:
原始 ViT 对所有 N 个 patch 做全局自注意力,计算复杂度为O(N2⋅d)\mathcal{O}(N^2 \cdot d)O(N2⋅d),其中 d 是特征维度。对于 224×224 的图像用 16×16 patch,N=196,可以接受;但对于 512×512 用 8×8 patch,N=4096,计算代价急剧上升。
优化方案:局部窗口注意力(Swin Transformer,复杂度降为O(N)\mathcal{O}(N)O(N));线性注意力(近似核方法,如 Performer);稀疏注意力(只计算重要 token pair);下采样(PVT 等在早期阶段用大 stride 减少序列长度);Flash Attention(IO 感知的算法优化,在 GPU 上大幅加速注意力计算而不改变复杂度数量级)。
Q7:为什么 ViT 在小数据集上不如 CNN?如何改善?
回答:
CNN 具有强烈的归纳偏置:局部连接(卷积核只看局部区域)和平移等变性(同一特征检测器在图像各处共享权重)。这些先验知识与自然图像的统计特性高度吻合,使 CNN 能够从少量数据中高效学习。ViT 完全依赖数据来学习这些空间关系,需要更多数据。
改善方法:知识蒸馏(DeiT,用 CNN 教师指导 ViT 学习 CNN 固有的局部偏置);强数据增强(Mixup, CutMix, RandAugment 等);引入 CNN 结构元素(如 CvT、LocalViT 在 patch 嵌入阶段用卷积引入局部感知);大规模自监督预训练(MAE, DINOv2 等在无标签数据上预训练,再微调到下游任务);更小的 patch size(增加序列长度,提供更细粒度的局部信息)。
Q8:如果让你设计一个用 ViT 做目标检测的方案,你会怎么做?
回答:
有两条主要路线。第一条是借鉴 Swin Transformer 的层次化设计,将 Patch Merging 引入 ViT 构建多尺度特征图,再搭配 FPN(Feature Pyramid Network)提取不同尺度的特征,最后接 Faster-RCNN 或 FCOS 等检测头。这是目前工程实践中最常用的方案。
第二条是ViTDet(He et al., 2022)的思路,坚持使用简单的非层次化 ViT,通过最后一层特征做简单上采样/下采样模拟 FPN,配合 Masked Attention 等技巧让 ViT 处理高分辨率输入,在 COCO 上证明了非层次化 ViT 也能做到很好的检测性能。这条路线后来在 SAM 等工作中被采用。
第三条是端到端的 DETR 系列(DEtection TRansformer),直接用 Transformer 做检测,ViT 作为编码器,用一组可学习的 object query 通过交叉注意力从图像特征中解码出检测框,不需要 NMS,架构更简洁优雅。