[2010.11929] An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
VIT
核心思想:把一张二维图片切成很多小块(patch),把每个 patch 当成 NLP 中的一个 token,然后直接交给标准 Transformer Encoder
定义图片
$$
\mathbf{x}\in\mathbb{R}^{H\times W\times C}
$$
把图片切成 $P\times P$
patch 总数为
$$
N=\frac{HW}{P^2}=\frac{H}{P}\frac{W}{P}
$$
再把每个 Patch 展平成一个向量
$$
\mathbf{x}_p\in\mathbb{R}^{N\times(P^2C)}
$$
使用一个可以训练的矩阵
$$
\mathbf{E}\in\mathbb{R}^{(P^2C)\times D}
$$
把每个 patch 的维度进行压缩得到 **Patch Embedding**
$$
P^2C\rightarrow D
$$
就可以得到可以送入Transformer层的语义向量了
在这之前还需要添加一个位置向量
$$
\mathbf E_{pos}\in\mathbb R^{(N+1)\times D}
$$
这里 +1 是因为VIT延续了Bert的设计,在开头加了一个[CLS]
以ViT-B/16为例,使用Pytorch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 输入图片 [B, 3, 224, 224]
↓ Patchify: 16×16
[B, 196, 3, 16, 16]
↓ Flatten 每个 Patch
[B, 196, 768]
↓ Linear Projection [这里只是刚好语义维度也是768]
[B, 196, 768]
↓ 添加 CLS Token
[B, 197, 768]
↓ 加 Position Embedding
[B, 197, 768]
↓ Transformer Encoder × 12
[B, 197, 768]
↓ 取 CLS
[B, 768]
↓ Classification Head
[B, num_classes]
|
[2103.14030] Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
核心思想:把图片切成较小的 Patch,但不把整张图片作为一个长序列做全局 Attention,而是在二维特征图上划分 Window,只在 Window 内做 Attention;然后不断 Patch Merging 下采样,得到多尺度特征
Patch Embedding
定义图片:
$$
\mathbf{x}\in\mathbb{R}^{H\times W\times C}
$$
Swin 原论文使用 $P=4$
$$
H\times W\rightarrow\frac H4\times\frac W4
$$
每个 Patch 原始维度为 $4\times4\times C$
再通过 Linear Projection 转换到定义的特征维度
1 2 3 4 5 6 7 8 9 10
| 输入 [B, 3, 224, 224]
↓ Patchify 4×4
[B, 56, 56, 48]
↓ Linear Projection
[B, 56, 56, 96]
|
这里和 ViT 最大区别之一是 Swin 更强调保留二维结构
Window Partition
Swin 没有让所有 Token 互相 Attention
而是划分成 7 × 7 Window
1 2 3 4 5 6 7 8 9 10 11 12 13
| [B, 56, 56, 96]
↓ Window Partition 7×7
[B, 64, 7, 7, 96]
↓ Window Flatten
[B, 64, 49, 96]
↓ 把 Window 合并到 Batch
[B×64, 49, 96]
|
然后每一个 49 Token 的小序列再做自注意力
W-MSA
第一个 Swin Block 使用 W-MSA Window Multi-head Self-Attention
1 2 3 4 5 6 7
| ┌───────┬───────┐ │Window │Window │ │ A │ B │ ├───────┼───────┤ │Window │Window │ │ C │ D │ └───────┴───────┘
|
只允许:
1 2 3 4
| A 内部互相 Attention B 内部互相 Attention C 内部互相 Attention D 内部互相 Attention
|
不同 Window 暂时不通信
SW-MSA
如果永远使用固定窗口 Window A 和 Window B 永远无法交换信息
所以第二个 Swin Block 把 Window 移动一下
SW-MSA Shifted Window Multi-head Self-Attention
移动
$$
\left\lfloor\frac M2\right\rfloor=3
$$
Shift 之后,一个新的 Window 就可能同时包含多个 window 的一部分 token
实现跨 Window 信息交流
因此 Swin Block 通常两个一组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| Block 1 LN ↓ W-MSA ↓ Residual ↓ LN ↓ MLP ↓ Residual
Block 2 LN ↓ SW-MSA ↓ Residual ↓ LN ↓ MLP ↓ Residual
|
Patch Merging
这是 Swin 和 ViT 非常大的另一个区别
ViT 基本一直保持 token 数不变
而 Swin 会下采样
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| 输入图片 [B, 3, 224, 224]
↓ Patchify 4×4
[B, 56, 56, 48]
↓ Linear Projection
[B, 56, 56, 96]
================ Stage 1 ================
↓ W-MSA
[B, 56, 56, 96]
↓ SW-MSA
[B, 56, 56, 96]
↓ Patch Merging
[B, 28, 28, 192]
================ Stage 2 ================
↓ W-MSA
↓ SW-MSA
[B, 28, 28, 192]
↓ Patch Merging
[B, 14, 14, 384]
================ Stage 3 ================
↓ W-MSA ↓ SW-MSA ↓ W-MSA ↓ SW-MSA ↓ W-MSA ↓ SW-MSA
[B, 14, 14, 384]
↓ Patch Merging
[B, 7, 7, 768]
================ Stage 4 ================
↓ W-MSA
↓ SW-MSA
[B, 7, 7, 768]
↓ Global Average Pooling
[B, 768]
↓ Classification Head
[B, num_classes]
|
Swin-T 的 Stage 深度就是 [2,2,6,2]