论文:https://arxiv.org/abs/2103.14030 如有侵权请联系博主
前几天读TCPMFNet时了解到了Transformer还可以应用到图像领域,这就激起了我的兴趣,刚好有了解到了VIT之后又推出了Swin Transformer,接下来我们就来一起看看吧。
总体的架构图如上,好像看着很复杂,其实后面四个阶段的做的工作是相同的,也就是说我们只要搞清楚一个阶段做的工作,就已经搞明白了整个架构的大部分了,这是不是就有学习的动力了,接下来我们一起来看看。
就看这一块就完事了
和我们之前了解的VIT相同,Patch Partition就是将原图划分为了一个个的小块(patch,4x4),然后在经过Linear Embeding将每个patch转换为我们想要的维度C,这两个过程也是可以直接通过一次卷积就可以实现,具体的步骤可以参考TCPMFNet中相关讲解。在图中也可以看到相关的注解,即原来H/4 xW/4 x 48转换为了H/4 x W/4 x C的输出(transformer中数据的维度不会发生变化)。
到这里你可能有点问题,H/4 xW/4 x 48 介是嘛呀
在前面我们已经知道了,每一个patch的大小是4x4,假设图片的高为H,宽为W,那样就可以划分为H/4 x W/4 个patch,一个patch中像素值数量为4x4即16,再乘通道数3,48就是这么来的,这一部分是Patch Patition的工作,Linear Embeding就是将H/4 xW/4 x 48 投射到C维度,即H/4 x W/4 x C。
Swin Transformer稍后仔细去讲,现在我们只需要知道经过他就是经过了一个transformer就可以了。
然后我们看一下Patch Merging,顾名思义哈,就是融合这些patch,那么为什么融?怎么融?
首先是为什么融?
类似于CNN的池化层,就是将token的数量减少,一方面减少了计算复杂性,另一方面也可以产生多尺度的特征。
那么怎么融?
即相邻的4个patch,被融为一个patch,4个patch在通道维度进行排列,此时一个patch的通道数是4C,然后再通过线性层将每个patch的通道数降为2C。具体过程看下图
通过上图的操作,你就会发现,需要处理的token数减少了四分之一,但每个token的维度变成了原来的两倍。通过Patch Merging原来的H/4 x W/4 x C变成了H/8 x W/8 x 2C,stage3和stage4的操作也与之相同,经过处理之后就变成了H/16 x W/16 x 4C和H/32 x W/32 x 8C。
这时再看最开始的结构图,你就会发现只剩swin transformer我们不了解,其他的都已经知道了。接下来我们就来讲swin transformer最重要的部分 ———— swin transformer block。
首先,相比于VIT直接使用transformer的原始架构,swin transformer有什么改进呢?
我们知道在VIT在Patch Patition和Linear Embeding阶段和swin transformer是大致相似的,其中不同就在多头注意力(MSA)计算这个部分,VIT对整张图片的token进行计算,即每个token都会与其他的token进行计算,而swin transformer则是在窗口内计算,这个窗口是MxM(默认为7,即包含7x7个patch)大小的。
这就很有趣了,因为M是固定的,那么无论图片尺寸如何增大,他的整体计算复杂度也是线性增加的,与VIT的复杂度对比如下
这里MSA是VIT的计算复杂度,W-MSA是swin transformer的计算复杂度,可见MSA的复杂度是hw的二次方级,而W-MSA的计算复杂度与hw成线性关系。
看到这里你觉得是不是有点问题,我们在上一篇博客中提到,transformer相对于CNN来说可以关注全局信息,这就是transformer相对于cnn的一个优势,但这里进行窗口内的多头注意力计算,这是不是违背了使用transformer的初衷?
但很幸运的是,swin transformer提出的滑动窗口就是为了解决这个问题。
那么滑动窗口是怎么作用的呢,来看下下面这张图
不知道大家是什么感觉,反正我第一眼我不知道这在干啥
那么我们一起来看看,从上面的图中,我们可以看到左图的窗口划分(红色边界划分为一个窗口)之后每一个窗口都是4x4大小的,即每一个窗口包含4x4个patch(灰色边界线是一个patch),此时就可以进行第一步计算了,即W-MSA,在每一个窗口中独立进行多头注意力计算即可。之后,将窗口的划分线沿着对角线平移M/2距离即可,即x轴向下平移M/2,y轴向下平移M/2,这时就出现了右图的划分情况。
但这时我们发现每一个窗口的尺寸不再是相同的了,如果强行将每一个窗口填充到4x4大小无疑会增加计算量,作者就采用移动这些尺寸不合适的窗口,将这些窗口从新拼接成一个个新的窗口,从而使得每一个窗口仍然都是4x4大小。过程如下
在这里还做一下mask,因为在移动之后会使得原本不相邻的patch变成相邻的,原本不相邻的patch不应该进行计算。
那么应该怎么做mask呢,我们知道softmax计算时如果数是负数,他分到的权重就会很小,我们可以利用这个性质,即当我们对一个patch进行多头注意力的计算时,如果窗口中的某些patch与其并不相邻,那么与这个patch对应的QK设置为复数,在经过softmax之后,这个权重就等于0了,则经过计算之后,每一个元素中所含的信息不会包括之前不相邻元素的信息。 但是别忘记,计算结束之后需要将所有的块位移到原位置。
通过上诉两种划分情况的不断交替就可以是得每一个patch都包含所有patch的信息,这里以一个动态图来模仿这个过程。
这里将整张图片分成四个区域,分别是1234,12就代表该patch有1,2两个区域内的信息,1234就代表该patch有1,2,3,4四个区域的信息。动态图中共经过了两次W-MSA和一次SW-MSA。
这时候再看总体架构图中的右图,就会清晰了很多
W-MSA和SW-MSA就是两种MSA的方式,W-MSA是所有的窗口的patch都是原本就相邻的,直接计算即可,而SW-MSA是所有的窗口的patch并非就是原本就相邻的,需要将各种形状的窗口拼接在一起,从而使每个窗口的形状大小都一样。
最后来看下Attention的计算,唯一与transformer不同的就是这个B,即相对位置。
在粗略的读完之后,只能说一句 小牛拉屁股——开了眼,在读完TCPMFNet之后就对图像领域的transformer有了兴趣,读完之后确实受益匪浅。
个人觉得很好的地方
这次的博客是自己的一个笔记,想到啥就写啥了,写的有点糙。
[1] Swin Transformer: Hierarchical Vision Transformer using Shifted Windows