Transformer in CV

title: 论文列表
1. ViT
	- An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale
	- Attention is all you need. 
	- Deep networks with stochastic depth.
2. Swin Transformer
	- Swin Transformer: Hierarchical Vision Transformer using Shifted Windows
3. VAN
	- Visual Attention Network

一、Transformer

1.1 Transformer系列模型更新

  • [[Transformer模型]] 架构于2017年6月推出
  • 2018年6月:GPT,第一份预训练的Transformer模型
  • 2018年10月:BERT,另一个大型预训练模型,旨在生成更好的句子摘要
  • 2019年2月:GPT-2,GPT的改进(和更大)版本
  • 2019年10月:DistilBERT,BERT的提炼版本,速度提高60%,内存减少40%,并且仍保留97%性能
  • 2020年5月:GPT-3,GPT-2的更大版本,能够在各种任务上表现良好而无需微调,称为零样本学习
  • 2021年6月:VIT(Vision Transformer)的发布成为了Transformer进军计算机视觉领域的里程碑
  • 2023年1月,OpenAI公司发布了聊天机器人ChatGPT,以高质量高水平高逻辑性的信息回复风靡全球

![[Pasted image 20230702162930.png]]

1.2 Self-Attention 注意力计算方式

Transformer中最重要的部分其实是Attention机制和Encoder-Decoder结构。Attention机制最关键的是自注意力的计算方法,但其实有很多的计算方式,Self-Attention的QKV机制只是其中之一,是其中较为流行的计算方式,见[[Transformer模型#4.1.1 Self-Attention中的QKV方法]]。

二、Vision Transformer

扩展阅读 ViT(Vision Transformer)解析 - 知乎 (zhihu.com)

基于torch的ViT代码实现

Transformer最初提出是针对NLP领域,并在NLP领域大获成功,几乎打败了RNN模型,已经成为NLP领域新一代的baseline模型。这篇论文Vision Transformer(VIT)也是受到其启发,尝试将Transformer应用到CV领域。通过这篇文章的实验,给出的最佳模型在ImageNet1K上能够达到88.55%的准确率(先在大型数据集JFT上进行了预训练),说明Transformer在CV领域确实是有效的,尤其是在大数据集预训练的支持之下,VIT因此也成为了Transformer进军CV的里程碑。

这个大数据的支持到底是多少呢?论文中作者做了相关实验,如下图所示。

横轴是不同的数据集,从左往右数据集容量依次是(130w,2100w,30000w)。竖轴是分类准确率。图中两条灰色之间的性能区间是ResNet纯卷积网络能达到的性能区间;不同颜色的圆形代表不同大小的VIT模型。结果表明当数据集容量为100w左右时,如ImageNet-1k,VIT模型的分类准确度是全面不如CNN模型的;当数据集容量为2100w左右时,如ImageNet-21k,VIT模型的分类准确度与CNN模型差不多;当数据集容量为30000w左右时,如JFT-300M,VIT模型的分类准确率略好于CNN模型的。
![[Pasted image 20230702165941.png]]

为了探究Transformer模型可以用于CV领域且效果优于卷积模型,ViT尽可能按照原始Transformer的结构来做,目的是保证控制变量,提供一个CV和NLP能共用的大一统算法框架,因此VIT在后序的多模态任务上,尤其是文本和图像结合的任务中也挖了个坑。

文章中,作者主要拿ResNet、ViT(纯Transformer)以及Hybrid(卷积和Transformer混合模型)三种模型进行比较。

2.1 Vision Transformer模型结构

![[Pasted image 20230702195613.png]]

ViT中Encoder输入的第一个位置的0向量与每一个输入信息均有交互类似BERT输入的第一个[CLS]向量,是对所有信息的总结。

模型主要由3个模块组成:

  • Linear Projection of Flattened Patches(Embedding层,目的是将子图映射成向量)
  • Transformer Encoder(上图右侧给出更加详细的结构,负责对输入信息进行计算学习)
  • MLP Head(最终用于分类的层结构,与CNN常用的top层设计类似)

2.1.1 Linear Projection of Flattened Patches

  • 对于标准的Transformer模块,要求输入的是token(向量)序列,即二维矩阵[num_token, token_dim]
  • 对于图像数据而言,数据格式为[H, W, C]是三维矩阵,明显不是Transformer想要的,所以需要先通过一个Embedding层来对数据做一个变换,这也是这个结构的设计目的。
  • 以ViT-B/16为例,将输入图片(224x224)按照16x16大小的Patch进行划分,划分后会得到( 224 / 16 ) * ( 224 / 16 ) =196个Patches。接着通过线性映射(Linear Projection)将每个Patch映射到一维向量中。
  • 线性映射:具体来说,直接使用一个卷积核大小为16 * 16,步距为16,卷积核个数为768的卷积来实现线性映射,这个卷积操作产生shape变化为[224,224,3]->[14,14,768],然后把H以及W两个维度展平(Flatten函数)即可,shape变化为[14,14,768]->[196,768]此时正好变成了一个二维矩阵,正好是Transformer想要的。其中,196表征的是patches的数量,将每个Patche数据shape为[16, 16, 3]通过卷积映射得到一个长度为768的向量(后面都直接称为token)。

在输入Transformer Encoder之前需要注意加上[CLS] token以及 Positional Embedding。为了使用[CLS]token而不是GAP(global average pooling)做分类的原因主要是参考bert,尽可能的保证模型结构与transformer类似来证明transformer在迁移到图像领域的有效性。

具体做法是:在经过_Linear Projection of Flattened Patches_后得到的一堆tokens中插入一个专门用于分类的[class]token,这个[class]token是一个可训练的参数,数据格式和其他token一样都是一个向量,以ViT-B/16为例,就是一个长度为768的向量,与之前从图片中生成的tokens拼接在一起,维度变化为 Cat([1, 768], [196, 768]) -> [197, 768]。由于transformer block中的self-attention机制可以关注到全部的token信息,因此我们有理由相信[CLS]token和GAP一样都可以融合transformer学习到的全部信息用于后续的分类计算。

关于Position Embedding

采用的是一个可训练的一维位置编码(1D Pos. Emb.),是直接叠加在tokens上的(add),所以shape要一样。以ViT-B/16为例,刚刚拼接[class]token后shape是[197, 768],那么这里的Position Embedding的shape也是[197, 768]。 自注意力是所有的元素两两之间去做交互,所以是没有顺序的,但是图片是一个整体,子图patches是有自己的顺序的,在空间位置上是相关的,所以要给patch embedding加上了positional embedding这样一组位置参数,让模型自己去学习patches之间的空间位置相关性。
作者对于不同的Position Embedding方式也有做一系列对比试验,结果如下图。在源码中默认使用的是1D Pos. Emb.,对比不使用Position Embedding准确率提升了大概3个点,和2D Pos. Emb.比起来没太大差别。作者的解释是,VIT是在patch-level上操作,而不是pixel-level。具体来说,在patch-level上,空间维度是(224/16)x(224/16),比pixel-level的小得多(224 x 224),在这个分辨率下学习表示空间位置,不论使用哪种策略,都很容易,所以结果差不多。
![[Pasted image 20230702205323.png]]

实际实验结果表明,不管使用哪种位置编码方式,模型的精度都很接近,甚至不适用位置编码,模型的性能损失也没有特别大。原因可能是ViT是作用在image patch上的,而不是image pixel,对网络来说这些patch之间的相对位置信息很容易理解,所以使用什么方式的位置编码影像都不大

2.1.2 Transformer Encoder

Transformer Encoder其实就是重复堆叠下图所示的Encoder Block L次,主要由以下几部分组成:
![[Pasted image 20230702205606.png]]

  • Layer Norm:这种Normalization方法主要是针对NLP领域提出的,这里是对每一个token进行Norm处理,作用类似于BN(Batch Normalization)六问透彻理解BN(Batch Normalization) - 知乎 (zhihu.com)

  • Multi-Head Attention:与[[Transformer模型#4.2.2 Multi-Head Self-Attention]]完全相同,就不展开叙述了。

  • Dropout/DropPath:原文直接使用Dropout层,但实现代码中使用的是DropPath(stochasitic depth)。

  • MLP Block:全连接层+GELU激活函数+Dropout。需要注意的是第一个全连接层会把输入结点翻四倍,[197, 768]->[197, 3072],第二个全连接层会返还原结点个数[197, 3072]->[197, 768]。

  • 在CV中,卷积可以同时处理通道和空间信息,在VIT中则分开进行处理。Encoder Block 的上半部分(包含MLP)对通道信息进行处理,下半部分对空间信息进行处理。

2.1.3 MLP Head

上面通过Transformer Encoder后输出的shape和输入的shape是保持不变的,以ViT-B/16为例,输入的是[197, 768]输出的还是[197, 768]。注意,在Transformer Encoder后其实还有一个Layer Norm没有画出来。

这里我们只是需要分类的信息,所以只需要提取出[CLS]token生成的对应结果就行,即[197, 768]中抽取出[CLS]token对应的[1, 768],因为self-attention计算全局信息的特征,这个[CLS]token其中已经融合了其他token的信息。接着我们通过MLP Head得到我们最终的分类结果。MLP Head原论文中说在训练ImageNet21K时是由Linear+tanh激活函数+Linear组成。但是迁移到ImageNet1K上或者你自己的数据上时,只用一个Linear即可。

值得注意的是,关于[CLS]token和GAP在原文中作者也是通过一些消融实验来比较效果的,结果证明,GAP和[CLS]token这两种方式能达到的分类准确率都差不多,所以,为了尽可能模仿Transfomer,这里选用了[CLS]token的计算方式,具体实验结果如下图
![[Pasted image 20230702211859.png]]

影响ACC的因素:Data + Model + Tragedy,前两者的影响比较大。
值得注意的是选择GAP的计算方式时要采用较小的学习率,否则会影响最终精度。这里值得总结的一点是:在深度学习中,有时候一个操作效果不好,不一定是操作的问题也有可能是训练策略的问题,即“炼丹技巧”。

2.2 model Scaling

在论文的Table1中有给出三个不同大小的模型参数(Base/Large/Huge),在源码中除了有Patch Size为16 * 16以外,还有32 * 32的。下表中的Layers就是Transformer Encoder中重复堆叠Encoder Block的次数,Hidden Size就是对应通过Embedding层后每个token的dim(向量的长度),MLP size是Transformer Encoder中MLP Block第一个全连接的节点个数(是Hidden Size的四倍),Heads代表Transformer中Multi-Head Attention的heads数。
![[Pasted image 20230702212445.png]]

三、Hybrid Vision Transformer

其实就是CNN和Transformer的混合模型,就是将传统CNN特征提取和Transformer进行结合。这里是以ResNet50作为特征提取器的混合模型。但是这里的ResNet与之前的ResNet有些不同,首先,这里的ResNet50的卷积层采用的是StdConv2d,而不是传统的Conv2d,然后将所有的BatchNorm层替换成GroupNorm层,在原ResNet50网络中,stage1重复堆叠3次,stage2重复堆叠4次,stage3重复堆叠6次,stage4重复堆叠3次,而在这里的ResNet50中,把stage4中的3个Block移至stage3中,stage3共重复堆叠9次。所以这里的ResNet50一共3个stage,stage1重复堆叠3次,stage2重复堆叠4次,stage3重复堆叠9次
通过ResNet50 Backbone进行特征提取后,得到的特征矩阵shape是[14, 14, 1024],接着再输入Patch Embedding层,注意Patch Embedding中卷积层Conv2d的kernel_size和stride都变成了1,只是用来调整channel,最后也会变成[196, 768]的shape。后面的部分和前面ViT中讲的完全一样,就不在赘述。

下图是将纯ViT、纯卷积Resnet和混血模型Hybrid分别在Average-5(5个数据集的综合表现)和ImageNet上做分类任务的ACC进行比较。
![[Pasted image 20230702213255.png]]

结果表明,当模型较小时,hybrid-ViT表现最好,这也是可以理解的,毕竟hybrid-ViT综合了两个算法的优点。但是,当模型较大时,纯ViT模型的效果最好,个人认为,这一定程度上说明了vit模型自己从数据集中学习到的知识比人们根据先验赋予cnn模型的知识更有意义。显然,预训练模型越大,混血模型hybrid难以继续提升,而传统CNN和ViT能够继续上升,所以混血模型的上限相比二者较低。

四、真的是Attention的功劳吗(扩展阅读)

扩展阅读 Vision Transformer - 魔法学院小学弟
由于Transformer的论文中力推self-attention机制,所以以后的很多年中,人们先入为主的认为self-attention在Transformer中起到了重要作用,但是最近的一些工作证明了事实并非如此。《MLP-Mixer: An all-MLP Architecture for Vision》将VIT中Transformer Encoder中的mutil head self-attention操作换成了MLP,模型照样可以获得不错的性能,这个工作证明了self-attention不是Transformer中的必要操作。值得注意的是,当把mutil head self-attention操作换成了MLP,整个VIT模型其实变成了一个纯MLP模型,又发展回深度学习的起点算法了---- 神经网络算法,甚至形成了 CNN, Transformer,MLP三足鼎立的事态。

另外,有些激进的学者直接将Transformer中的self-attention替换成了没有可学习参数的pooling层(《Metaformer is actually what you need for vision》),结果模型照样可以有不错的性能,因此,他们认为,Transfomer成功的关键是整体的模型框架设计,他们把这个框架称之为MetaFormer。因此,到底是什么让Transmer这么有效?这个问题在学术界依然没有同一的答案,有人说self-attention is all you need;有人说 MLP is all you need;有人说patch is all you need,也有人说 MetaFormer is all you need。但是,我觉得,Transfomer效果好的前提是大量训练数据的支持,训练这些数据需要大量的计算资源,所以答案是 Money is all you need!(开玩笑的哈,别当真)。

在CV中,深度学习算法最初从MLP发展到CNN, 又从CNN发展到Transfomer,如今看上去又回到了MLP,但是,需要注意的是现在的MLP模型,如mlp-mixer,跟最初代的MLP是不一样的,是有改进的。历史上,技术的发展总是螺旋上升的,我很期待经过Transfomer和MLP的冲击,CNN是否回厚积薄发,重夺在CV中的统计地位。

五、Swin Transformer

Swin Transformer是包含滑窗操作,具有层级设计的Transformer,是升级了的Hybrid混血模型。

其中滑窗操作包括不重叠的local window,和重叠的cross-window。将注意力计算限制在一个窗口中,一方面能引入CNN卷积操作的局部性,另一方面能节省计算量
![[Pasted image 20230702215202.png]]

Swin Transformer使用了类似卷积神经网络中的层次化构建方法(Hierarchical feature maps),比如特征图尺寸中有对图像下采样4倍的,8倍的以及16倍的,这样的设计有助于网络提取更高级的特征,更适合构建目标检测,实例分割等任务。而在之前的Vision Transformer中是一开始就直接下采样16倍,后面的特征图也是维持这个下采样率不变。

在Swin Transformer中使用了Windows Multi-Head Self-Attention(W-MSA)的概念,比如在下图的4倍下采样和8倍下采样中,将特征图划分成了多个不相交的窗口(Window),但窗口并不是最小的计算单元,最小的计算单元是窗口里的patch图像块,每个窗口里都有m * m个patch,在Swin Transformer的原文中,m的值一般默认为7,此时每个窗口里就有49个patch,自注意力计算都是分别在窗口内完成的,所以序列长度永远都是49(而VIT中是16 * 16 = 196的序列长度)。基于窗口计算自注意力的方式虽然很好的解决了内存和计算量的问题,但是窗口与窗口之间没有了通信,没能达到全局建模的效果,这就限制了模型的能力。所以在论文中作者又提出了 Shifted Windows Multi-Head Self-Attention(SW-MSA)的概念,通过此方法能够让信息在相邻的窗口中进行传递。

基于torch的Swin Transformer代码实现

5.1 整体框架

图解Swin Transformer - 知乎 (zhihu.com)
![[Pasted image 20230702215314.png]]

整个模型采取层次化的设计,一共包含4个Stage,每个stage都会缩小输入特征图的分辨率,像CNN一样逐层扩大感受野

  • 在输入开始的时候,做了一个Patch Embedding,将图片切成一个个图块,并嵌入到Embedding
  • 在每个Stage里,由Patch Merging和多个Block组成。
  • 其中Patch Merging模块主要在每个Stage一开始降低图片分辨率。
  • 而Block具体结构如右图所示,主要是LayerNormMLPWindow AttentionShifted Window Attention组成

其中有几个地方处理方法与ViT不同:

  • ViT在输入会给embedding进行位置编码。而Swin-T这里则是作为一个可选项self.ape),Swin-T是在计算Attention的时候做了一个相对位置编码
  • ViT会单独加上一个可学习参数,作为分类的token。而Swin-T则是直接做平均,输出分类,有点类似CNN最后的全局平均池化层。

主要结构

  • Patch Partition
  • Patch Merging
  • W-MSA (Windows Multi-Head Self-Attention)
  • SW-MSA (Shifted Windows Multi-Head Self-Attention)
  • 相对位置偏置 Relative Position Bias

整体流程

首先将图片输入到Patch Partition模块中进行分块,即每4 * 4相邻的像素为一个Patch,然后在channel方向展平(flatten)。假设输入的是RGB三通道图片,那么每个patch就有4 * 4=16个像素,然后每个像素有R、G、B三个值所以展平后是16 * 3=48,所以通过Patch Partition后图像shape由 [H, W, 3]变成了 [H/4, W/4, 48]。然后在通过Linear Embeding层对每个像素的channel数据做线性变换,由48变成C,即图像shape再由 [H/4, W/4, 48]变成了 [H/4, W/4, C]。其实在源码中Patch Partition和Linear Embedding就是直接通过一个卷积层实现的,和之前Vision Transformer中讲的 Embedding层结构一模一样。

然后就是通过四个Stage构建不同大小的特征图,除了Stage1中先通过一个Linear Embeding层外,剩下三个stage都是先通过一个Patch Merging层进行下采样(后面会细讲)。然后都是重复堆叠Swin Transformer Block注意这里的Block其实有两种结构,如图(b)中所示,这两种结构的不同之处仅在于一个使用了W-MSA结构,一个使用了SW-MSA结构。而且这两个结构是成对使用的,先使用一个W-MSA结构再使用一个SW-MSA结构。所以你会发现堆叠Swin Transformer Block的次数都是偶数。 最后对于分类网络,后面还会接上一个Layer Norm层、全局池化层以及全连接层得到最终输出,这个顶层图中没有画 。

5.1.1 Patch Partition

源码中Patch Partition和Linear Embedding就是直接通过一个卷积层实现的,和之前Vision Transformer中讲的 Embedding层结构一模一样。

在输入进Block前,我们需要将图片切成一个个patch,然后嵌入向量。

具体做法是对原始图片裁成一个个 patch_size * patch_size的窗口大小,然后进行嵌入。

这里可以通过二维卷积层,将stride,kernelsize设置为patch_size大小。设定输出通道来确定嵌入向量的大小。最后将H,W维度展开,并移动到第一维度。

5.1.2 Patch Merging

![[Pasted image 20230702221258.png]]

该模块的作用是在每个Stage开始前做下采样,用于缩小分辨率,调整通道数进而形成层次化的设计,同时也能节省一定运算量。

在CNN中,则是在每个Stage开始前用stride=2的卷积/池化层来降低分辨率。

每个Stage中首先要通过一个Patch Merging层进行下采样(Stage1除外)。如上图所示,操作的目的是将特征信息从空间维度转移到通道维度。假设输入Patch Merging的是一个4x4大小的单通道特征图(feature map),以特征图左上角的四个元素为起点,通过间隔采样得到四个子特征图, 然后将这四个子特征在通道维度上进行concat拼接,然后在通过一个LayerNorm层。最后通过一个全连接层在feature map的深度方向做线性变化,将feature map的深度由C变成C/2。通过这个简单的例子可以看出,通过Patch Merging层后,feature map的高和宽会减半,深度会翻倍

具体实现

每次下采样是两倍,因此在行方向和列方向上,间隔2选取元素

然后拼接在一起作为一整个张量,最后展开。此时通道维度会变成原先的4倍(因为H,W各缩小2倍),此时再通过一个全连接层再调整通道维度为原来的两倍

5.1.3 Window Partition/Reverse

window partition函数是用于对张量划分窗口,指定窗口大小。将原本的张量从 N H W C, 划分成 num_windows*B, window_size, window_size, C,其中 num_windows = HW / (window_sizewindow_size),即窗口的个数。而window reverse函数则是对应的逆过程。这两个函数会在后面的Window Attention用到。

5.1.4 Windows Attention

这是这篇文章的关键。传统的Transformer都是基于全局来计算注意力的,因此计算复杂度十分高。而Swin Transformer则将注意力的计算限制在每个窗口内,进而减少了计算量。

我们先简单看下公式

A t t e n t i o n ( Q , K , V ) = S o f t m a x ( Q K T d k + B ) ⋅ V Attention(Q,K,V)=Softmax(\frac{QK^T}{\sqrt{d_k}}+B)·V Attention(Q,K,V)=Softmax(dk QKT+B)V

主要区别是在原始计算Attention的公式中的Q,K时加入了相对位置编码。后续实验有证明相对位置编码的加入提升了模型性能。相对位置编码在后面会介绍。

5.1.5 W-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,也就是上面的Windows Attention。
![[Pasted image 20230702221805.png]]

采用W-MSA模块的计算节省了95%的计算复杂度,但是缺点也很明显,就是缺失了模块之间的联系

5.1.6 SW-MSA

其实就是模块的偏移。
当采用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 \frac M 2 2M​ 个像素)。

![[Pasted image 20230702223723.png]]

此时,如偏移后的右图所示Layer1+1层,对于第一行第2列的2x4的窗口,它能够使第Layer1层的第一排的两个窗口信息进行交流。再比如,第二行第二列的4x4的窗口,他能够使第Layer1层的四个窗口信息进行交流,其他的同理。那么这就解决了不同窗口之间无法进行信息交流的问题。

![[f68de51f316ef003998683cccbdf5e4.jpg]]

由此可以发现通过将窗口进行偏移后,就到达了窗口与窗口之间的相互通信。虽然已经能达到窗口与窗口之间的通信,但是原来的特征图只有4个窗口,经过移动窗口后,得到了9个窗口,窗口的数量有所增加并且9个窗口的大小也不是完全相同,这就导致计算难度增加。因此,作者又提出而了Efficient batch computation for shifted configuration,一种更加高效的计算方法,计算也十分巧妙。如下图所示:

![[Pasted image 20230702223937.png]]

先将012区域移动到最下方,再将360区域移动到最右方,此时移动完后,4是一个单独的窗口;将5和3合并成一个窗口;7和1合并成一个窗口;8、6、2和0合并成一个窗口。这样又和原来一样是4个4x4的窗口了,所以能够保证计算量是一样的。代码里对其实现是通过如果把不同的区域合并在一起(比如5和3)进行MSA,这信息会乱窜,为了防止这个问题,在实际计算中使用的是masked MSA即带蒙板mask的MSA,这样就能够通过设置蒙板来隔绝不同区域的信息了。

关于mask如何使用,先回顾常规的MSA计算:

A t t e n t i o n ( Q , K , V ) = S o f t m a x ( Q K T d k ) V Attention(Q,K,V)=Softmax\bigg(\frac{QK^T}{\sqrt{d_k}}\bigg)V Attention(Q,K,V)=Softmax(dk QKT)V

可以发现,其在最后输出时要经过Softmax操作,Softmax在输入很小时,其输出几乎为0。以上面的区域5和区域3的合并区域为例,如果某像素是属于区域5的,我们只想让它和区域5内的像素进行匹配。那么我们可以将该像素与区域3中的所有像素做注意力计算后的结果都减去100 ,这样再通过Softmax后,得到对应的权重都几乎就等于0了。所以对于该像素而言,实际上还是只和区域5内的像素进行了MSA。那么对于其他像素也是同理。注意,在计算完后还要把数据给挪回到原来的位置上

5.1.7 Attention Mask

这个设计是Swin Transformer的精华,通过设置合理的mask,让Shifted Window Attention在与Window Attention相同的窗口个数下,达到等价的计算结果。

具体实现

首先我们对Shift Window后的每个窗口都给上index,并且做一个roll操作(window_size=2, shift_size=-1)

![[Pasted image 20230703001140.png]]

我们希望在计算Attention的时候,让具有相同index QK进行计算,而忽略不同index QK计算结果

最后正确的结果如下图所示
![[Pasted image 20230703001841.png]]

而要想在原始四个窗口下得到正确的结果,我们就必须给Attention的结果加入一个mask,将mask加到attention的计算结果,并进行softmax。mask的值设置为-100,softmax后就会忽略掉对应的值。

5.1.8 Relative Position Bias

关于相对位置偏置,论文中描述使用了相对位置偏置后给够带来明显的提升。根据原论文中的实验结果,在ImageNet数据集上如果不使用任何位置偏置,top-1为80.1,但使用了相对位置偏置(rel. pos.)后top-1为83.3,提升还是很明显的。相对位置偏置的添加位置如下公式所示: A t t e n t i o n ( Q , K , V ) = S o f t m a x ( Q K T d k + B ) ⋅ V Attention(Q,K,V)=Softmax\bigg(\frac{QK^T}{\sqrt{d_k}}+B\bigg)·V Attention(Q,K,V)=Softmax(dk QKT+B)V
要理解相对位置偏置,我想先理解什么是相对位置索引和绝对位置索引。

首先我们可以构建出每个像素的绝对位置(左下方的矩阵),对于每个像素的绝对位置是使用行号和列号表示的。比如蓝色的像素对应的是第0行第0列所以绝对位置索引是( 0 , 0 ) ,接下来再看看相对位置索引。以蓝色的像素举例, 用蓝色像素的绝对位置索引与其他位置索引进行相减,就得到其他位置相对蓝色像素的相对位置索引。例如黄色像素的绝对位置索引是( 0 , 1 ) ,则它相对蓝色像素的相对位置索引为( 0 , 0 ) − ( 0 , 1 ) = ( 0 , − 1 ) 。那么同理可以得到其他位置相对蓝色像素的相对位置索引矩阵。同样,也能得到相对黄色,红色以及绿色像素的相对位置索引矩阵。接下来将每个相对位置索引矩阵按行展平,并拼接在一起可以得到下面的4x4矩阵 。

![[Pasted image 20230703002231.png]]

请注意,到此计算得到的是相对位置索引,并不是相对位置偏置参数。因为后面我们会根据相对位置索引去取对应的参数,如下图所示。比如说黄色像素是在蓝色像素的右边,所以相对蓝色像素的相对位置索引为( 0 , − 1 )。绿色像素是在红色像素的右边,所以相对红色像素的相对位置索引为( 0 , − 1 ) 。可以发现这两者的相对位置索引都是( 0 , − 1 ),所以他们使用的相对位置偏置参数都是一样的。

![[Pasted image 20230703002855.png]]

5.1.9 Transformer Block整体架构

![[Pasted image 20230703003130.png]]

两个连续的Block架构如上图所示,需要注意的是一个Stage包含的Block个数必须是偶数,因为需要交替包含一个含有Window Attention的Layer和含有Shifted Window Attention的Layer。

具体实现

  • 先对特征图进行LayerNorm
  • 通过self.shift_size决定是否需要对特征图进行shift
  • 然后将特征图切成一个个窗口
  • 计算Attention,通过self.attn_mask来区分Window Attention还是Shift Window Attention
  • 将各个窗口合并回来
  • 如果之前有做shift操作,此时进行reverse shift,把之前的shift操作恢复
  • 做dropout和残差连接
  • 再通过一层LayerNorm+全连接层,以及dropout和残差连接

5.2 模型详细配置参数

下表是原论文中给出的关于不同Swin Transformer的配置,T(Tiny),S(Small),B(Base),L(Large),其中:

  • win. sz. 7x7表示使用的窗口(Windows)的大小
  • dim表示feature map的channel深度(或者说token的向量长度)
  • head表示多头注意力模块中head的个数

![[Pasted image 20230703003352.png]]

5.3 Swin Transformer 扩展阅读

Swin Transformer - 魔法学院小学弟

实际上,个人认为Swin是一只披着CNN皮的Transformer,可以看做是优化版的CNN,优化的地方主要在于用局部patch的全连接attention替换了CNN的卷积。其在模型设计思想上处处都在模仿CNN,例如:

  • Window的机制是否类似于卷积核的局部相关性?
  • 层级结构的下采样是否类似于CNN的层级结构?
  • Window的Shift操作是否类似于卷积的non-overlapping的步长?

所以,虽然Transformer看似攻占了CV领域的半壁江山,但是我们也不要忽略卷积的重要性。Transformer的核心模块是self-attention,CNN的核心模块是conv,个人认为在计算机视觉领域self-attention不会替代conv,而是和conv融合、取长补短。 举几个具体的例子:

图像跟文本不太一样的一个地方是图像比文本维度更大,直接全部用self-attention,会导致计算量出奇的大,这明显是我们不太愿意看到的,如果借用conv的局部思想也许就可以缓解这个问题,或者干脆在网络前面部分直接用conv。比如ViT(文章里提到的将图片分成多个无overlap的patch,每个patch通过linear projection映射为patch embedding,这个过程其实就是conv)。

Conv有两个假设,局部相关性和平移不变性,在conv横行计算机视觉领域的时候,学术界认为conv之所以这么有效是因为这两个假设和图像的数据分布非常匹配。假如conv的这两个假设实际上真的和图像的数据分布非常匹配,那其实可以将这两个假设和self-attention结合起来,即self-attention不是针对全局的,而是类似conv一样,一个patch一个patch滑,每个patch里做self-attention。回想一下这是否是swin-transformer的思路?

另外,我们面对一个领域内多种方法的时候,总想排个序,看看谁最好,谁最差。但是实际上,这是没有必要的,每个方法有自己的适用范围,有自己优点和缺点。大家要有一个更开放和包容的心态也许更好,在不知道具体数据分布的时候,不要强行排序,也不要接受他人的排序。当数据分布确定的时候,我们再来分析已有的方法有哪些特性跟它是匹配的,然后“集万千宠爱于一身”,岂不美哉。

就像深度学习火起来的时候,很多初学者内心都有一个疑问“既然有了深度学习,我们是不是不需要传统机器学习算法了?”,我在深度学习的学习历程里讨论过这个问题:尺有所长,寸有所短。每个模型都有它适用的范围,深度学习也不例外。比如你的数据天然是线性可分的,那svm将会是最好的选择,如果你选了“高大上”的深度学习,结果反而会适得其反。面对一个任务,分析这个任务的assumption,然后去你的武器库(也就是各种模型)里寻找跟这个assumption匹配的武器,知己知彼,方能百战不殆。不要瞧不起svm这样的“匕首”,也不要太高看深度学习这样的“屠龙刀”。

六、VAN

虽然Transformer最初是为自然语言处理任务而设计的,但最近已经在各种计算机视觉领域掀起了风暴。然而,图像是有空间信息的二维数据,这给计算机视觉中应用Transformer带来了三个挑战:

  1. 将图像视为一维序列忽略了其二维结构。
  2. 对于高分辨率的图像来说,self-attention的计算复杂性太昂贵了。
  3. self-attention只能抓住了空间适应性而忽略了通道适应性。

在工作中,作者提出了一种新的注意力机制,名为 large kernal attention(LKA),来模仿self-attention中的自适应性和长距离的相关性,同时避免其缺点。此外,我们提出了一个基于LKA的神经网络,即 Visual Attention Network(VAN)。虽然非常简单,但VAN在各种任务中的性能表现可以超过类似规模的Transformer(ViTs)和卷积神经网络(CNNs),包括图像分类、物体检测、语义分割、全景分割、姿势估计等。

基于torch的VAN代码实现

6.1 相关工作

6.1.1 卷积算法

在处理图像数据时,学习特征表示(feature representation)很重要, CNN因为使用了局部相关性和平移不变性这两个归纳偏置,极大地提高了神经网络的效率。在加深网络的同时,网络也在追求更加轻量化。 本文的工作与MobileNet有些相似,把一个标准的卷积分解为了两个部分:一个depthwise conv,一个pointwise conv。本文把一个卷积分解成了三个部分:depthwise conv, depthwise and dilated conv 和pointwise conv。但是目的不同,MobileNet拆分卷积的目的是为了减少参数量和计算复杂度;本文拆分卷积的目的是为了获得更大的计算感受野来模仿self-attention计算全局的特性

6.1.2 注意力机制

注意力机制使得很多视觉任务有了性能提升。 视觉的注意力可以被分为四个类别: 通道注意力、空间注意力、时间注意力和分支注意力。每种注意力机制都有不同的效果。例如VIT,Swin-Transformer等属于空间注意力机制。

Transformer中的Self-attention 是一个特别的注意力,可以捕捉到长程的依赖性和适应性。但是,在视觉任务中self-attention有三个缺点:

  • 它把图像变成了1D的序列进行处理,忽略了2D的结构信息
  • 对于高分辨率图片来说,二次计算复杂度太高
  • 它只实现了空间适应性却忽略了通道适应性

对于视觉任务来说,不同的通道经常表示不同的概念,通道适应性在视觉任务中也是很重要的。为了解决这些问题,本文提出了一个新的视觉注意力机制:LKA。 它包含了self-attention的适应性和长程依赖,而且它还吸收了卷积操作中可以同时对空间信息和通道信息做处理的优点。

6.1.3 CV的多层感知机

在CNN出现之前,MLP曾是非常知名的方法。但是由于高昂的计算需求和低下的效率,MLP的能力被限制了很长一段时间。 最近的一些研究成功地把标准的MLP分解为了spatial MLP和channel MLP,显著降低了计算复杂度和参数量,释放了MLP的性能。基于MLP的模型有两个缺点:

  • MLP对输入尺寸很敏感,只能处理固定尺寸的图像。
  • MLP只考虑了全局信息而忽略了局部的信息。

而本文的方法VAN可以充分利用MLP的优点并且避免它的缺点。

6.2 大核注意力机制 LKA

首先,注意力机制的关键在于我们会通过一系列操作得到一个于输入信息尺寸相同的attention map,在将这个attention map与输入信息进行相乘,通过乘的方式做输入信息重要程度的重分配。至于得到attention map的方法则有很多种,self-attention只是这些方法中的一种而已。

有两种众所周知的方法可以建立注意力关系。

  1. 第一种是采用自我注意机制(Self-Attention)来捕捉远程依赖。
  2. 第二种方法是使用大核卷积建立相关性并生成attention map。这种方式仍然存在明显的缺点。大的内核卷积带来了大量的计算开销和参数
  3. 小核卷积由于卷积的特征之一是局部相关性,这就导致没有办法进行远距离的注意力建模,不符合注意力关系全局的特点,所以不考虑。

为了克服上述缺点,利用自注意和大核卷积的优点,提出分解一个大核卷积运算来获取远程关系。

如下图所示,一个大的核卷积可以分为三部分:

  • 一个逐层卷积(depth-wise的卷积)
  • 一个逐层空洞卷积(depth-wise的空洞卷积)
  • 一个逐点卷积(1 × 1卷积)

通过上述分解,可以让模型以小的计算量和小的参数量为代价,捕捉到的远程关系。在获得远程关系之后,就可以估计一个点的重要性并生成attention map。

![[Pasted image 20230703112532.png]]

实际上并不是相等的概念,只是用堆叠来模拟大卷积核
三个卷积的目的分别为:处理空间信息,扩大感受野,处理通道信息

如上图所示,LKA 模块可以写为 : A t t e n t i o n = C o n v 1 × 1 ( D W − D − C o n v ( D W − C o n v ( F ) ) ) O u t p u t = A t t e n t i o n ⊗ F \begin{aligned} &Attention=Conv_{1\times 1}\bigg(DW-D-Conv\big(DW-Conv(F)\big)\bigg)\\ &Output=Attention \otimes F \end{aligned} Attention=Conv1×1(DWDConv(DWConv(F)))Output=AttentionF

其中, F ∈ R C × H × W F\in R^{C\times H\times W} FRC×H×W A t t e n t i o n ∈ R C × H × W Attention \in R^{C\times H\times W} AttentionRC×H×W , ⊗ \otimes 是指元素的乘积。

通过LKA计算得到 attention map 之后,通过 ⊗⊗ 输入信息来实现注意力机制,如下图所示:

![[Pasted image 20230703113331.png]]

值得一提的是,如果把 ⊗ \otimes 换成 ⊙ \odot ,那么就变成了大名鼎鼎的残差结构,如下图所示:

![[Pasted image 20230703113417.png]]

最后,我们与self-attention算法相比,相似的是都计算得到一个 attention map 然后通过与输入信息相乘做注意力的重分配。不同的是,计算得到attention map 的方法不同,VAN采用的是LKA的方式,而不是self-attention。
注意力机制中类似attention map的概念其实是 S o f t m a x ( Q K T d k ) Softmax\bigg(\frac{QK^T}{\sqrt{d_k}}\bigg) Softmax(dk QKT)

![[Pasted image 20230703113446.png]]

对比之下,LKA融合了Conv和self-Attention的优点,如下表所示:

PropertiesConvolutionSelf-AttentionLKA
Local Receptive Field 局部感受野×
Long-rangeDependence长距离依赖×
Spatial Adaptability 空间自适应卷积中空间通道信息同时处理
Channel Adaptability 通道自适应卷积中空间通道信息同时处理×
Computational ComplexityO(n) O ( n 2 ) O(n^2) O(n2)O(n)

6.3 基于LKA的视觉注意力网络VAN

VAN模型的层级结构非常简单,由四个stage序列构成,每个stage都会降低空间分辨率和增加通道数。输出空间分辨率逐渐降低,分别是 H 4 × W 4 、 H 8 × W 8 、 H 16 × W 16 和 H 32 × W 32 \frac H4×\frac W4、\frac H8×\frac W8、\frac H{16}×\frac W {16}和\frac H{32}× \frac W{32} 4H×4W8H×8W16H×16W32H×32W

随着分辨率的降低,输出通道的数量也在增加。

![[Pasted image 20230703115112.png]]

其中,C 表示通道数量;L 表示每阶段的 LKA 模块数量。B0-7 代表模型的缩放,具体通过增加每阶段的 LKA 数量和通道数量来实现。默认的,我们使用5x5 depthwise conv、7x7的空洞率为3的depthwise conv和1x1 conv来近似一个21x21尺寸的大卷积核conv。在这种设置下,VAN可以有效的实现近似全局注意力。

6.4 实验

数据集

在ImageNet-1K图像分类数据集、COCO目标检测数据集和ADE20K语义分割数据集上进行了定量实验。

实验结果

消融研究。进行消融研究,以证明LKA的每个成分都是至关重要的。table 4表明LKA中的所有组件对于提高性能是必不可少的

![[Pasted image 20230703120116.png]]

与现存方法比较

至于在ImageNet数据集上的实验结果,VAN相比同计算复杂度的其他先进模型,例如ResNet,Swin-Tranformer,ConvNeXt等可以到达更好的分类性能,具体结果如下:

![[Pasted image 20230703115252.png]]

七、总结

最后,作者在未来将在以下几个方向完善VAN:

继续改进它的结构。在本文中,只展示了一个简单的结构,还存在很多潜在的改进点,例如:应用大核、引入多尺度结构和使用多分支结构。

大规模的自监督学习和迁移学习。VAN 自然地结合了CNN和ViT的优点。一方面VAN利用了图像的2D结构。另一方面 VAN可以基于输入图片动态的调整输出,它很适合自监督学习和迁移学习。结合了这两点,作者认为VAN可以在这两个领域有更好的性能。

更多的应用场景。由于资源有限,作者只展示了它在视觉任务中的优秀性能。作者期待VAN在各个领域都展示优秀性能并变成一个通用的模型。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安徒生在ACL讲一千零一夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值