视觉 Transformer (ViT)
视觉 Transformer(Vision Transformer,简称 ViT)是将 Transformer 架构应用于图像处理的开创性工作,打破了卷积神经网络(CNN)在视觉领域的垄断。
核心原理
传统方法的局限
在 ViT 之前,计算机视觉主要依赖 CNN:
- 局部感受野
- 难以捕捉全局关系
- 需要大量卷积层堆叠
ViT 的创新
ViT 将图像视为"Token 序列":
-
图像切块(Patch Embedding):
- 将图像分割成固定大小的块(如 16×16)
- 每个块展平为向量
- 通过线性投影转换为嵌入
-
位置编码:
- 添加可学习的位置嵌入
- 保留空间位置信息
-
Transformer 编码器:
- 标准的多头自注意力
- 全局信息交互
图像 → 切块 → 线性投影 → 添加位置编码 → Transformer → 分类头
模型结构
输入处理
假设图像大小为 H×W×C,块大小为 P×P:
- 块数量 N = (H×W) / (P×P)
- 每个块维度:P×P×C
- 投影后维度:D(隐藏维度)
特殊 Token
- [CLS] Token: 用于分类任务的特殊标记
- 位于序列开头
- 最终输出用于分类
架构变体
| 变体 | 层数 | 隐藏维度 | 头数 | 参数量 |
|---|---|---|---|---|
| ViT-Base | 12 | 768 | 12 | 86M |
| ViT-Large | 24 | 1024 | 16 | 307M |
| ViT-Huge | 32 | 1280 | 16 | 632M |
ViT 的优势
1. 全局注意力
- 每个 Patch 都能关注所有其他 Patch
- 更好地捕捉长距离依赖
- 适合需要全局理解的任务
2. 扩展性
- 随着数据和模型规模增加,性能持续提升
- 比 CNN 有更好的 scaling law
3. 统一架构
- 视觉和语言使用相同的 Transformer 架构
- 便于多模态模型的构建
ViT 的挑战
1. 数据饥渴
- 需要大规模数据(JFT-300M 级别)
- 在小数据集上表现不如 CNN
2. 计算复杂度
- 自注意力复杂度 O(N²)
- 高分辨率图像计算成本高
3. 缺乏归纳偏置
- 没有 CNN 的局部性和平移不变性
- 需要更多数据来学习这些特性
重要变体
DeiT(Data-efficient Image Transformers)
- 引入知识蒸馏
- 可以在 ImageNet 上从头训练
- 不需要超大数据集
Swin Transformer
- 层次化设计
- 滑动窗口注意力
- 线性复杂度
- 适合下游任务(检测、分割)
BEiT(BERT 预训练用于图像)
- 借鉴 BERT 的掩码预训练
- 自监督学习
- 更好的特征表示
MAE(Masked Autoencoder)
- 随机掩码 75% 的图像块
- 重建被掩码的部分
- 高效的自监督预训练
在多模态中的应用
ViT 是现代多模态模型的基础:
CLIP
- 图像编码器使用 ViT
- 对比学习图文对
- 强大的零样本能力
GPT-4V / GPT-4o
- 视觉编码器基于 ViT
- 与语言模型深度融合
LLaVA
- ViT 提取视觉特征
- 映射到语言模型空间
代码示例
使用 Hugging Face Transformers:
from transformers import ViTImageProcessor, ViTForImageClassification
from PIL import Image
# 加载模型和处理器
processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224')
model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224')
# 处理图像
image = Image.open('image.jpg')
inputs = processor(images=image, return_tensors="pt")
# 推理
outputs = model(**inputs)
predicted_class = outputs.logits.argmax(-1).item()
发展趋势
- 高效注意力: 减少计算复杂度
- 多尺度设计: 更好地处理不同分辨率
- 与 CNN 融合: 结合两者优点
- 视频理解: 扩展到时序数据