一篇文章讲明白 Vision Transformer(ViT)

📅 2026/7/10 20:21:33 👁️ 阅读次数 📝 编程学习
一篇文章讲明白 Vision Transformer(ViT)

一篇文章讲明白 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个Token

4. Patch Embedding:Patch 怎么变成 Token?

Transformer 不认识:

16×16图片块

所以需要映射。

原始:

Patch 768维

经过 Linear:

768 ↓ 768

得到:

Patch Token

类似 NLP:

单词 ↓ Embedding ↓ 词向量

图片:

Patch ↓ Embedding ↓ 视觉Token

5. 加入 CLS Token

现在有:

Patch1 Patch2 ... Patch196

但是分类需要:

整张图片 → 一个类别

怎么办?

加入:

CLS Token

输入变成:

CLS Patch1 Patch2 ... Patch196

总共:

197 Tokens

CLS 的作用:

汇总所有 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 最大区别

CNNViT
基本单位像素Patch
核心操作卷积Attention
感受野逐渐扩大直接全局
先验知识
数据需求较少较多
扩展能力一般

CNN:

第一层:

看附近像素

第二层:

看更大区域

慢慢获得全局信息。


ViT:

第一层 Attention:

Patch1 直接看到 Patch196

天然全局。


10. ViT 为什么需要大数据?

这是 ViT 最大特点。

CNN 自带:

局部性假设 平移不变性 共享卷积核

例如:

猫耳朵在哪里都像猫耳朵。

ViT:

没有这些假设。

它需要自己学习:

什么是边缘 什么是纹理 什么是物体

所以:

小数据:

CNN > ViT

大数据:

ViT > CNN

11. ViT 参数规模

常见版本:

模型PatchEmbedding维度Layer
ViT-Base16×1676812
ViT-Large16×16102424
ViT-Huge14×14128032

例如:

ViT-B/16:

B = Base 16 = Patch大小

输入:

224×224

产生:

196 Patch

12. 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 的全部核心思想。