共计 1548 个字符,预计需要花费 4 分钟才能阅读完成。
传统 CNN 的瓶颈在哪里?
在 CIFAR-10 这样的 32×32 小尺寸图像分类任务中,CNN 的局部感受野设计反而可能成为限制。典型的 3 ×3 卷积核每次只能看到 9 个像素点的关系,虽然通过堆叠卷积层可以扩大感受野,但这种间接的全局信息获取方式会导致:
- 浅层网络难以建模长距离依赖
- 深层网络出现梯度消失 / 爆炸
- 重复下采样造成空间信息丢失
这解释了为什么在 CIFAR-10 上,ResNet-18 的测试准确率常年在 94-95% 徘徊。
Transformer 的破局之道
| 模型 | 参数量 (M) | FLOPs(G) | 准确率 (%) |
|---|---|---|---|
| ResNet-18 | 11.2 | 0.56 | 94.7 |
| ViT-Tiny | 5.7 | 1.3 | 96.2 |
| Swin-Tiny | 28.3 | 4.5 | 97.1 |
上表展示在相同训练配置下的性能对比
Transformer 通过自注意力机制实现了:
- 全局感知能力:每个 patch 可以直接与其它所有 patch 交互
- 动态权重分配:重要区域自动获得更高注意力权重
- 并行计算优势:无需像 CNN 那样顺序执行卷积操作
关键实现步骤
Patch Embedding 实现
# 将 32x32 图像切割成 8x8 的 patch(共 16 个)class PatchEmbed(nn.Module):
def __init__(self, img_size=32, patch_size=8, in_chans=3, embed_dim=192):
super().__init__()
self.proj = nn.Conv2d(in_chans, embed_dim,
kernel_size=patch_size,
stride=patch_size) # 输出形状:(B, 192, 4, 4)
self.norm = nn.LayerNorm(embed_dim)
def forward(self, x):
x = self.proj(x) # [B, C, H, W] -> [B, D, H/P, W/P]
x = x.flatten(2).transpose(1, 2) # -> [B, num_patches, D]
return self.norm(x)
位置编码可视化

不同颜色的方块代表不同位置的位置编码向量,可以看到相邻 patch 具有相似但不同的编码
训练循环核心代码
scaler = torch.cuda.amp.GradScaler()
for epoch in range(epochs):
model.train()
for x, y in train_loader:
x, y = x.to(device), y.to(device)
with torch.cuda.amp.autocast():
logits = model(x)
loss = criterion(logits, y)
optimizer.zero_grad()
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
性能优化实战
显存占用对比
| Batch Size | ResNet-18 | ViT-Tiny |
|---|---|---|
| 128 | 2.1GB | 3.4GB |
| 256 | 4.2GB | 6.8GB |
学习率策略影响
余弦退火相比阶梯下降获得更稳定的收敛过程
避坑指南
- 位置编码优化 :
- 对小尺寸图像使用可学习的位置编码
-
尝试相对位置偏置 (relative position bias)
-
过拟合对策 :
- 使用 CutMix 数据增强
- 添加 Stochastic Depth
- 限制 attention head 数量 (4→2)
迁移到医疗影像的思考
医疗影像往往具有:
– 更高分辨率 (512×512+)
– 更精细的局部特征
– 更小的数据集规模
改进方向可能包括:
1. 设计多尺度 patch 提取
2. 结合 CNN+Transformer 的混合架构
3. 使用自监督预训练
正如我们看到的,Transformer 在计算机视觉领域展现出了惊人的潜力。它是否终将完全取代 CNN?或许未来的答案在于两者的有机融合。
正文完
发表至: 未分类
近两天内
