目录
前言
1、Swin Transformer简介
2、Swin Transformer模型原理
2.1 Swin Transformer模型整体框架
2.2 基于窗口的自注意力计算
2.3 基于移动窗口的自注意力计算
2.4 PatchMerging
总结
这是新手入门级理解Swin Transformer的原理。在大家想看Swin Transformer的原理的时候,小编建议大家先去看一下ViT模型的原理,Vision Transformer可以说是Transformer处理视觉任务的开山之作,可以说Vision Transformer成功的将视觉问题转换成了NLP问题,它成功的将2D的图像通过打成多个patch块来转换Transformer能处理的1Dpatch序列,Swin Transformer在前面也是借鉴了Vision Transformer对于图片的处理方法,如果大家看了并理解了Vision Transformer,那在座的各位兄弟将会更容易理解Swin Transformer
Swin Transformer名字的前部分Swin来自于Shifted Windows,Shifted Windows(移动窗口)也是Swin Transformer的主要特点。Swin Transformer的作者的初衷是想让Vision Transformer像卷积神经网络一样,也能够分成几个block做层级式的特征提取,从而导致提出来的特征具有多尺度的概念。
标准的Transformer直接用到视觉领域有一些挑战,难度主要来自于尺度不一和图像的resolution较大两个方面。首先是关于尺度的问题,例如一张街景的图片,里面有很多车和行人,并且各种物体的大小不一,这种现象不存在于自然语言处理。再者是关于图像的resolution较大问题,如果以像素点为基本单位,序列的长度就变得高不可攀,为了解决序列长度这一问题,科研人员做了一系列的尝试工作,包括把后续的特征图作为Transformer的输入或者把图像打成多个patch以减少图片的resolution,也包括把图片划成一个一个的小窗口,然后再窗口里做自注意力计算等多种办法。针对以上两个方面的问题,Swin Transformer网络被提出,它的特征是通过移动窗口的方式学来的,移动窗口不仅带来了更大的效率,由于自注意力是在窗口内计算的,所以也大大降低了序列的长度,同时通过Shiting(移动)的操作可以使相邻的两个窗口之间进行交互,也因此上下层之间有了cross-window connection,从而变相达到了全局建模的能力。
层级式结构的好处在于不仅灵活的提供各种尺度的信息,同时还因为自注意力是在窗口内计算的,所以它的计算复杂度随着图片大小线性增长而不是平方级增长,这就使Swin Transformer能够在特别大的分辨率上进行预训练模型。
图1
我们来给定一张图片,来看看图片在Swin Transformer 模型中是如何变化的。在看到这些维度变化的时候,我相信在座的各位心中满满的疑问,这什么狗屁作者,竟然也不写怎么变化来的,不急不急,如何变化来的详细细节在整体流程的下面,也就是说基于窗口自注意力、基于移动窗口自注意力、patchmerging关键技术讲解部分,这样写的目的是希望大家跟我一样带着满脸疑问来学习。我希望当大家看完后面的技术部分再来看这一小节,相信大家会更容易理解看懂。
1、给定一张224*224*3的图片,先将图片打成patch,patch size设置为4*4,经过patch partition后图片的尺寸为56*56*48(56=224/4,48=16*3,3为RGB通道数)
2、接下来进入linear embedding层,linear embedding层会将输入向量的维度变成预先设置好的值即Transformer能够接受的值,若此处将超参数C设置成96,那么向量大小就变成了56*56*96,然后经过拉直变成3136*96,3136就是序列的长度,96成为了每个token的维度。在Swin Transformer中的patch partition层和linear embedding层相当于ViT模型的patch projection层操作,在代码里用一次卷积就能够完成。
3、Swin Transformer在最前面将2D的图片处理成1D的序列的方法同ViT模型没有什么较大的区别。前面处理好的序列的长度为3136,但相对于ViT模型里的196来说太长了,在这里就用到了基于窗口的自注意力,每个窗口都有7*7=49个小patch,所以序列长度就变成了49,这样就解决了计算复杂度的问题。基于窗口的自注意力在下面进行介绍。这里实在是困惑,建议兄弟可以先去看看下面如何基于窗口计算注意力。
4、如果我们想要有多尺寸的特征信息,就要构建一个层级式的Transformer,也就是说需要像卷积神经网络里一样有一个池化的操作,所以这里就提出了parch merging的操作。经过patch merging之后我们的整张图片的尺寸就从56*56*96变成了28*28*192。
5、再经过一个Transformer Block(如图3.1中的stage2),维度不变仍然是28*28*192。图3.1中的stage3和stage4的过程和stage2基本一致。通过stage4之后维度就变成了7*7*768。
6、最后Swin Transformer并没有像ViT一样使用CSL token,而是像卷积神经网络一样在得到最后的特征图之后用了一个global average polling(全局池化的操作)直接将7*7取平均拉直变成1。如果是在ImageNet数据集上做分类任务,那么最后将1*768变成1*1000。这就完成了整个网络的分类任务。
基于全局的自注意力计算会导致平方倍的复杂度,当进行视觉里的下游任务时尤其是密集预测型任务或者非常大尺寸的图片时,基于全局计算自注意力的复杂度会非常的高,而Swin Transformer则采用了窗口计算自注意力。
图2
如图,原来的图片会不重叠的分成多个窗口,但窗口并不是最小的计算单元,最小的计算单元是窗口里的patch图像块,每个窗口里都有m*m个patch,在Swin Transformer的原文中,m的值一般默认为7,此时每个窗口里就有49个patch,自注意力计算都是分别在窗口内完成的,所以序列长度永远都是49。
基于窗口计算自注意力的方式虽然很好的解决了内存和计算量的问题,但是窗口与窗口之间没有了通信,没能达到全局建模的效果,这就限制了模型的能力。移动窗口被提出后,先进性一次窗口的自注意力计算,再进行一次移动窗口后的自注意力计算,这样就实现了窗口与窗口之间的通信,从而达到了全局建模的效果。
图3
图3是由图2向右下角移动2个patch的单位得到,原来的窗口与移动后的窗口有了重叠的部分,这样就到达了窗口与窗口之间的相互通信。虽然已经能达到窗口与窗口之间的通信,但是原来的特征图只有4个窗口,经过移动窗口后,得到了9个窗口,窗口的数量有所增加并且9个窗口的大小也不是完全相同,这就导致计算难度增加。
Swin Transformer原作者团队使用了循环移位和掩码操作的方式,既保证了移动窗口后窗口的数量保持不变,也保证了每个窗口内的patch数量不变。
图4
通过循环移位,由图4中的window partition图变成图4的cyslic shift图,经过循环移位后,图片重新分成4个窗口,移动窗口前是4个窗口,经过循环移位后仍是4个窗口,这就使得窗口数量还是4个,窗口的数量就固定了,这就使得计算难度降低了。
循环移位后仍然有一些问题存在,A,B,C所在的三个窗口中不仅包含了原本就在这个地方的元素,同时也包含了A,B,C三个从很远的地方移位过来的元素,每个窗口中原本存在的元素和移位过来的元素之间是没有什么较大的关系的,因为二者离的比较远,所以我们不需要对二者进行注意力的计算。针对这个问题Swin Transformer原作者团队提出了掩码操作,从而能够让一个窗口中不同的区域之间能用一次前向过程就能把自注意力就散出来,而相互之间都不干扰。以下将举例说明循环移位和掩码操作的具体计算过程。
图5
图5是经过循环移位后得到的图,图的大小为14*14,每个窗口的大小为7*7,其中数字0~8用来区分不同的区域。
现在0号区域为一个窗口,1号、2号区域为一个窗口,3号、6号区域为一个窗口,4号、5号、7号、8号 区域为一个窗口。2号和5号区域相当于图3.3中的B区域,6号、7号相当于图3.3中的C区域,8号相当于图4中的A区域。
0号区域所在的窗口内的所有元素可以相互去做自注意力的计算。
对于1号和2号区域所在的窗口,1号区域是原图区域,但2号取悦是从别的地方移位过来的,所以这两个区域是不相同的,他们之间不应该做自注意力的计算。
对于3号和6号所在的窗口,3号区域是原图区域,但6号区域是从别的地方移位过来的,所以这两个区域是不相同的,他们之间不应该做相互的自注意力计算。
最复杂的是4号、5号、7号、8号区域所在的窗口,4号区域是原图区域,5号、7号、8号区域是从别的地方移位过来的区域,所以这4个区域都不相同,他们之间也都不应该去做自注意力的计算。
以3号、6号区域所在窗口来举例说明自注意力是如何计算以及掩码是如何设置的。
图6
3号和6号区域所在的窗口内有49个patch,每个patch都是一个向量,如果现在把这个窗口拉直,就变成了如图6的矩阵,矩阵大小为49*1,这个矩阵一共有4*7=28个3号位元素,有3*7=21个6号位元素,每个向量的维度是C。
图7
图6的矩阵经过转置后得到图7的矩阵,这两个矩阵相乘得到图8的矩阵。
图8
在图8中两两相同的元素是可以做自注意力计算的,如33、66,这样的矩阵元素需要保留。两两不同的元素是不需要做自注意力计算的,如36、63,这样的矩阵元素需要通过加上掩码的方式将其掩掉。
图9
掩码的设置如图9,需要掩掉的部分相加的掩码部分是-100,需要留下的部分相加的掩码部分是0,相加后需要留下的还是原来的数。此时,需要掩掉的部分变成了负数,整个相加掩码后的矩阵通过softmax函数后需要掩掉的部分就变成了0,需要保留的部分仍然是原数。
想要有多尺寸的特征信息,就要构建一个层级式的Transformer,也就是说我们要像卷积神经网络里一样有一个池化的操作,所以就提出了patch merging。Patch merging 顾名思义,合并小patch成一个大patch,这样就起到了下采样一个特征图效果的了。
图10
如图10左上角一个简单的张量,patch merging的操作是将临近的小patch合并成一个大patch,这样就能达到下采样一个特征图的效果。
如果说想下采样两倍,那就每隔一个patch选取一次,对于图10左上角的张量来说,每次选的点事1、1、1、1,图10的1,2,3,4并不是矩阵里的值,而是为方便在这里给它定义的一个序号,序号只是帮助理解的,同样序号的patch就会被合并到一起,经过采样之后,一个张量就变成了如图10右上角的4个张量,所有的1号都在一起,所有的2号都在一起等等。
如果原来张量的维度是h*w*c,经过采样之后,每个张量的维度的大小就变成了(H/2)*(W/2),尺寸都缩小了一倍,将4个张量在C维度上进行拼接,得到的张量的大小就变成了(H/2)*(W/2)*4C,相当于用空间上的维度去换了更多的通道数,就像卷积神经网络里的池化操作一样,为了跟卷积神经网络保持一致,只想让通道数翻倍而不是变成4倍,所以后边又做了一次卷积操作,在C的维度上用了一次1*1的卷积,把通道数降成了2C,经过这一系列操作之后,原来一个大的张量就变成了(H/2)*(W/2)*2C的一个张量。以上整个过程就是patch merging。
小编感觉,你能有耐心看到这里实属不易,如果换成小编自己的话,我看到一半只想说好烦啊,这什么玩意啊!所以你比小编好很多了已经。
无论是图像分类,还是图像分割,亦或是视频,Swin Transformer已经出现在视觉领域的各项任务中,并且已经成为了屠榜的存在,我的毕业设计题目是Transformer在计算机视觉中应用的研究,除了理解Swin Transformer原理以外,我还实现了以下几点,并也写在CSDN中。
Swin Transformer源码基于win10实现分类模型的预训练(ImageNet-1k数据集)
Swin Transformer使用预训练模型训练自己数据集实现特定类别分类
Swin Transformer实现图像实例分割并训练自己的数据集
如果大家能够赏个脸,也可以去看下我写的关于以上Swin Transformer的博客
最后感谢大家赏个赞吧,比心心!!!!