Skip to content

ViT 视觉 Transformer

五层读懂一个词。这次拆的是:ViT(Vision Transformer)--把 Transformer 搬进视觉领域的关键一跃。核心洞察:把图像切成固定大小的 patch(如 16×16),每个 patch 当作 NLP 里的 token,直接喂给 Transformer。不需要 CNN 的卷积/池化,纯注意力机制在图像上也能拿到 SOTA。是大一统架构的第一步——让同一个 Transformer 既能看又能读。


L1 · 一句话点破

ViT = 把图像切成 patch 当 token,用纯 Transformer 做图像分类。一张 224×224 的图像 → 切成 14×14=196 个 16×16 的 patch → 每个 patch 拉平成向量 → 加位置编码 → 喂给标准 Transformer Encoder → 分类头输出标签。CNN 统治了视觉 10 年,ViT 证明了「不需要卷积,注意力就够了」——前提是有足够的数据(JFT-300M)或预训练。


L2 · 通俗类比

CNN 处理图像像一位画家

  • 一层层画细节:先画轮廓(浅层卷积),再画纹理(中层卷积),再画整体(深层卷积)
  • 每层只关注局部(卷积核 3×3/5×5)
  • 逐层抽象,从低层特征到高层语义

ViT 处理图像像「读一篇文章」

  • 把图像切成小方格(patch),每个方格像一个词
  • 每个方格的位置很重要("猫在上方" vs "猫在下方")
  • 所有方格之间互相看(自注意力),建立全局关系
  • 不需要「逐层画」,一次性理解全局

关键类比

NLP Transformer:
  输入: "The cat sat on the mat"
  切分: ["The", "cat", "sat", "on", "the", "mat"]
  处理: Token Embedding + Positional Encoding → Transformer

ViT:
  输入: 一张猫的图片
  切分: [patch1, patch2, ..., patch196]
  处理: Patch Embedding + Positional Encoding → Transformer

一模一样——只是把「词」换成了「图像块」。

为什么 ViT 是革命性的

  • CNN 的卷积是特殊设计的归纳偏置(locality, translation invariance)
  • ViT 说:这种偏置不是必需的,纯注意力足够
  • 更重要的是:同一架构可以处理文本和图像
  • 为 CLIP、多模态 LLM 等大一统模型铺路

代价

  • 数据饥渴:CNN 在 ImageNet 上训练好,ViT 需要 ImageNet-21k 或 JFT-300M
  • 小数据上不如 CNN(缺乏卷积的归纳偏置)
  • 推理快但训练更贵

L3 · 正经定义

ViT(Vision Transformer):由 Dosovitskiy et al. 2020(Google)提出的纯 Transformer 图像分类架构。流程:

  1. 图像 $x \in \mathbb{R}^{H \times W \times C}$ 切为 $N = HW/P^2$ 个 $P \times P$ 的 patch
  2. 每个 patch 展平为向量 $\in \mathbb{R}^{P^2 \cdot C}$
  3. 线性投影到 Transformer 维度 $D$:$z_i = \text{Flatten}(x_i) E$
  4. 加可学习位置编码 $E_{pos}$ 和 CLS token
  5. 输入标准 Transformer Encoder(多头自注意力 + FFN)
  6. CLS token 对应的输出经 MLP head 做分类

参数量

  • ViT-Base: 86M(对标 ResNet-50 的 25M,但可扩展到 ViT-Huge 632M)
  • ViT-Large: 307M
  • ViT-Huge: 632M

参考资料

  • 📄 Dosovitskiy et al., An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale, ICLR 2021
  • 📄 Touvron et al., Training data-efficient image transformers (DeiT), 2020
  • 📄 Liu et al., Swin Transformer: Hierarchical Vision Transformer using Shifted Windows, ICCV 2021
  • 🔧 HuggingFace ViT:google/vit-base-patch16-224

L4 · 原理深挖

4.1 架构细节

Patch Embedding

python
# 图像: [B, 3, 224, 224]
# Patch 大小: 16×16 → N = 14×14 = 196 patches
# 每个 patch: [B, 3, 16, 16] → flatten → [B, 768]

