Vision Transformer、MAE、Swin-Transformer
一、Vision Transformer论文精读
1.1 引言
1.1.1 前言
作者介绍的另一篇论文:《Intriguing Properties of Vision Transformer》(Vision Transformer的一些有趣特性)如下图所示:
- 图a表示的是遮挡,在这么严重的遮挡情况下,不管是卷积神经网络,人眼也很难观察出图中所示的是一只鸟
- 图b表示数据分布上有所偏移,这里对图片做了一次纹理去除的操作,所以图片看起来比较魔幻
- 图c表示在鸟头的位置加了一个对抗性的patch
- 图d表示将图片打散了之后做排列组合
上述例子中,卷积神经网络很难判断到底是一个什么物体,但是对于所有的这些例子Vision Transformer都能够处理的很好。
1.1.2 摘要
在VIT之前,self-attention
在CV领域的应用很有限,要么和卷积一起使用,要么就是把CNN里面的某些模块替换成self-attention,但是整体架构不变。
VIT的出现,打破了AlexNet出现以来CNN网络在CV领域的统治地位。VIT表明,在图片分类任务中,只使用纯的Vision Transformer
结构也可以取的很好的效果(最佳模型在ImageNet1K
上能够达到88.55%的准确率)开启CV新时代。而且 VIT将CV直接当做NLP来做,还打破了CV和NLP的模型壁垒,推进了多模态领域的发展。
下图
Ours-JFT
表示在在Google自家的JFT数据集上进行了预训练,Ours-I21K
表示在ImageNet 21K上预训练,再在ImageNet 1K上测试。实验分数也可以在paperwithcode
的Dataset排行榜上看到。
在这篇文章中,作者主要拿
ResNet
、ViT
(纯Transformer模型)以及Hybrid
(卷积和Transformer混合模型)三个模型进行比较,所以本博文除了讲ViT模型外还会简单聊聊Hybrid模型。
1.1.3 引言
基于self-attention的模型架构,特别是Transformer,在NLP领域几乎成了必选架构。现在的主流方式就是:在大型语料库上训练一个大模型,然后迁移到小的数据集上进行微调。多亏了Transformer的高效性和可扩展性,现在已经可以训练超过1000亿参数的大模型,随着模型和数据集的增长,还没有看到性能饱和的现象。 (英伟达和微软联合推出的大型语言生成模型Megatron-Turing,有5300亿参数,还能在各种任务上大幅度提升性能,而没有达到性能饱和)
Transformer是对输入序列做self-attention,其复杂度是 ,现在支持的最大序列长度一般就是几百几千。如果直接把图片每个像素值拉平当做输入序列,那么序列就太长了。所以在CV领域CNN一直占主导地位。
受NLP启发,很多工作尝试将CNN和self-attention结合起来。那怎么降低输入序列把它用到CV领域呢?
- Non-local Neural Networks(CVRP,2018):将原始图片中间层输出的特征图作为输入序列,来传入Transformer(比如ResNet50在最后一个Stage的特征图size=14×14)。
- 《Stand-Alone Self-Attention in Vision Models》(NeurIPS,2019):使用孤立注意力
Stand-Alone Axial-Attention
来处理。具体的说,不是输入整张图,而是在一个local window(局部的小窗口)中计算attention。窗口的大小可以控制,复杂度也就大大降低。(类似卷积的操作) - 《Axial-DeepLab: Stand-Alone Axial-Attention for Panoptic Segmentation》(ECCV,2020a):将图片的2D的矩阵想办法拆成2个1D的向量。等于是先在高度的维度上做一次self-attention,然后再在宽度的维度上再去做一次self-attention,大幅度降低了计算的复杂度。
- 《On the Relationship between Self-Attention and Convolutional Layers》( ICLR, 2020.):在相关工作中,作者介绍了,和本文最相似的工作是这一篇文章。其作者从输入图片中抽取2×2的图片patch,然后一样的做self-attention(只在CIFAR-10数据集上做了实验,其数据集大小为32×32,所以patch size=2×2就行)
- image GPT:在相关工作中,作者也说到image GPT和本文很相近。但是image GPT是一个生成模型,虽然用了Transformer,但最终结果差很多(ImageNet上的最高的分类准确率也只能到72)。不过受此启发,后面出现了MAE,用一个自监督模式训练的生成式的模型,做出了比之前判别式的模型更好的效果(分类和检测)。
所以,自注意力早已经在计算机视觉里有所应用,而且已经有完全用自注意力去取代卷积操作的工作了。
这些模型虽然理论上是非常高效的,但事实上因为这个自注意力操作都是一些比较特殊的自注意力操作(除了上面举例的最后一篇),要很复杂的工程去加速算子,所以就导致很难训练出一个大模型。因此在大规模的图像识别上,传统的残差网络还是效果最好的。
本文是被transformer在NLP领域的可扩展性所启发,本文想要做的就是直接应用一个标准的transformer作用于图片,尽量做少的修改。好处是可以直接使用NLP中成熟的Transformer架构,不需要再魔改模型,而且Transformer这么多年有很多高效的实现。具体的处理方式见下一节。
上面举例的例4模型,从技术上讲就是
Vision Transformer
。但是作者认为二者的区别,是本文证明了,使用一个标准的Transformer endoder
(类似BERT,不需要任何特殊改动)在大规模的数据集上做预训练的话,就能取得比现在最好的卷积神经网络差不多或者 还好的结果。(这是本文的主要论证工作,在1.4.2和1.4.3章节都有体现 )另外就是二者可处理图片的分辨率不同(32×32对比224×224)。
引言的最后部分放出了结论:
- 在中型大小的数据集上(比如说ImageNet)上训练的时候,如果不加比较强的约束,Vit的模型其实跟同等大小的残差网络相比要弱一点。
作者对此的解释是:transformer跟CNN相比,缺少了一些CNN所带有的归纳偏置(inductive bias
,是指一种先验知识或者说是一种提前做好的假设)。CNN的归纳偏置一般来说有两种:locality
:CNN是以滑动窗口的形式一点一点地在图片上进行卷积的,所以假设图片上相邻的区域会有相邻的特征,靠得越近的东西相关性越强;translation equivariance
(平移等变性或平移同变性):写成公式就是,不论是先做 g 这个函数,还是先做 f 这个函数,最后的结果是不变的;其中f代表卷积操作,g 代表平移操作。(因为在卷积神经网络中,卷积核就相当于是一个模板,不论图片中同样的物体移动到哪里,只要是同样的输入进来,然后遇到同样的卷积核,那么输出永远是一样的)- 一旦神经网络有了这两个归纳偏置之后,他就拥有了很多的先验信息,所以只需要相对较少的数据就可以学习一个相对比较好的模型。但是对于transformer来说,它没有这些先验信息,所以它对视觉的感知全部需要从这些数据中自己学习。
- 为了验证这个假设, 作者在更大的数据集(ImageNet 22k数据集&JFT 300M数据集)上做了预训练,然后发现大规模的预训练效果要比归纳偏置好。 如下图所示:
- 上图中VTAB也是作者团队所提出来的一个数据集,融合了19个数据集,主要是用来检测模型的稳健性,从侧面也反映出了VisionTransformer的稳健性也是相当不错的。
1.2 相关工作
简单介绍了一下Transformer在NLP领域应用最广的两大分支BERT和GPT,都是基于自监督的训练方式(MLM任务和Next word prediction)。
直接将图片的像素作为序列输入Transformer是不可行的,所以作者介绍了一下之前的相关处理方式(类似上面引言提到的几个模型)。
第三段介绍了,有一些工作研究了用比ImageNet更大的数据集去做预训练,效果会更好,比如说ImageNet-21k和JFT300M。最终作者也是在这两个数据集上预训练模型。
1.3 ViT
1.3.1 整体结构
下图是原论文中给出的关于Vision Transformer(ViT)的模型框架。简单而言,模型由三个模块组成:
Embedding
层(线性投射层Linear Projection of Flattened Patches)Transformer Encoder
(图右侧有给出更加详细的结构)MLP Head
(最终用于分类的层结构)
如上图所示:
embedding
层(图片输入)- 一张图片先分割成n个
patchs
,然后这些patchs一个个输入线性投射层得到Pacth embedding
。比如ViT-L/16
表示每个patchs
大小是16×16。 - 在所有tokens前面加一个新的
class token
作为这些patchs全局输出,相当于transformer中的CLS(这里的加是concat拼接)。 - 和transformer一样,引入位置信息。VIT的做法是在每个token前面加上位置向量,即
position embedding
(这里的加是直接向量相加,不是concat)。
self-attention本身没有考虑输入的位置信息,无法对序列建模。而图片切成的patches也是有顺序的,打乱之后就不是原来的图片了。
- 一张图片先分割成n个
Pacth embedding
+position embedding
+class token
一起输入Transformer Encoder
层得到其输出。- class token的输出当做整个图片的特征,经过
MLP Head
得到分类结果。(VIT只做分类任务) - 整个模型是使用有监督的训练(相对于NLP中,transformer类模型很多都是无监督训练)
整体上看,VIT的模型结构还是很简洁的,难点就是如何将图片转为token输入网络。
1.3.2 Embedding层结构详解
对于标准的Transformer模块,要求输入的是token(向量)序列,即二维矩阵[num_token, token_dim]。对于图像数据而言,其数据为[H, W, C]格式的三维矩阵,明显不是Transformer想要的。所以需要先通过一个Embedding层来对数据做个变换。
- 如下图所示,首先将一张图片按给定大小分成一堆Patches。以
ViT-B/16
为例(后面都是以此模型举例),将输入图片(224x224)按照16x16大小的Patch尺寸进行划分,划分后会得到 ( 224 / 16 ) 2 = 196 (224/16)^2=196 (224/16)2=196个Patches。 - 接着通过线性映射将每个Patch映射到一维向量中。具体的,每个Patche数据shape为[16, 16, 3],通过映射得到一个长度为768的向量(token)。
[16, 16, 3] -> [768]
在代码实现中,直接通过一个卷积层来实现。卷积核大小为16x16,步距为16,卷积核个数为768。通过卷积
[224, 224, 3] -> [14, 14, 768]
,然后把H以及W两个维度展平即可[14, 14, 768] -> [196, 768]
,此时正好变成了一个二维矩阵,正是Transformer想要的。如果模型更大的话,
Pacth embedding
可以映射到更大的维度,也就是论文中提到的参数D
。