视频:ViT论文逐段精读【论文精读】_哔哩哔哩_bilibili
代码:论文源码
使用pytorch搭建Vision Transformer(vit)模型
vision_transforme · WZMIAOMIAO/deep-learning-for-image-processing · GitHub
VisionTransformer — Torchvision API
李沐论文精读系列二:Vision Transformer神洛华的博客
目录
这篇文章挑战了自从2012年AlexNet提出以来卷积神经网络在计算机视觉里绝对统治的地位。结论是如果在足够多的数据上做预训练,也可以不需要卷积神经网路,直接使用标准的transformer也能够把视觉问题解决的很好。它打破了CV和NLP在模型上的壁垒,开启了CV的一个新时代,推进了多模态领域的发展。
paperswithcode可以查询现在某个领域或者说某个数据集表现最好的一些方法有哪些。图像分类在ImageNet数据集上排名靠前的全是基于Vision Transformer The latest in Machine Learning | Papers With Code
ImageNet Benchmark (Image Classification) | Papers With Code
对于目标检测任务在COCO数据集上,排名靠前都都是基于Swin Transformer。Swin Transformer是ICCV 21的最佳论文,可以把它想象成一个多尺度的Vit(Vision Transformer)
COCO test-dev Benchmark (Object Detection) | Papers With Code
在其他领域(语义分割、实例分割、视频、医疗、遥感),基本上可以说Vision Transformer将整个视觉领域中所有的任务都刷了个遍。
1 引言
1.1 Vision Transformer的一些有趣特性
作者的另一篇论文:
《Intriguing Properties of Vision Transformer》
如下图所示:
图a表示的是遮挡,在这么严重的遮挡情况下,不管是卷积神经网络,人眼也很难观察出图中所示的是一只鸟
图b表示数据分布上有所偏移,这里对图片做了一次纹理去除的操作,所以图片看起来比较魔幻
图c表示在鸟头的位置加了一个对抗性的patch
图d表示将图片打散了之后做排列组合
上述例子中,卷积神经网络很难判断到底是一个什么物体,但是对于所有的这些例子Vision Transformer都能够处理的很好。
1.2 标题
一张图片等价于很多16*16大小的单词。为什么是16*16的单词?把图片分割成很多方格patch的形式,每一个方格的大小都是16*16,那么这张图片就相当于是很多16*16的patch组成的整体
1.3 摘要
在VIT之前,self-attention在CV领域的应用很有限,要么和卷积一起使用,要么就是把CNN里面的某些模块替换成self-attention,但是整体架构不变。
这篇文章证明了,在图片分类任务中,只使用纯的Vision Transformer结构直接作用于一系列图像块,也可以取的很好的效果(最佳模型在ImageNet1K上能够达到88.55%的准确率)。尤其是当在大规模的数据上面做预训练然后迁移到中小型数据集(ImageNet、CIFAR-100、VATB)上面使用的时候,Vision Transformer能够获得跟最好的卷积神经网络相媲美的结果。Transformer的另外一个好处:它只需要更少的训练资源,而且表现还特别好。
作者这里指的少的训练资源是指2500天TPUv3的天数。这里的少只是跟更耗卡的模型去做对比。
1.4 引言
Transformer在NLP领域的应用
基于self-attention的模型架构,特别是Transformer,在NLP领域几乎成了必选架构。现在比较主流的方式,就是先去一个大规模的数据集上去做预训练,然后再在一些特定领域的小数据集上面做微调。多亏了Transformer的高效性和可扩展性,现在已经可以训练超过1000亿参数的大模型(GPT3)。随着模型和数据集的增长,还没有看到性能饱和的现象。
- 很多时候不是一味地扩大数据集或者说扩大模型就能够获得更好的效果的,尤其是当扩大模型的时候很容易碰到过拟合的问题,但是对于transformer来说目前还没有观测到这个瓶颈
- 微软和英伟达联合推出了一个超级大的语言生成模型Megatron-Turing,它已经有5300亿参数了,还能在各个任务上继续大幅度提升性能,没有任何性能饱和的现象
将transformer运用到视觉领域的难处
Transformer在做自注意力的时候是两两互相的,这个计算复杂度是跟序列的长度呈平方倍的。目前一般在自然语言处理中,硬件能支持的序列长度一般也就是几百或者是上千(比如说BERT的序列长度也就是512)。
首先要解决的是如何把一个2D的图片变成一个1D的序列(或者说变成一个集合)。最直观的方式就是把每个像素点当成元素,将图片拉直放进transformer里,看起来比较简单,但是实现起来复杂度较高。
一般来说在视觉中训练分类任务的时候图片的输入大小大概是224*224,如果将图片中的每一个像素点都直接当成元素来看待的话,序列长度就是224*224=50176个像素点,这个大小就相当于是BERT序列长度的100倍。这还仅仅是分类任务,对于检测和分割,现在很多模型的输入都已经变成600*600或者800*800或者更大,计算复杂度更高,所以在视觉领域,卷积神经网络还是占主导地位的,比如AlexNet或者是ResNet。
将自注意力用到机器视觉的相关工作
受NLP启发,很多工作研究如何将自注意力用到机器视觉中。一些工作是说把卷积神经网络和自注意力混到一起用;另外一些工作就是整个将卷积神经网络换掉,全部用自注意力。这些方法其实都是在干一个事情:因为序列长度太长,所以导致没有办法将transformer用到视觉中,所以就想办法降低序列长度
Non-local Neural Networks(CVRP,2018):将网络中间层输出的特征图作为transformer输入序列,降低序列的长度。比如ResNet50在最后一个Stage的特征图size=14×14,把它拉平,序列元素就只有196了,这就在一个可以接受的范围内了。
《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):
- 孤立自注意力:不使用整张图,就用一个local window(局部的小窗口),通过控制这个窗口的大小,来让计算复杂度在可接受的范围之内。这就类似于卷积操作(卷积也是在一个局部的窗口中操作的)
- 轴自注意力:之所以视觉计算的复杂度高是因为序列长度N=H*W,是一个2D的矩阵,将图片的这个2D的矩阵想办法拆成2个1D的向量,所以先在高度的维度上做一次self-attention(自注意力),然后再在宽度的维度上再去做一次自注意力,相当于把一个在2D矩阵上进行的自注意力操作变成了两个1D的顺序的操作,这样大幅度降低了计算的复杂度
这些模型虽然理论上是非常高效的,但事实上这个自注意力操作都是一些比较特殊的自注意力操作,无法在现在的硬件上进行加速,所以就导致很难训练出一个大模型。因此在大规模的图像识别上,传统的残差网络还是效果最好的。
所以,自注意力早已经在计算机视觉里有所应用,而且已经有完全用自注意力去取代卷积操作的工作了。本文是被transformer在NLP领域的可扩展性所启发,直接应用一个标准的transformer作用于图片,尽量做少的修改。
vision transformer如何解决序列长度的问题
To do so, we split an image into patches and provide the sequence of linear embeddings of these patches as an input to a Transformer. Image patches are treated the same way as tokens (words) in an NLP application. We train the model on image classification in supervised fashion.
- vision transformer将一张图片打成了很多的patch,每一个patch是16*16
- 假如图片的大小是224*224,则sequence lenth(序列长度)就是N=224*224=50176,如果换成patch,一个patch相当于一个元素的话,有效的长宽就变成了224/16=14,所以最后的序列长度就变成了N=14*14=196,对于普通的transformer来说是可以接受的
- 将每一个patch当作一个元素,通过一个全连接层就会得到一个linear embedding,这些就会当作输入传给transformer。这时候一张图片就变成了一个一个的图片块了,可以将这些图片块当成是NLP中的单词,一个句子中有多少单词就相当于是一张图片中有多少个patch,这就是题目中所提到的一张图片等价于很多16*16的单词
有监督的训练
本文训练vision transformer使用的是有监督的训练。为什么要突出有监督?因为对于NLP来说,transformer基本上都是用无监督的方式训练的,要么是用language modeling,要么是用mask language modeling,都是用的无监督的训练方式。但是对于视觉来说,大部分的基线(baseline)网络还都是用的有监督的训练方式去训练的
前人最相关的工作
本文把视觉当成自然语言处理的任务去做的,尤其是中间的模型就是使用的transformer encoder,跟BERT完全一样。这么简单的想法,之前其实也有人想到过去做,跟本文的工作最像的是一篇ICLR 2020的paper
- 这篇论文是从输入图片中抽取2*2的图片patch
- 为什么是2*2?因为这篇论文的作者只在CIFAR-10数据集上做了实验,而CIFAR-10这个数据集上的图片都是32*32的,所以只需要抽取2*2的patch就足够了,16*16的patch太大了
- 在抽取好patch之后,就在上面做self-attention
从技术上而言这就是Vision Transformer,但是本文的作者认为二者的区别在于,本文的工作证明了如果在大规模的数据集上做预训练的话,那么就能让一个标准的Transformer,不用在视觉上做任何的更改或者特殊的改动,取得比现在最好的卷积神经网络差不多或者还好的结果。
This model is very similar to ViT, but our work goes further to demonstrate that large scale pre-training makes vanilla transformers competitive with (or even better than) state-of-the-art CNNs.
这篇文章的主要目的就是说,Transformer在Vision领域能够扩展的有多好,就是在超级大数据集和超级大模型两方的加持下,transformer也能在视觉中起到很好的效果
ViT和CNN网络使用效果的比较
在中型大小的数据集上(比如说ImageNet)上训练的时候,如果不加比较强的约束,ViT的模型其实跟同等大小的残差网络相比要弱一点。
作者对此的解释是:transformer跟CNN相比,缺少了一些CNN所带有的归纳偏置(inductive bias,是指一种先验知识或者说是一种提前做好的假设)。
CNN的归纳偏置一般来说有两种:
- locality:CNN是以滑动窗口的形式一点一点地在图片上进行卷积的,所以假设图片上相邻的区域会有相邻的特征,靠得越近的东西相关性越强;
- translation equivariance(平移等变性):写成公式就是f(g(x))=g(f(x)),不论是先做 g 这个函数,还是先做 f 这个函数,最后的结果是不变的;其中f代表卷积操作,g代表平移操作。因为在卷积神经网络中,卷积核就相当于是一个模板,不论图片中同样的物体移动到哪里,只要是同样的输入进来,然后遇到同样的卷积核,那么输出永远是一样的
一旦神经网络有了这两个归纳偏置之后,他就拥有了很多的先验信息,所以只需要相对较少的数据就可以学习一个相对比较好的模型。但是对于transformer来说,它没有这些先验信息,所以它对视觉的感知全部需要从这些数据中自己学习。
为了验证这个假设, 作者在更大的数据集(ImageNet 22k数据集, 14M个样本&JFT 300M数据集, 300M个样本)上做了预训练,然后发现在有足够的数据做预训练的情况下,Vit能够获得跟现在最好的残差神经网络相近或者说更好的结果
Our Vision Transformer (ViT) attains excellent results when pre-trained at sufficient scale and transferred to tasks with fewer datapoints. When pre-trained on the public ImageNet-21k dataset or the in-house JFT-300M dataset, ViT approache