ICCV最佳论文:Swin Transformer

swin transformer 训练效果 不如 resnet_卷积

 

 Swin,其实就是Shifted Win dows的意思,即使用一个滑动窗口的ViT工作。

 

相对来说,ViT只是证明了Transformer在图片分类领域的效果非常好,但是Swin Transformer,则将这个东西推广到了CV的方方面面,告诉大家,不管什么任务,都用Transformer就好了,而确实这个模型在CV领域已经大杀四方。

 

和ViT相比:

swin transformer 训练效果 不如 resnet_卷积_02

 

 即Swin在小窗口上做自注意力,和ViT在整张图上做自注意力来对全局进行建模不同。

这个想法其实也借鉴了CNN的设计思想。

swin transformer 训练效果 不如 resnet_卷积_03

swin transformer 训练效果 不如 resnet_卷积_04

 (最小的是patch(4x4的像素),4x4的patch组成了一个窗口,即window,最大的黄色框是一个滑动示意图,每次滑动半个Window,这样每次在窗口中做的自注意力,就可以和其他窗口做交互了)

 

 为什么叫shift window而不是Window,就因为它移动的其实不是整个Window。如上图,它对于一个整体来说,往右下角移动了两个patch,那么就会得到一个新的划分,变成了右边的格式。这样的话,窗口与窗口之间就会有重叠,从而可以互相学习到特征。否则一个窗口里的特征永远学不到其他窗口的特征,这样就会让self-attention变得具有全局建模的能力。

当然了,这个SHifted window是不能运用到NLP里的,所以如果在“NLP与CV模型大一统”这一点上的成就来说,Swin还是不如ViT的。

 

Method

swin transformer 训练效果 不如 resnet_数据_05

 

 

 这个架构有点模仿CNN了,特别是这个patch merging。

他输入了一张HW3的图,这里这个HxWx3指的是像素,在patch parition之后,H和W变成原来的1/4,因为每一个patch的大小约定为了4x4,而48指的是每一个patch的纬度数(4x4x3),这样就打好了patch。

打好patch后,送入线性Embedding层,调整到我们需要的维度(或者说transformer能够接受的维度),这个维度在Swin中被设置成了一个超参数C,原论文C=96.

而后面的patch merging,就更有意思了,它和卷积处理之后的结果很相似,即降低数据尺寸,增大数据维度,如下图。

swin transformer 训练效果 不如 resnet_滑动窗口_06

 

 它对每一个patch做了重新编码,即每一个patch分为1/2/3/4四个位置,随后将相邻的4个位置的patch里的1号抽取出来单独作为一个切片,2、3、4位置做同样操作,随后将它们叠在一起,将数据从H W C变成了H/2 W/2 4C。随后再对C的维度做一个1x1的卷积,将其缩小一倍,这样就得到了H/2 W/2 C/2的结果,和卷积处理得到的结果是一致的。

而且不只是维度上在和CNN保持一致,其为了和CNN保持一致,甚至没有使用ViT中的 CLS token。

 

总之就是将ViT设计成层级式的结构(Patch Merging),为了减少复杂度,所以又提出了基于窗口和移动窗口的自注意力机制(右边的block)

 

神奇的掩码方式

我们从上面那个斜着移动半个大小的窗口可以看出,这样子移动得到的窗口会将原本的4x4的4个patch划分成9个大小不一的patch。但是现在存在一个问题。窗口数量增加了,且大小不一,这样子会极大地增大运算资源的消耗。如果将所有的窗口pad成4x4,压成相同大小的patch,但是仍然会有很大的复杂度(本来只算4个窗口,现在需要算9个)

所以原作者提出了一个非常巧妙的移动方法,就像玩七巧板一样:

swin transformer 训练效果 不如 resnet_卷积_07

 

 也就是说,我们将原本的被切开的块拼接到目标位置的窗口,这样就又会变成一个4x4的窗口大小。当然这会引入一个新的问题,即我们拼接过来的这几块内容,它和其他内容并不相同。

举个栗子,比如这幅图是太阳从山头升起来了,那么AC区域可能就是太阳,而中间的正方形区域可能就是山头,但是如果把AC放到下面来,那就变成了太阳从山脚升起来了,那整个图片的语义信息就被破坏掉了。

所以我们需要保证,拼接过来的这些不相邻的元素,不应该被计算Attention。

因此,Swin就引出了一个非常巧妙地掩码操作。从而,将不同窗口的相邻的窗口做了Attention之后,再将ABC拼接回去即可。

swin transformer 训练效果 不如 resnet_滑动窗口_08

 

 这里这个例子举得是36号patch,做自注意力其实就是两个矩阵的乘法,相乘结果如右图,3/3之间可以进行自注意力,6/6之间也可以进行自注意力,但是36之间不可以,因此我们要将副对角线的两块置零。那么最终这个矩阵要经过一层Softmax,因此我们给整个矩阵做一个主对角线为0,副对角线为-100(很小的负数)的减法,这样将副对角线的数据都变成负数,再经过Softmax时,就被成功置零了。

其他操作亦是如此,原作者也曾回应过具体的细节,如下:

swin transformer 训练效果 不如 resnet_滑动窗口_09

 

 太牛逼了!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

看到这里,我真的佩服,它这个best paper,当之无愧。

 

另外,它对于ViT的这种层级式的使用,让我想起了之前的PointNet和PointNet++。Pointnet和Transformer都是一种基本的骨干网络,但都是领域中的开山之作,即使用这个网络,能够很高效地处理领域中的数据。比如PointNet,他就是第一个直接将原始点云喂到模型中去的,而不需要将其进行多面积投影、体素化等将其变成规则的数据预处理。但是它没有考虑点与点之间的联系,于是,原作者就有了下一篇工作——pointnet++,即在不同层次(或者说尺度)去多次使用Pointnet模型,从而达到一个更高的高度。

ViT和Swin Transformer也给我这种感觉,只不过他们不是同一个作者,如果是同一个作者,可能Swin Transformer就不叫这个了,就会叫ViT++。Swin Transformer也是在不同层次上去使用ViT的方法。所以我现在觉得,对开山之作多次合理地使用,有没有可能是科研上的一种成功论之一呢?

二者在调用时都遇到了不同的问题。PointNet++的challenge是点云没有结构和次序,是杂乱且稀疏的,所以如何分批次地去使用PointNet是一个问题,因此作者提出了2种多尺度采点的方法去搭模型;

而Swin Transformer的challenge是多层次的调用会造成非常大的计算开销,且在目前来看,送入Transformer的向量长度是不现实的,因此提出了窗口的概念,为了更好地吸收相邻像素的邻近特征,还提出了滑动窗口的概念,而提出滑动窗口带来了新的challenge,即滑动后的窗口大小不一,且计算开销翻两倍不止,所以又提出了七巧板拼接的方式去限制模型的开销,而七巧板模型又带来了新的challenge,即如果计算不相邻的patch的attention会对原图的语义信息造成破坏,因此又非常巧妙地设计了一种掩码模板来解决这个问题。

可以说,是从一个idea出发,提出方式,制造挑战,克服挑战,带来新的挑战,克服挑战,制造挑战……最终,将挑战全部完成,成就了这一篇best paper!!