Swin Transformer

22年初的屠榜模型

题目:用了移动窗口的层级式的vision transformer

摘要:Swin transformer可以作为CV中通用骨干网络。与NLP不同的第一个是对象尺度的问题,第二是多次提到的分辨率太大的问题,之前工作已经用很多办法减少过输入模型的序列长度。移动窗口可以让每次只计算一个窗口内的自注意力,而移动操作使得窗口之间有了交互,使得上下层级之间变相的拥有了全局建模的能力,非常类似CNN,也就是说这个归纳偏置(先验知识)已经又和CNN差不多了,即首先关注局部信息。层级结构不仅可以提供各个尺度的信息,而且计算复杂度随图像大小线性增长(而非平方级别)。

导言:先看图,朱老师说CV中多尺度特征是一个很重要的事,之前无论是分类还是分割任务,都用一些办法尽可能的发挥各个尺度上特征的作用。

ViT处理的都是单一尺寸的特征(16*16),所以可能并不适合密集预测的任务,如分割。此外,它的自注意力始终是在整张图上进行,所以其计算复杂度是图片尺寸的平方倍增长。而Swin里面每一个窗口大小一固定,计算复杂度就固定了,窗口数量随图片大小线性增长。他这里提到全局计算自注意力对于CV来说是浪费资源的,例如同一个物体的不同部位,或者语义相近的不同物体总是在同一块区域出现的。

这里我也想到,对于海洋来说,可能需要根据数据的分辨率,来确定各个尺度的过程对应什么样大小的窗口以及信息互通的程度,比如说,也许大到一定尺度的时候完全不需要再提取高层的特征,只需要进行简单的信息交流就够了。

如何生成多尺寸特征:在CNN中,我们通过池化操作来扩大卷积核的视野范围,类似的,在Swin中这里提出了一个patch merging,将相邻的小patch合并为一个大patch。

 ViT是只有16*16的patch,Swin是从底到顶逐渐增大的。有了各个尺寸的特征以后就可以给FPN(第一个图)做检测或者构造Unet做分割。

 如图所示,灰色是patch,红色是窗口。移动窗口的意思就是将红色窗口往右下角移了两个patch。之前的方法窗口和窗口之间的Patch是无法交流的,如果一个目标刚好被分到两个窗口里就无法构成一个完整的语义信息。现在滑动窗口以后,patch之间可以进行cross window connection。 再配合上patch merging,到模型的最后几层时就可以看到大部分图片了。

 这里的流程可以看到,特征图的维度尽可能地与CNN保持一致,每经过一层,特征图大小减半,通道翻倍。具体patch merging方式在上面手画的图上,将特征图分为小patch,然后标号1234,将相同标号的取出来,变成四个通道,就完成了大小减半。但此时的特征图是四倍,所以再用1x1卷积缩小一下通道数。

 图3b是一个完整的Swin块,首先是一个普通的多头块,然后是一个移动窗口的多头块,两个块叠在一起构成一次完整操作。所以在a图中只要有swin的地方块数都是偶数。

 之前的移动窗口示意图可以看到,原本四个窗口移动完之后变成9个了,增加了两倍多。更重要的问题是每个窗口长度不一样,没有办法压成一个batch进行快速的矩阵乘法。所以这里又提出了上图的解决办法:四个窗口移动完以后,其实也就能保证最中间的那个窗口还是完整的,那剩下的就想办法补,这里是把左上角的移动到右下角,然后重新分成四个块,也就是说之前中间那个完整块变成左上角了,剩下三个块都是拼的。这样计算完注意力之后,再把块移动回去,否则多叠几层block原图就面目全非了。

 但是你只有一块图是完整的,可以正常计算自注意力。剩下三块都是拼的,算出来的东西根本没意义。所以剩下三块根据其拼图的规则,再按照矩阵运算的法则,设计出三种对应的掩码。只保留运算结果中有意义的注意力,把原本不相邻的拼凑在一起之后,两块东西之间的东西都掩码掉不要了。这地方我想了想,要意识到一点,其实在实际应用中,窗口数量比这个要大得多,真实要做拼凑再掩码这一步的只是最外围,中间大多数都是正常的。我第一反应是拼凑的那些边角料不能正常用上吗?后来反应过来边角上的块本来就没法给它凑完整的信息了,它放在这些位置上能够自己和自己注意力一下,已经是最高效的解决方案了。

做这件事情最重要的就是为了并行,使得模型能够更便宜一点。

 

posted @ 2023-04-19 21:38  诸葛村夫CC  阅读(193)  评论(0编辑  收藏  举报