[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]

Swin Transformer

[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]