一、实验内容
- **Vision Transformer (ViT) **的内容可见视频:https://www.bilibili.com/video/BV1Jh411Y7WQ/
- Swin Transformer的内容可见视频:https://www.bilibili.com/video/BV1pL4y1v7jC/
- 视觉Transformer综述可见视频:https://www.bilibili.com/video/BV1cr4y1m7tS/
- 代码练习可以使⽤⾕歌的 Colab(它是⼀个 Jupyter 笔记本环境,已经默认安装好 pytorch,完全在云端运⾏),使用教程:https://www.cnblogs.com/lfri/p/10471852.html
二、实验过程
2.1 视频学习
笔记如下:
2.1.1 Vision Transformer (ViT)
https://blog.csdn.net/2401_89740151/article/details/154704991
2.1.2 Swin Transformer
https://blog.csdn.net/2401_89740151/article/details/154705370
2.1.3 基础知识备忘录
https://blog.csdn.net/2401_89740151/category_13063550.html
2.2 pytorch 实现 ViT
用 CIFAR-10(32×32) 做演示,模型是小号 ViT,训练更容易收敛。
0) 环境检查与准备
# 如果是打开一个全新 Colab,建议先重启一次运行时,然后再跑本单元 |
1) 配置参数
说明:把常用超参数放在一起,便于修改实验规模。
from dataclasses import dataclass |
2) 数据集与数据增强(CIFAR-10)
训练集做轻度增强(随机裁剪/水平翻转)。
import torch |
3) ViT 组件:PatchEmbed / Attention / MLP / Block
按 Transformer Encoder 的标准实现。
import torch |
4) ViT 主体:位置编码 / [CLS] / 堆叠 Block / 分类头
实现 ViT 主体。位置编码与 [CLS] 是关键;输出用 [CLS] 表示整图特征。
class ViT(nn.Module): |
5) 训练准备:损失/优化器/调度器/评估函数
使用 AdamW + 余弦退火;可选混合精度(AMP);提供 evaluate()。
import torch.optim as optim |
6) 训练循环
结果如图1.
from pathlib import Path |
7) 加载权重与快速推理
加载保存的权重,以及对几张图片做预测。结果如图2.
import torchvision |
![]() |
![]() |
|---|---|
| 图1 训练循环结果 | 图2 推理结果 |
2.3 回答相关问题
2.3.1 在ViT中要降低 Attention的计算量,有哪些方法?(提示:Swin的 Window attention,PVT的attention)
A. 限域与分块
- 使用窗口注意力:只在固定大小窗口内做注意力,计算量近似线性随分辨率增长。
- 使用条带/十字/轴向注意力:改成行/列或十字形局部关注。
B. 下采样 K/V 或减少序列长度
- Spatial-Reduction Attention:对 K/V 特征做步幅下采样,Q 全量、K/V 变少,从而把复杂度从 N² 降到 N·(N/r²)。
- Token Pooling / Patch Merging / Strided Conv:在层间逐步减小 token 个数。
2.3.2 Swin体现了一种什么思路?对后来工作有哪些启发?(提示:先局部再整体)
Swin 的核心思想其实挺符合人类的视觉习惯——“先看局部,再看整体”。一开始,它在小窗口里看局部细节,就像你先盯着图片的一块区域。 然后它在下一层把窗口平移一下,这样前后两层的窗口就会有重叠,模型就能逐步把这些局部信息拼成全局的理解。
这种从局部到全局的层次式结构非常聪明。它让 Transformer 拥有了类似 CNN 的多尺度特征(高分辨率看细节、低分辨率看整体),而且计算量控制得很好。
也因为这个设计,后面很多模型都跟着它走,比如 CSWin、Twins、SwinV2,都在模仿它的思路:先高效建局部,再逐步扩全局。Swin 的启发就是让大家意识到:Transformer 不一定要看全局,分阶段整合信息反而更高效、更稳。
2.3.3 有些网络将CNN和Transformer结合,为什么一般把 CNN block放在面前,Transformer block放在后面?
CNN 擅长低层局部特征,Transformer 擅长高层全局语义,前者打地基,后者盖高楼。CNN 的卷积特别擅长捕捉局部纹理,像边缘、角点、颜色变化这些低级特征。而 Transformer 擅长的是全局关系,比如哪两个区域属于同一个物体、或者整体的语义是什么。
所以在结构上,大多数人会先用 CNN 做前端特征提取——相当于帮 Transformer 打好底,再用 Transformer 去处理全局信息。
还有一个很现实的原因:图像刚开始的时候分辨率特别大,patch 特别多,如果一上来就用 Transformer,显存会炸。CNN 可以在前面先做降采样,把特征图缩小,给后面的 Transformer 减轻负担。
2.3.4 阅读并了解Restormer,思考:Transformer的基本结构为 attention+ FFN,这个工作分别做了哪些改进?
Restormer 是一个专门为**图像复原(比如去噪、去模糊、超分辨) **设计的 Transformer。它把原来的两个部分——Attention 和 FFN 都改得更懂图像了。
在 Attention 这块,它用了一个叫 MDTA(Multi-DConv Head Transposed Attention) 的结构。简单来说,它先在算注意力前后加了深度卷积,这样模型不光能看全局关系,还能看到局部纹理细节。另外,它的注意力不是在空间上算(HW×HW),而是在通道维度上算(C×C),这让高分辨率图片的计算量小很多,效率更高。
在 FFN 这块,它用了 GDFN(Gated-DConv Feed-Forward Network)。它在原来的两层全连接中间加了门控机制和深度卷积。门控让网络能自动判断哪些信息该保留,哪些可以忽略,而卷积让 FFN 有了局部感知能力,更适合处理图像。整体结构也变成了一个 U-Net 风格 的 Transformer,有 encoder、decoder 和跳跃连接,所以特别适合恢复类任务。
三、问题与体会
这次学习让我对 Transformer 在视觉领域的应用有了更深的理解。一开始我只知道 ViT 是把图像切成小块去做注意力,但没想到计算量这么大,也没意识到后面有那么多改进的方向。通过对比 Swin、PVT、Restormer 这些模型,我发现大家其实都在解决同一个问题——让 Transformer 更懂图像、更高效地处理高分辨率数据。
我觉得 Swin 的思路特别有启发性。它没有一上来就做全局建模,而是从局部窗口开始,逐步扩展到全局。这种“先局部、再整体”的设计很像我们人看图的方式,也说明在深度学习里,很多有效的想法其实来自常识。

