从零学习SwinTransformer
论文信息
论文名称:Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
原论文地址: https://arxiv.org/abs/2103.14030
官方开源代码地址:https://github.com/microsoft/Swin-Transformer
本篇博客参考文章:从零学习SwinTransformer
名词解答
⌊M/2⌋: 表示向下取整
像素通道: 参考-图像的通道数问题
描述一个像素点,如果是灰度,那么只需要一个数值来描述它,就是单通道。
如果一个像素点,有RGB三种颜色来描述它,就是三通道。
四通道图像,R、G、B加上一个A通道,表示透明度。一般叫做alpha通道,表示透明度的。
2通道图像不常见,通常在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便。
dense prediction理解:
标注出图像中每个像素点的对象类别,要求不但给出具体目标的位置,还要描绘物体的边界,如图像分割、语义分割、边缘检测等等
WindowPatchToken理解:
假设输入图片的尺寸为224X224,先划分成多个大小为4x4像素的小片,每个小片之间没有交集。224/4=56,那么一共可以划分56x56个小片。每一个小片就叫一个patch,每一个patch将会被看成一个token,所以patch=token。而一张图被划分为7x7个window,每个window之间也没有交集。那么每个window就会包含8x8个patch。
一张图有224(pixel)X224(pixel)= 56(个patch)x56(个patch)x4(pixel)x4(pixel)=7(个window)x7(个window)x8(个patch)x8(个patch)x4(pixel)x4(pixel)
不懂可看下图,图中本想画出224*224像素的图片,奈何画不了,所以就画一部分就可以说明划分关系。其中图中每个小方块中包含4x4个像素,红色框起来的8x8个patch为一个window,这样的window一张图片有7x7个,每个window之间也没有交集。那么每个window就会包含8x8个patch。
疑问: 图中那4x4个patch组成的叫啥:好像啥也不叫,只是顺手画出来的。哦,下图中的4x4个patch组成的东西是一个window的一个计算单元,一个window中有4x4个这样的单元,用于计算self-attention,意思就是在计算self-attention时是8x8个patch作为一个单元去跟别人计算的。
网络整体框架
原论文中给出的关于Swin Transformer(Swin-T)网络的架构图。通过图(a)可以看出整个框架的基本流程如下:
输入image
假设模型的输入是一张224x224x3
的图片
Patch Partition详解
首先将图片输入到Patch Partition模块中进行分块,即每4x4个相邻的像素划分为一个patch,即在上面画的图,将图片划分一个一个的patch。
详解每4x4个像素(3通道)如何展平为1x1个patch(48通道)?
大概以上的图形就可示意每4x4个像素(3通道)如何展平为1x1个patch(48通道)。
对224x224个像素(3通道)的图片都这样处理,会得到(56,56)个patch,48通道,特征图大小为(56,56,48)见下图第二个带绿色部分的立体图。
再复述一遍以上的过程:将上面4x4=16个像素的图然后在通道(channel)方向展平(flatten)。假设输入的是RGB三通道的图片,那么每个patch就有4x4=16个像素,然后每个像素有R、G、B三个值,所以展平后是16x3=48,所以通过Patch Partition后图像的shape由 [H, W, 3]=(224,224,3)变成了 [H/4, W/4, 48]=(56,56,48)。上图中的最左下角的第一张图片是将一张图划分patch之后的样子,简略示意(224,224)个pixel,3通道,展平之后展平为(56,56)个patch,48个通道。
之后就没像素什么事了,后来都是在patch上的讨论。
Linear Embedding详解
参考:Swin Transformer全方位解读【ICCV2021最佳论文】
(56,56,48)————Linear Embedding———>(56,56,96)
这个层优点感觉像是卷积层,只不过是对通道数进行卷积
Linear Embeding层对每个patch的channel数据做线性变换,由48变成C=(96),即图像shape再由 [H/4, W/4, 48]=(56,56,48)变成了 [H/4, W/4, C]=(56,56,96)。每个图片被划分为56x56=3136个patch,每个patch又被编码成96维的向量。
这一步在代码上实现十分简单,就是一个Conv2D,把步长和kernel size都设置为patch的长度即可,可看:
nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)
这步以后再flatten一下,就可以把56x56x96变为3196x96。
Swin Transformer Block(W-MSA、SW-MSA)详解
与标准transformer不同的就是紫色部分的两个框,分别是W-MSA和SW-MSA。
W-MSA表示,在window内部的Multi-Head Self-Attention,就是把window当做独立的全局来计算window中每个token两两注意力。
SW-MSA与W-MSA的一丢丢不一样,就是将window的覆盖范围偏移一下,原文设置为window的边长的一半。
Swin Transformer Block注意这里的Block其实有两种结构,如图(b)中所示,这两种结构的不同之处仅在于一个使用了W-MSA结构,一个使用了SW-MSA结构。而且这两个结构是成对使用的,先使用一个W-MSA结构再使用一个SW-MSA结构。所以你会发现堆叠Swin Transformer Block的次数都是偶数(因为成对使用)。
W-MSA详解
全称为Window based Multi-head Self Attention。一张图平分为7x7个window,这些window互相都没有overlap。然后,每个window包含一定数量的token,直接对这些token计算window内部的自注意力。 以分而治之的方法,远远降低了标准transformer的计算复杂度。以第1层为例,7x7个window,每个window包含8x8个patch,相当于把标准transformer应用在window上,而不是全图上。
在Swin Transformer中使用了Windows Multi-Head Self-Attention(W-MSA)的概念,将特征图划分成了多个不相交的区域(Window),Multi-Head Self-Attention只在每个窗口(Window)内进行。相对于Vision Transformer中直接对整个(Global)特征图进行Multi-Head Self-Attention,这样做的目的是能够减少计算量的,尤其是在浅层特征图很大的时候。这样做虽然减少了计算量但也会隔绝不同窗口之间的信息传递,所以在论文中作者又提出了 Shifted Windows Multi-Head Self-Attention(SW-MSA)的概念,通过此方法能够让信息在相邻的窗口中进行传递。
引入Windows Multi-head Self-Attention(W-MSA)模块是为了减少计算量。如下图所示,左侧使用的是普通的Multi-head Self-Attention(MSA)模块,对于feature map中的每个像素(或称作token,patch)在Self-Attention计算过程中需要和所有的像素去计算。但在图右侧,在使用Windows Multi-head Self-Attention(W-MSA)模块时,首先将feature map按照MxM(例子中的M=2)大小划分成一个个Windows,然后单独对每个Windows内部进行Self-Attention。
两者的计算量具体差多少呢?原论文中有给出下面两个公式,这里忽略了Softmax的计算复杂度。:
h代表feature map的高度
w代表feature map的宽度
C代表feature map的深度
M代表每个窗口(Windows)的大小
W-MSA模块计算量详解
好像在计算计算量的时候不计算加法的次数。hw是第一个矩阵的行数,第一个C是一个行与列的计算量,第二个C是后一个矩阵的列数个前面的小计算量。
即矩阵L(ab)与P(bd)相乘,计算为abd,即(第一个矩阵的行数)x(第一个矩阵的列数)x(第二个矩阵的列数)。
SW-MSA详解
在局部window内计算Self-Attention确实可以极大地降低计算复杂度,但是其也缺失了窗口之间的信息交互,降低了模型的表示能力。为了引入Cross-Window Connection,SwinTransformer采用了一种移位窗口划分的方法来实现这一目标,窗口会在连续两个SwinTransformer Blocks交替移动,使得不同Windows之间有机会进行交互。
采用W-MSA模块时,只会在每个窗口内进行自注意力计算,所以窗口与窗口之间是无法进行信息传递的。为了解决这个问题,作者引入了Shifted Windows Multi-Head Self-Attention(SW-MSA)模块,即进行偏移的W-MSA。如下图所示,左侧使用的是刚刚讲的W-MSA(假设是第L层),那么根据之前介绍的W-MSA和SW-MSA是成对使用的,那么第L+1层使用的就是SW-MSA(右侧图)。根据左右两幅图对比能够发现窗口(Windows)发生了偏移(可以理解成窗口从左上角分别向右侧和下方各偏移了⌊M/2⌋个像素)。看下偏移后的窗口(右侧图),比如对于第一行第2列的2x4的窗口,它能够使第L层的第一排的两个窗口信息进行交流。再比如,第二行第二列的4x4的窗口,他能够使第L层的四个窗口信息进行交流,其他的同理。那么这就解决了不同窗口之间无法进行信息交流的问题。
根据上图,可以发现通过将窗口进行偏移后,由原来的4个窗口变成9个窗口了。后面又要对每个窗口内部进行MSA,这样做感觉又变麻烦了。为了解决这个麻烦,作者又提出而了Efficient batch computation for shifted configuration,一种更加高效的计算方法。下面是原论文给的示意图。
下图左侧是刚刚通过偏移窗口后得到的新窗口,右侧是为了方便大家理解,对每个窗口加上了一个标识。然后0对应的窗口标记为区域A,3和6对应的窗口标记为区域B,1和2对应的窗口标记为区域C。
然后先将区域A和C移到最下方。
接着,再将区域A和B移至最右侧。
移动完后,4是一个单独的窗口;将5和3合并成一个窗口;7和1合并成一个窗口;8、6、2和0合并成一个窗口。这样又和原来一样是4个4x4的窗口了,所以能够保证计算量是一样的。这里肯定有人会想,把不同的区域合并在一起(比如5和3)进行MSA,这信息不就乱窜了吗?是的,为了防止这个问题,在实际计算中使用的是masked MSA
即带蒙板mask的MSA,这样就能够通过设置蒙板来隔绝不同区域的信息了。关于mask如何使用,可以看下下面这幅图,下图是以上面的区域5和区域3为例。
对于该窗口内的每一个像素(或称token,patch)在进行MSA计算时,都要先生成对应的query(q),key(k),value(v)。假设对于上图的像素0而言,得到q0后要与每一个像素的k进行匹配(match),假设α0,0代表q0与像素0对应的k0进行匹配的结果,那么同理可以得到α0,0至α0,15。按照普通的MSA计算,接下来就是SoftMax操作了。但对于这里的masked MSA,像素0是属于区域5的,我们只想让它和区域5内的像素进行匹配。那么我们可以将像素0与区域3中的所有像素匹配结果都减去100(例如α0,2,α0,3,α0,6 ,α 0,7等等),由于α的值都很小,一般都是零点几的数,将其中一些数减去100后再通过SoftMax得到对应的权重都等于0了。所以对于像素0而言实际上还是只和区域5内的像素进行了MSA。那么对于其他像素也是同理。注意,在计算完后还要把数据给挪回到原来的位置上(例如上述的A,B,C区域)。
SW-MSA模块计算量详解
LayerNorm
相对位置偏置(relative position bias)
Patch Merging详解
在每个Stage中首先要通过一个Patch Merging层进行下采样(Stage1除外)。如下图所示,假设输入Patch Merging的是一个4x4大小的单通道特征图(feature map),Patch Merging会将每个2x2的相邻像素划分为一个patch,然后将每个patch中相同位置(同一颜色)像素给拼在一起就得到了4个feature map。接着将这四个feature map在深度方向进行concat拼接,然后在通过一个LayerNorm层。最后通过一个全连接层在feature map的深度方向做线性变化,将feature map的深度由C变成C/2。通过这个简单的例子可以看出,通过Patch Merging层后,feature map的高和宽会减半,深度会翻倍。
Relative Position Bias详解
真正使用到的可训练参数B是保存在relative position bias table表里的,这个表的长度是等于(2M−1)×(2M−1)的。那么上述公式中的相对位置偏执参数B是根据上面的相对位置索引表根据查relative position bias table表得到的,如上图所示。
参考:
Swin Transformer全方位解读【ICCV2021最佳论文】
Swin-Transformer网络结构详解
2021-Swin Transformer Attention机制的详细推导
(附加:CSDN上传图片去水印方法)
从零学习SwinTransformer相关推荐
- 快速系统从零学习OpenCV 4路线图
点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 转眼间,小白学视觉就要成立三周年了,小白一直是很感谢小伙伴们的支持 ...
- 【从零学习OpenCV 4】4种读取Mat类元素的的方法
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】Mat类构造与赋值
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】Mat类介绍
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】安装过程中问题解决方案
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】了解OpenCV的模块架构
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】Image Watch插件的使用
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习OpenCV 4】opencv_contrib扩展模块的安装
本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门 ...
- 【从零学习openCV】IOS7下的人脸检測
前言: 人脸检測与识别一直是计算机视觉领域一大热门研究方向,并且也从安全监控等工业级的应用扩展到了手机移动端的app,总之随着人脸识别技术获得突破,其应用前景和市场价值都是不可估量的,眼下在学习ope ...
最新文章
- PyTorch框架:(6)图像识别实战常用模块解读
- phpcmsV9 排序规则 - 小结篇
- (Windows和Linxu双系统)Alibaba套件sentinel1.7下载和nacos1.3和seate-server1.3下载
- 军队计算机使用管理规定,军队通用计算机系统使用安全要求.doc
- angularjs获取上一个元素的id_DOM(1)-DOM概念和获取元素
- C# WinForm 给某动态控件设置 IsBalloon = true的ToolTip 即 气泡状提示
- 推荐3个好用的Excel项目管理甘特图模板
- Linux学习笔记——网络组成
- 基于RFID的图书馆管理
- IT服务体系工具支撑
- Ue4首次项目的感想和心得
- 仿微信公众号界面实现
- 【springboot】5、lombok
- nvidia驱动,cuda与cudnn的关系
- 活化N-羟基琥珀酰亚胺酯疏水染料CAS: 201998-61-0,BDP 576 NHS溶于极性有机溶剂该试剂是染料的活化N-羟基琥珀酰亚胺酯,与伯氨基和仲氨基具有反应性。
- 打开从网络访问计算机,u盘启动大师Win7如何设置允许或拒绝从网络中访问本地电脑...
- 7所大学提供区块链、加密货币及金融科技相关线上课程
- 喝了38年的雪碧变样了!中国首发上市,白标原味、黑标无糖,加入两款新品 | 美通社头条...
- java计算器输入框_java实现计算器的输入框
- TMS320F2812调试记录一