一篇文章讲明白 Vision Transformer(ViT)
1. ViT 是什么?
ViT 全称:
Vision Transformer(视觉 Transformer)
它是把Transformer 从 NLP(自然语言处理)迁移到计算机视觉领域的一种模型。
传统视觉模型:
图片 ↓ CNN卷积 ↓ 特征提取 ↓ 分类ViT:
图片 ↓ 切成Patch ↓ Patch变成Token ↓ Transformer Encoder ↓ 分类核心思想:
把一张图片看成一段“视觉语言”,把图像块(Patch)当成 NLP 里的单词(Token)。
ViT 最早由 Google 在论文:
An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
提出。
2. 为什么 Transformer 可以处理图片?
Transformer 原本处理文本:
例如:
我 喜欢 AI转换:
Token1 Token2 Token3然后:
Transformer ↓ 理解上下文图片怎么办?
图片:
224 × 224 × 3不能直接丢进去。
因为:
Transformer 输入需要:
序列所以 ViT 做了一件事:
把图片切成很多小块,每个小块当成一个 Token。
3. 第一步:Patchify(图片切块)
假设:
输入图片:
224 × 224 × 3使用:
Patch size = 16×16切:
224 / 16 = 14所以:
14 × 14 = 196 个 Patch每个 Patch:
16 × 16 × 3展开:
16×16×3 =768个数字所以图片变成:
Patch1 768维 Patch2 768维 ... Patch196 768维也就是:
196个Token4. Patch Embedding:Patch 怎么变成 Token?
Transformer 不认识:
16×16图片块所以需要映射。
原始:
Patch 768维经过 Linear:
768 ↓ 768得到:
Patch Token类似 NLP:
单词 ↓ Embedding ↓ 词向量图片:
Patch ↓ Embedding ↓ 视觉Token5. 加入 CLS Token
现在有:
Patch1 Patch2 ... Patch196但是分类需要:
整张图片 → 一个类别怎么办?
加入:
CLS Token输入变成:
CLS Patch1 Patch2 ... Patch196总共:
197 TokensCLS 的作用:
汇总所有 Patch 信息,代表整张图片。
6. 加入 Position Embedding(位置编码)
Transformer 不知道顺序。
例如:
猫在左边 猫在右边Patch内容一样:
猫但位置不同。
所以加入:
Position Embedding输入:
Token + Position例如:
CLS + pos0 Patch1 + pos1 Patch2 + pos2这样模型知道:
这个Patch来自哪里7. ViT整体结构
完整流程:
Image | | Patchify | ----------------------- | | | Patch1 Patch2 Patch196 | | Patch Embedding | | + Position Embedding | | [CLS] Patch1 ... Patch196 | | Transformer Encoder | | CLS输出 | | Linear Head | | 分类结果8. Transformer Encoder 在干什么?
核心:
Self-Attention
假设:
图片:
狗在草地上某个Patch:
狗的眼睛通过 Attention:
可以关注:
耳朵Patch 鼻子Patch 身体Patch也就是说:
Patch之间互相交流。
公式:
Attention(Q,K,V)=softmax(QKTd)V Attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt d})VAttention(Q,K,V)=softmax(dQKT)V
简单理解:
当前Patch ↓ 寻找其他Patch ↓ 决定关注谁 ↓ 融合信息9. ViT 和 CNN 最大区别
| CNN | ViT | |
|---|---|---|
| 基本单位 | 像素 | Patch |
| 核心操作 | 卷积 | Attention |
| 感受野 | 逐渐扩大 | 直接全局 |
| 先验知识 | 强 | 弱 |
| 数据需求 | 较少 | 较多 |
| 扩展能力 | 一般 | 强 |
CNN:
第一层:
看附近像素第二层:
看更大区域慢慢获得全局信息。
ViT:
第一层 Attention:
Patch1 直接看到 Patch196天然全局。
10. ViT 为什么需要大数据?
这是 ViT 最大特点。
CNN 自带:
局部性假设 平移不变性 共享卷积核例如:
猫耳朵在哪里都像猫耳朵。
ViT:
没有这些假设。
它需要自己学习:
什么是边缘 什么是纹理 什么是物体所以:
小数据:
CNN > ViT大数据:
ViT > CNN11. ViT 参数规模
常见版本:
| 模型 | Patch | Embedding维度 | Layer |
|---|---|---|---|
| ViT-Base | 16×16 | 768 | 12 |
| ViT-Large | 16×16 | 1024 | 24 |
| ViT-Huge | 14×14 | 1280 | 32 |
例如:
ViT-B/16:
B = Base 16 = Patch大小输入:
224×224产生:
196 Patch12. ViT 代码结构(PyTorch简化版)
classViT(nn.Module):def__init__(self):super().__init__()# Patch Embeddingself.patch_embed=nn.Conv2d(3,768,kernel_size=16,stride=16)# CLS Tokenself.cls_token=nn.Parameter(torch.randn(1,1,768))# Transformerself.encoder=nn.TransformerEncoder(...)# 分类self.head=nn.Linear(768,num_classes)defforward(self,x):# 图片切Patchx=self.patch_embed(x)# B,C,H,Wx=x.flatten(2)# 转Tokenx=x.transpose(1,2)# 加CLScls=self.cls_token.expand(x.size(0),-1,-1)x=torch.cat([cls,x],dim=1)# Transformerx=self.encoder(x)# CLS分类x=x[:,0]returnself.head(x)13. ViT 面试八股总结
Q1:ViT 如何处理图片?
答:
ViT 将图片切分成固定大小 Patch,将每个 Patch 展平并通过线性层映射成 Token,再加入位置编码和 CLS Token,输入 Transformer Encoder 进行特征学习。
Q2:为什么需要 CLS Token?
答:
CLS Token 是一个可学习向量,通过 Self-Attention 聚合所有 Patch 信息,最终作为整张图片的表示用于分类。
Q3:Patch Embedding 怎么实现?
两种方式:
方法1:
reshape+Linear方法2:
Conv2d(kernel_size=patch_size,stride=patch_size)实际 ViT 常用第二种。
Q4:ViT 为什么比 CNN 强?
答:
ViT 利用 Self-Attention 建模全局关系,并且结构天然适合扩大模型规模,在大规模数据预训练后具有更强泛化能力。
14. 一句话总结 ViT
ViT 就是把图片切成很多小块,把每个小块当成 NLP 里的单词,然后交给 Transformer 学习这些视觉 Token 之间的关系,最后利用 CLS Token 完成图像理解。
记忆口诀:
图片 ↓ 切Patch ↓ Patch Embedding ↓ 加CLS + 位置编码 ↓ Transformer Encoder ↓ CLS分类这就是 ViT 的全部核心思想。