卷1 · 深度学习与 CV 基础
1.4 ViT 与视觉 Transformer 谱系:图像成为 token
展开本章目录与同卷章节
1. ViT:最简单的设计为什么成立2. 谱系速览:每个变体在解决什么3. 视觉 token 数量:多模态的核心矛盾(卷3 伏笔)4. 实操:用 timm 玩真模型5. 视觉编码器在多模态里的位置(前瞻)6. 自测题7. 动手作业8. 延伸资源同卷章节1.1 从 CNN 到 ResNet:卷积时代的遗产1.2 注意力机制:从加权检索到万物的基础操作1.3 Transformer 逐层拆解:从 Block 到小 GPT1.4 ViT 与视觉 Transformer 谱系:图像成为 token1.5 自监督三巨头:MAE、CLIP、DINO1.6 CLIP 精读与 zero-shot 评测实操(第一个完整项目)1.7 SAM 与分割基础模型:提示式视觉1.8 检测与分割极简史:知道即可的一章1.9 图像形成与相机模型:给 3D/具身留的几何底座本章目标:理解”图像怎么变成 token 序列”——这是整个多模态大厦的第一块砖。学完标准:能讲清 ViT 的最简设计与它成立的前提,知道主流变体解决什么问题,明白”视觉 token 数量”为什么是多模态的核心矛盾(卷3 的伏笔)。
1. ViT:最简单的设计为什么成立
《An Image is Worth 16x16 Words》(2020) 的做法简单到失礼:
- 把 224×224 图像切成 196 个 16×16 patch;
- 每个 patch 展平(16×16×3=768 维),过一个线性层 → 768 维 token;
- 加 [CLS] token(汇总全局信息,作分类头输入)+ 位置编码;
- 喂给标准 Transformer encoder(和 NLP 一模一样),CLS 输出接分类头。
工程等价性(必懂):切 patch + 线性投影 = 一个 stride=16、kernel=16 的卷积:
self.patch_embed = nn.Conv2d(3, 768, kernel_size=16, stride=16) # (B,3,224,224) → (B,768,14,14)
# 再 flatten + transpose → (B, 196, 768),拼上 CLS token,加位置编码,进 Transformer
第一层卷积参数 = 16×16×3×768,就是 N 个”patch → token”的线性映射。所以 ViT 并没有抛弃卷积,只是把卷积压缩成了一次 token 化,之后全交给注意力。
成立的前提:1.1 章讲过,弱先验架构需要大数据。ViT 论文自己的实验梯度——ImageNet-1k(百万级)上 ViT 输给 ResNet;ImageNet-21k + JFT-300M(亿级)上反超。结论不是”ViT 更好”,而是”数据规模换架构先验”的交易曲线。小数据场景(医疗影像常见)ViT 未必赢——这正是 DeiT 和混合架构存在的原因。
2. 谱系速览:每个变体在解决什么
| 变体 | 解决的问题 | 关键设计 | 现状 |
|---|---|---|---|
| ViT | 证明可行 | 最简设计 | 一切的起点 |
| DeiT | ImageNet-1k 也能训好 ViT | 强增强 + 蒸馏 token | 数据增强哲学被全行业继承 |
| Swin | 检测/分割需要高分辨率 | 层级下采样 + 窗口注意力(窗口内算,跨窗口移位交互) | 检测分割时代主力,现被 ViTDet 等挑战 |
| ConvNeXt | 用现代配方让 CNN 回牌桌 | 大核、LayerNorm、GELU 等逐项改造 ResNet | 证明”训练配方”≈“架构” |
| BEiT / EVA | 视觉预训练 | 遮罩重建 / CLIP 蒸馏 | 思想汇入自监督(1.5) |
读谱系的正确姿势:不是记名字,而是看张力轴——局部先验 vs 全局交互、窗口稀疏 vs 全局平方复杂度、纯视觉 vs 图文联合。所有变体都在这几根轴上找位置。
3. 视觉 token 数量:多模态的核心矛盾(卷3 伏笔)
算一笔账:224² 分辨率 → 196 token,没问题。但:
- 文档/OCR 要看清小字:需要 1024+ 分辨率 → 数千 token;
- 检测要 800×1333 → 约 2700 token(patch16);
- 视频每帧 196 token,16 帧就是 3136 token;
- 而 LLM 的注意力对 token 数平方敏感(1.2 章的账)。
多模态模型设计的核心工程问题之一就是:视觉 token 塞多少、怎么压。你以后会遇到的每个设计——Qwen-VL 的 pixel shuffle 压缩、BLIP-2 的 Q-Former(32 个 query token 打包整图)、Qwen3-VL 的动态分辨率 patch 化——都是在回答同一道题。现在记住题目本身:分辨率↑ → token 爆炸 → 注意力平方爆炸。
4. 实操:用 timm 玩真模型
import timm, torch
model = timm.create_model("vit_base_patch16_224", pretrained=True)
model.eval()
print(model) # 逐行读:patch_embed / cls_token / pos_embed / blocks.0...11 / head
x = torch.randn(1, 3, 224, 224)
feats = model.forward_features(x) # (1, 197, 768):196 patch + 1 CLS
print(feats.shape)
要求自己能对着打印输出说出每个模块的角色(对照本章 §1 和 1.3)。再从 model.blocks[i].attn 里抓 attention 权重画热力图,看最后一层注意力聚焦在哪——通常围绕物体轮廓(1.5 章 DINO 会把这个现象做到极致)。
5. 视觉编码器在多模态里的位置(前瞻)
到 2026 年,几乎所有开源 VLM 的视觉塔都是 ViT 变体(CLIP ViT、SigLIP、InternViT、AIMv2……),差别在训练目标和数据。你将来做 VLM 微调时冻结/解冻的就是这个东西。现在建立”视觉塔 = 冻结的 ViT 特征提取器”的直觉,卷3 会反复用到。
6. 自测题
- 切 patch + linear 等价于什么卷积?(k=16, s=16;参数即投影矩阵)
- ViT 为什么需要 CLS token 或全局池化?(输出是 196 个 token,要一个汇聚全局的向量做分类)
- ViT 在 ImageNet-1k 上输给 ResNet 说明什么先验问题?(弱先验架构数据不足时不如强先验;平移等变/局部性在中小数据仍有价值)
- Swin 的窗口注意力在省什么?(N² 注意力 → 窗口内线性增长;代价是牺牲部分全局交互,用移位窗口补偿)
- 1024×1024 图像 patch16 是多少 token?对 VLM 意味着什么?(4096 个;不压缩的话 LLM 端注意力代价爆炸——token 压缩是多模态核心工程题)
- ConvNeXt 的结论对科研方法论有什么启示?(配方与架构同样重要——复现失败先怀疑训练配方,再怀疑思想)
7. 动手作业
- 手写
PatchEmbed(conv 实现 + CLS + 可学习位置编码),前向输出 (B, 197, 768),与 timm 的model.patch_embed对比参数量。 - 用 timm 加载 ViT,冻结全部参数,只把 head 换成 10 类,在 CIFAR-10 上微调(只训 head,lr 1e-3;再试解冻最后 2 个 block,lr 1e-5)——体会”预训练特征 + 轻量适配”的威力与冻结/解冻的取舍。
- 可视化第 0/6/11 层 block 的 CLS→patch 注意力图,对比”低层看纹理、高层看物体”。
- 挑战:把输入改成 384×384(timm 的
img_size参数或直接换vit_base_patch16_384),观察位置编码怎么变——引出”插值位置编码”这一经典工程 trick。
8. 延伸资源
- ViT 原论文 + 李沐《论文精读》ViT 一期——必读必看
- Swin / ConvNeXt 论文泛读(看图说话级别即可)
- timm repo(
pytorch-image-models)——视觉 backbone 的瑞士军刀,后面项目反复用
