目录
- 1 介绍
- 2 摘要
- 3 模型架构
- 4 窗口自注意力
- 5 移动窗口自注意力
- 5.1 巧妙的掩码方式
- 5.2 相对位置编码
- 6 总结
论文:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
代码:https://github.com/microsoft/Swin-Transformer
Huggingface:https://hub.fastgit.org/rwightman/pytorch-image-models/blob/master/timm/models/swin_transformer.py
1 介绍
论文题目是:Swin Transformer是一个用了移动窗口的的层级式Vision Transformer。Swin = Shifted WINdows。移动窗口是这篇论文的主要贡献。Swin Transformer实际上就是想着让ViT像卷积神经网络一样,也能够分成几个block,也能做这种层级式的特征提取,这样提取出来的特征有多尺度的概念。
Swin Transformer相关的模型当年霸榜视觉检测榜前十。
2 摘要
这篇论文提出来一个新的Vision Transformer,叫做Swin Transformer,可以被用来作为计算机视觉领域通用的骨干网络。如果直接把Transformer从NLP用到Vision领域是有一些挑战的,主要来自于两个方面:
- 一个是尺度上的问题,例如一张图片上面有大大小小不同的物体,代表同样语义的词比如说行人或者汽车,有不同的尺寸,这种现象在NLP领域是没有的;
- 另一个挑战是图像的resolution太大了,如果我们以像素点作为基本单位的话,这个序列的长度就会变得高不可攀,所以之前的工作要么就是用后续的特征图来当做Transformer的输入,要么就是把图片打成patch,减少图片的resolution,要么把图片划分成一个个小的窗口,然后在窗口里做自注意力,所有的这些方法都是为了减少序列的长度。
基于这两个挑战,作者就提出多层级的Transformer,特征是通过一种叫做移动窗口的方式学来的。移动窗口的好处不仅带来了更大的效率,因为自注意力是在窗口内计算的,所以序列的长度大大的降低了,同时通过移动的操作,能够让相邻的两个窗口之间有了交互,所以上下层之间可以有cross-window connection,从而变相地达到了全局建模的能力。
这种层级式的结构的好处是:
- 非常灵活,可以提供各个尺度的特征信息;
- 自注意力是在小窗口内计算的,计算复杂度是随着图像的大小而线性变化的,而不是平方级变化,从而可以在特别大的分辨率上去预训练模型。
因为Swin Transformer拥有了像卷积神经网络一样的分层的结构,有了多尺度的特征,所以很容易被使用到下游任务中,包括在图像分类、密集预测型的任务上(物体检测、分割)的成绩都遥遥领先。
这种基于Transformer的模型在视觉领域是非常有潜力的,对于MLP的这种架构,用shifted window的方法也有提升。
3 模型架构
下图是模型总览图,Swin Transformer的patch size是4×4,而不是像ViT一样16×16,先不考虑Swin Transformer Block里的移动窗口自注意力操作,前向过程如图所示:
如果是图像分类任务,得到最后的7×7×768输出之后,再接上一个global average polling,就是全局池化操作,直接把7×7取平均拉直变成1了,最终变成1×768,再经过一个全连接层之后变成1×1000。这里和ViT使用的cls token不一样。作者没有把这部分画到图里,因为Swin Transformer的本意不只是做分类,还会去做检测和分割,所以这里只画了骨干网络的部分。
4 窗口自注意力
以第一个Swin Transformer block之前的输入举例子,它的尺寸是56×56×96。
计算复杂度:
公式(1)的具体计算过程如下:
对于窗口自注意里的复杂度,首先,对于一个窗口,patch数不是h×w,而是M×M,将 h=M 和 w=M 代入公式(1),就能得到1个窗口的自注意力计算复杂度。我们总共有 h/M×w/M个窗口,乘以1个窗口的自注意力复杂度公式,就能得到公式(2)了。
这两个公式的第一项相同,第二项由hw变成了MM,将h=56、w=56和M=7代入公式,发现结果相差了几十甚至上百倍。
5 移动窗口自注意力
为了能让窗口和窗口之间能够通信起来,作者提出了移动窗口的方法。移动窗口示意图:
最开始的窗口如左图所示,现在把窗口往右下方移动一半,就变成右图这种形式。Swin Transformer Block的安排是有讲究的,每次都是要先做一次基于窗口的多头自注意力(第一个Block),然后再做一次移动窗口的多头自注意力(第二个Block),这样就达到了窗口和窗口之间的互相通信,这两个Block加起来,才算是Swin Transformer的一个基本计算单元。所以模型的配置里,每个stage下面的配置数都是偶数,也就是说Block总是偶数,因为它始终需要两层Block连在一起作为一个基本单元。
5.1 巧妙的掩码方式
原来只有4个窗口,移动窗口后,变成了9个窗口,计算复杂度成倍增加。
为了提高移动窗口的计算效率,作者采取了一种非常巧妙的masking掩码方式,通过循环移位的方式,首先先将上方的A和C移到下面,然后再将左边的B和左下方的A移动到右边,这样就得到了下图中间cyclic shift这种图了,就又变成了4个窗口了,窗口数量固定了,计算复杂度也固定了。经过带掩码的多头注意力之后,再反向循环移动,这样又恢复回原图了。
具体的计算方式,作者在issue38里做了一个掩码的可视化如下图所示。整体思路是,把每个窗口里的元素拉直,和自己转置后的矩阵相乘,例如windows2,结果是33和66的保留,结果是36和63的置成-100,这样计算softmax的时候就能把36和63的值给掩盖掉了。
详细的视频介绍可以参考:Swin Transformer论文精读,移动窗口自注意力这一节。
5.2 相对位置编码
论文没有使用绝对位置编码,而是使用相对位置编码的方式。
6 总结
Swin Transformer的几种变体:
这篇论文提出了Swin Transformer,是一个层级式的Transformer,计算复杂度是跟输入图像的大小呈线性增长的。Swin Transformer在COCO和ADE20K上的效果都非常好,远远超越了之前最好的方法。这篇论文最关键的贡献是基于shifted window的自注意力,对很多视觉任务尤其是下游任务例如密集预测型任务非常有帮助。