最近在学习深度学习和机器学习的相关知识,在这里记录一下学习的模型和个人的一些感悟,文章包括了模型的讲解和项目源码。由于自身水平原因,总体会比较偏白话,适合小白,如果有出错的地方请大家指正。
1、项目源码以及主要参考
博客讲解:https://blog.csdn.net/qq_37541097/article/details/121119988
B站讲解:链接地址
源码地址:链接地址
主要的库文件的相关版本:
torch 1.10.1+cu102
torchaudio 0.10.1+cu102
torchvision 0.11.2
tensorflow 2.4.1
numpy 1.23.4
(具体的由于库的版本问题引起的警告或者报错可以直接百度解决)
数据下载:https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz (可以直接复制链接到迅雷下载)
2、Swin-Transformer介绍
Swin Transformer是2021年微软研究院发表在ICCV上的一篇文章,并且已经获得ICCV 2021 best paper的荣誉称号。它可以作为计算机视觉的通用backbone,并且在很多视觉底层任务中取得了Sota的水准。
上图是Swin Transformer在Vit论文基础上做出的改进。可能很多人和我一样在读过Vit的情况下看到这张图就是一脸懵。在读文章前,我先简单介绍一下模型中的一些“单位”。
像素:一张图片的最小单位
Patch:由相邻的几个像素组成的一个正方形区域
Window:由相邻的若干Patch组成的一个正方形区域
例如:在轻便版的swin transformer tiny中有:
1 Patch = 4x4 像素
1 Window = 7x7 Pacth
所以上面的(a)图中的4x 可以简单理解为,取4个窗口作为一个整体进行操作;同理8x可以理解为,取8个窗口作为一个整体进行操作(多头自注意力W-MSA)等等······
所以相比于之前的Vit模型,我们的Swin Transformer模型一次性取的窗口数较少,减少了矩阵运算的维度,从而减少了运算量,但同时这样也有一些缺点,我们将在下面的讲解中提及。
3、模型的构成
Swin Transformer模型如下图所示,一般情况下,下面的结构作为Backbones Network(骨干网络)使用,简单来说就是可以用这些结构提取特征,然后按照我们的需求在后面加上一个全连接层来完成回归或者分类任务。
3.1 Patch Partition
首先将图片输入到Patch Partition模块中进行分块,即每4x4相邻的像素为一个Patch,然后在channel方向展平(flatten)。假设输入的是RGB三通道图片,那么每个patch就有4x4=16个像素,然后每个像素有R、G、B三个值所以展平后是16x3=48,所以通过Patch Partition后图像shape由 [H, W, 3]变成了 [H/4, W/4, 48]。(来自博主:太阳花的小绿豆)
这部分可以简单理解为划分和展平,将4*4的像素划成一个Patch,其中每个Patch中的像素不重复,所以图像横向的Patch数为W/4,纵向的Patch数为H/4(后面我们将以Patch为单位进行操作) 。
每个Patch所具有的4x4=16个像素,对于RGB图像又有着3个Channel ,所以每个Patch的特征数量为4x4x3=48个。
3.2 Linear Embedding
该部分就是直接通过一个卷积层,将图像(H/4)x(W/4)x48变成(H/4)x(W/4)xC,也就是一个“映射”的操作,将原先的48个维度映射到我们想要的C维度,代码中间的C为96 。
3.3 Swin Transformer Block
其实该部分就是下图的这两个操作,所以我们能发现Swin Transformer Block总是2的整数倍,因为每个版块都有两个部分。Swin Transformer Block模块并不会改变图片的相关尺寸。
Layer Normal(LN)
LayerNorm是归一化的一种方法,下面是Pytorch文档中的官方说明,如果有感兴趣的可以查看这篇博客 https://blog.csdn.net/weixin_41978699/article/details/122778085
Windows Multi-head Self Attation (W-MSA)
窗口多头自注意力模块的作用,我个人的理解是提取窗口与窗口之间的联系,打个比方,对于一个猫猫头,眼睛得在鼻子上面,嘴巴在鼻子下面,这就是一种空间上的特征,而自注意力操作则是提取出这种特征。
这里有一点需要注意的就是,窗口间的自注意力操作是对于相邻的几个窗口而言的,比如上图标号为1,2,3,4的窗口间可进行自注意力,但是1,2就不能和9,10进行自注意力操作。
在第二部分,Swin-Transformer介绍 ,我们讲解过,Swin transformer相比于Vit取的作自注意力的窗口数减少了,因此大大减小了运算量。但是同时,我们也失去部分区域的空间特征,比如窗口4,5,6,7组成的部分,因此论文提出了一种叫做滑动窗口的方法。
Windows Multi-head Self Attation (SW-MSA)
滑动窗口的原理类似于用一个模具切割一张图片,我们把模具向右移动两厘米,向下移动两厘米,然后再切割照片,这样就能得到图像不同空间区域的特征,但是这样又引出了一个问题,我们做自注意力一般正方形比较好,所以论文作者就进行了一个A,B,C的编码,然后重新组成正方形(下面的cyclic shift部分)。
此外,考虑到编码后的“正方形”原来可能不是连在一起的Windows,不能作自注意力,论文作业又进行了一个masked操作,可以理解为用一张布遮住本不应该做自注意力的那部分的结果。这样我们就能在保证减少了计算量的基础上还提取了空间中多尺度的特征。
想更加输入了解的可以参考B站的这个讲解视频: Swin Transformer论文精读
MLP
该部分就是一个使用 GELU 激活函数 + Dropout 的全连接层。
3.4 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的高和宽会减半,深度会翻倍。
4、源码的使用
代码地址:github
数据集地址:https://storage.googleapis.com/download.tensorflow.org/example_images/flower_photos.tgz
简单来说就是下载好数据集合源码后,进入train.py文件,设置好数据集的路径以及图像分类的类数就可以直接跑程序了,如果想跑自己的数据集,可以将数据集按照下图的模型放置。
如果觉得Swin Transformer Tiny性能不够,还可以选择下图的其他版本,只需在train.py前面修改这一串代码就行。
from model import swin_tiny_patch4_window7_224 as create_model
文章来源:https://www.toymoban.com/news/detail-628863.html
第一次写这么长的文章,自己水平有限,有些地方还不够严谨,希望大家能给我一个小小的赞!文章来源地址https://www.toymoban.com/news/detail-628863.html
到了这里,关于Swin-Transformer 实战代码与讲解(快速上手)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!