x = rearrange(x, 'b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1=16, p2=16)
# [B, 196, 768]

# 线性投影到 D 维
patch_embed = nn.Linear(768, D)(x)
# [B, 196, D]

CLS Token

  • BERT 风格的特殊 token
  • 位置 0,汇总全图信息
  • 最后一层的 CLS token 输出用作分类
  • 也可以做 GAP(Global Average Pooling),效果相似

位置编码

python
# 可学习的位置编码: [1, 197, D](197 = 1 CLS + 196 patches)
pos_embed = nn.Parameter(torch.randn(1, num_patches + 1, D))

# 或 2D 正弦位置编码
# 分别对 x 和 y 位置编码,捕获 2D 结构

Transformer Encoder

标准结构,和 NLP Transformer 相同:

z_0 = [CLS_token; patch_embed_1, ..., patch_embed_N] + pos_embed

for l in 1..L:
    z_l' = MSA(LN(z_{l-1})) + z_{l-1}
    z_l  = MLP(LN(z_l')) + z_l'

y = LN(z_L)[0]  # CLS token 输出
output = MLP_head(y)

4.2 ViT 为什么能工作

自注意力建立全局依赖

  • 第 1 层:每个 patch 就和所有其他 patch 建立关系
  • CNN:需要多层才能建立长距离依赖(感受野逐层扩大)
  • ViT:第 1 层就能看到全图

注意力距离分析

低层(Layer 1-3): 每个 patch 主要关注相邻 patch(学习 CNN 式的局部特征)
中层(Layer 4-8): 关注范围扩大,形成形状/纹理
高层(Layer 9-12): 全局关注,跨 patch 建立语义关系

换句话说:ViT 的注意力层自然学会了 CNN 的层次化特征提取——低层关注局部,高层关注全局,但都是同一种机制(注意力)做到的。

4.3 ViT 的 Scaling

数据规模是关键

训练数据ViT-B/16ViT-L/16ViT-H/14
ImageNet (1.2M)77.9%76.5%-
ImageNet-21k (14M)84.0%85.2%85.1%
JFT-300M84.2%87.1%88.6%

结论

  • 小数据:ViT ≈ 甚至不如 ResNet(缺乏卷积归纳偏置)
  • 中数据:ViT ≈ ResNet
  • 大数据:ViT >> ResNet(Scalability 更好)

为什么 ViT 更 scalable

  • Transformer 的训练和推理对硬件更友好(矩阵乘法 vs 卷积)
  • 参数效率更高(多头注意力在更高维时收益更大)

4.4 ViT 的变体

DeiT(Data-efficient Image Transformer)

  • 解决 ViT 数据饥渴问题
  • 用蒸馏(用 CNN teacher 教 ViT student)
  • 只需 ImageNet-1K 就达到好效果

Swin Transformer

  • 分层结构(patch merging,类似 CNN 的下采样)
  • Shifted Window Attention(在窗口内做注意力,窗口之间 shift)
  • 计算复杂度从 $O(N^2)$ 降到 $O(N)$
  • 适合密集预测任务(检测/分割)

PVT(Pyramid Vision Transformer)

  • 金字塔结构 + 空间缩减注意力
  • 更好的多尺度特征

ViT vs CNN 对比

维度CNN (ResNet)ViT
归纳偏置强(局部性、平移不变)弱(需数据补偿)
全局依赖逐层建立第 1 层就有
数据效率高(小数据好)低(需大数据)
Scalability中等
多模态兼容好(同架构)

4.5 ViT 在多模态中的作用

CLIP

文本: "a cat" → Text Encoder → text_embedding
图像: 猫的图片 → ViT → image_embedding

训练: text_embedding · image_embedding 最大化
→ ViT 学到的视觉特征和文本对齐

多模态 LLM

图像 → ViT → visual_features
文本 → Tokenizer → text_tokens
[visual_features, text_tokens] → LLM → 回答

ViT 是图像进入 LLM 世界的「翻译器」。

4.6 ViT 的局限

局限 1: 数据饥渴。ImageNet-1K 上 ViT 不如 CNN。需要大数据预训练或蒸馏。

局限 2: 高分辨率挑战。Patch 大小固定时,分辨率翻倍 → patch 数翻 4 倍 → 注意力复杂度翻 16 倍。

局限 3: 不适合所有视觉任务。分类 OK,但检测/分割等密集预测任务 Swin Transformer 等分层变体更好。

局限 4: 位置编码不够灵活。训练时 224×224,推理 384×384 需要插值位置编码。

局限 5: 小的物体。固定 patch 大小(16×16),小物体可能在 1-2 个 patch 内,表示能力不够。

局限 6: 计算成本。ViT-H/14 的 FLOPs 是 ResNet-50 的 10x 以上。

局限 7: 训练不稳定。Transformer 训练需要更多的技巧(warmup, 大 batch, 强正则化)。


L5 · 沿革与坑

5.1 沿革

  • 2017:Transformer 论文(Vaswani et al.),NLP 领域革命
  • 2019:Image GPT(OpenAI),首次尝试 Transformer 生成图像像素
  • 2020-10:ViT 论文(Google),纯 Transformer 图像分类
  • 2021-03:DeiT(Facebook),蒸馏解决数据效率
  • 2021-03:Swin Transformer(Microsoft),分层+窗口注意力
  • 2021-2022:CLIP/DALL-E/Stable Diffusion 爆发,ViT 成为视觉 backbone 标配
  • 2023-2024:ViT 被多模态 LLM 广泛采用(LLaVA/Qwen-VL/GPT-4V)
  • 2024-2025:ViT 变体(DINOv2/SigLIP)继续迭代,视觉 Self-Supervised Learning 结合

5.2 常见坑

坑 1: 小数据上直接训 ViT。ImageNet 级别的数据量不够。要:DeiT 蒸馏 / 用预训练 ViT / 加更多数据。

坑 2: 图像尺寸和 patch 大小不整除。224 不能被 16 整除?要 resize 或 padding。

坑 3: 推理分辨率变了不插值位置编码。训练 224,推理 384 → 位置编码要插值。否则准确率暴跌。

坑 4: CLS token 和 GAP 混用。大部分 ViT 用 CLS token 分类。代码里不小心改了头导致不匹配。

坑 5: ViT 当 CNN 用。ViT 的 feature map 不是 CNN 式的 multi-scale。检测/分割用 Swin。

坑 6: 忽略预训练权重。ViT 严重依赖预训练。随机初始化训 ViT 几乎不可能(除非海量数据)。

坑 7: Patch 16 vs Patch 32 vs Patch 14。Patch 越小越精细但越慢。16 是通用甜点。

坑 8: 通道数不匹配。预训练 ViT 是 RGB 3 通道,灰度图/多光谱图要改输入层。

坑 9: Attention 的可视化过度解读。低层的注意力图不一定有意义(query-key 匹配 vs 实际特征)。

坑 10: ViT 对对抗样本的鲁棒性。ViT 比 CNN 对对抗扰动更鲁棒,但不是免疫的。

5.3 面试怎么考

  1. ViT 的核心思想? 答:图像切成 patch 当 token,纯 Transformer 处理。不需要 CNN 的卷积/池化。架构 = NLP Transformer。
  2. ViT 和 CNN 的对比? 答:CNN 有卷积归纳偏置(局部性),小数据好;ViT 纯注意力,大数据更好、更 scalable、更适合多模态。
  3. 为什么 ViT 需要大数据? 答:缺乏卷积的归纳偏置(局部性、平移不变性),需要从数据中学习这些模式。数据不够时不如 CNN。
  4. CLS token 做什么? 答:BERT 风格的特殊 token,汇总全图信息用于分类。位置编码中包含 CLS token。
  5. Swin Transformer 解决了什么问题? 答:ViT 的复杂度 $O(N^2)$ 不适合密集预测。Swin 用分层+窗口注意力降到 $O(N)$,适合检测/分割。

速记卡

ViT 架构

图像 → 切Patch → Patch Embedding → + Positional Encoding → Transformer Encoder → CLS → MLP Head → 标签

核心公式

z_0 = [CLS; x_1E; x_2E; ...; x_NE] + E_pos
z_l = Transformer_Block(z_{l-1}), l=1..L
y = LN(z_L)_CLS → MLP → class

ViT 变体

模型PatchLayersDimParams
ViT-Base16×161276886M
ViT-Large16×16241024307M
ViT-Huge14×14321280632M

数据规模影响(准确率):

数据ViT-B/16ResNet-50
ImageNet-1K77.9%76.1%
ImageNet-21K84.0%-
JFT-300M84.2%-

何时用 ViT vs CNN vs Swin

需求推荐
分类 + 大数据ViT
分类 + 小数据CNN 或 DeiT
检测/分割Swin
多模态ViT(统一架构)

一句话记忆:ViT = 图像切 patch 当 token + 标准 Transformer。把 NLP Transformer 直接搬进视觉,不需要卷积。大数据上远超 CNN,小数据需要蒸馏(DeiT)。是多模态大一统架构的基础——同一 Transformer 处理文本和图像。Swin Transformer 是分层变体,更适合检测/分割。ViT-Base 86M 参数,Patch 16 是通用甜点。


上一篇:可观测性与追踪 -- 评估与监控专题末篇,多模态专题让 AI 不止于文字。下一篇:扩散模型原理 -- ViT 让模型看懂图像,扩散模型让模型生成图像。

内容采用 CC BY-SA 4.0,代码采用 MIT。