Vision Transformer(ViT)

它是目前图片分类最好的模型,超越了最好的CNN。
在这里插入图片描述
图片分类的意思是自动判断这张图片是什么。如果给定这个图片,神经网络应当判断这张图片是狗。

在这里插入图片描述
把图片输入神经网络中,神经网络输出分类结果p,p的每个元素对应一个类别。如果数据集中一共有8个类别,那么p是八维的向量。(神经网络有40%的信心认定图片为狗)

CNN中ResNet在图片分类结果很好。

Vision Transformer是最近提出的,2021年正式发表。在所有公开数据集中,ViT的表现都超越了最好的ResNet,前提是要在足够大的数据集上做预训练,在越大的数据集上做预训练,ViT的优势越明显。

Transformer原本是用于自然语言处理的模型,在2017年提出,ViT是Transformer在计算机视觉上的成功。ViT模型其实就是Transformer Encoder网络。

步骤:

1.将图片划分成Patches

在这里插入图片描述
图片划分可以重叠也可不重叠。
划分的时候使用滑动窗口每次移动若干个像素,滑动窗口每次移动的步长叫stride。

2.向量化(Vectorization)

向量化的意思是将张量拉伸成向量。(几块变成几个向量,如一个 d 1 × d 2 × d 3 d_1 \times d_2\times d_3 d1×d2×d3的张量,向量化后对应的向量尺寸为 d 1 d 2 d 3 × 1 d_1d_2d_3\times1 d1d2d3×1
在这里插入图片描述

3.用全连接层对向量做线性变换

(此处全连接层不使用激活函数,只是单纯的线性变换)
在这里插入图片描述
每个向量的所使用的全连接层共享参数,都使用相同的参数矩阵W和b。

4.用Positional Encoding对图片每一块的位置做编码

图片被划分成了n块,那么位置就是1~n之间的整数,每个位置被编码成一个向量,向量大小与z向量相同。
在这里插入图片描述

5.把位置编码对应的向量加到z向量上

这样一来,一个z向量即是patch内容的表征,也包含patch的位置信息。如果不用positional encoding会掉3个点的准确率。

为什么要用positional encoding?
在这里插入图片描述
右边打乱顺序的图片和左边的不一样,但是无论怎样交换z向量,都不会影响transformer的最终输出,也就是说z向量没有位置信息,那么左右两张图在transformer眼里是一样的。所以应该给patch标注上位置信息,并对位置做编码,把编码得到的向量加到z向量上。这样一来,我们交换patch后,transformer的结果会不同。

6.用CLS符号表示分类,对这个符号做embed,得到向量 z 0 z_0 z0

z 0 z_0 z0与其他的z向量大小相同。
用CLS符号的原因是transformer这个位置上的输出要被用作分类。

为什么要引入这个class embedding?
因为transformer输入为一系列的patch embedding,输出也是同样长的序列patch feature。但是最后要总结为一个类别的判断,简单方法可以用avg pool,把所有的patch feature都考虑算出image feature,但是作者没有用这种方式,而是引入一个类似flag的class token,其输出特征加上一个线性分类器就可以实现分类。其中训练的时候,class token的embedding被随机初始化并与pos embedding相加,因此从图中可以看到输入transformer的时候【0】处补上一个新的embedding,最终输入长度N+1
在这里插入图片描述

该class token的主要特点:(1)不基于图像内容;(2)位置编码固定。

这样做的好处:

  • 该token随机初始化,并随着网络的训练不断更新,它能够编码整个数据集的统计特性。

  • 该token对所有其他token上的信息做汇聚(全局特征聚合),并且由于它本身不基于图像内容,因此可以避免对sequence中某个特定token的偏向性

  • 对该token使用固定的位置编码能够避免输出收到位置编码的干扰。ViT中作者将class embedding视为sequence的头部而非尾部,即位置为0.这样即使sequence的长度n发生变化,class embedding的位置编码依然是固定的。

7.把从 z 0 z_0 z0 z n z_n zn这n+1个向量输入Multi-Head Self-Attention(多头自注意力层)
在这里插入图片描述

这一层的输出也是n+1个向量。
在上面加一个全连接层,输出还是n+1个向量。
在这里插入图片描述
可以继续加多头自注意力层和全连接层(想加多少都可以)
在这里插入图片描述
把搭的自注意力层和全连接层记作Encoder这样的一个Encoder
在这里插入图片描述
它的输出是 c 0 、 c 1 c_0、c_1 c0c1 c n c_n cn一共n+1个向量
在这里插入图片描述
向量 c 1 c_1 c1 c n c_n cn没有用,直接忽略掉,有用的是 c 0 c_0 c0,可以把它看作是从图片中提取的特征向量,用作分类任务。
在这里插入图片描述
c 0 c_0 c0输入Softmax Classifier(分类器),分类器输出向量p,向量p表示分类的结果。
在这里插入图片描述
p的大小是类别的数量,如果有1000个类别,那么p就是一千维的向量。下面图中是向量p中每个元素的值,它们就是分类的结果:
在这里插入图片描述
在训练的时候,我们比较向量p和真实标签之间的交叉熵,用交叉熵作为损失函数,求损失函数关于神经网络参数的梯度,用梯度去更新神经网络参数。

我们已经搭建好了神经网络,需要用数据去训练神经网络参数,具体是这样做训练的:
首先,随机初始化神经网络参数
在这里插入图片描述
在数据集A上做训练
在这里插入图片描述
数据集的规模一定要大。这一步叫做预训练,我们得到了预训练的模型参数。
在这里插入图片描述
然后在B的数据集上继续训练,这个数据集通常比较小,这一步叫做Fine-tuned(微调)。
在这里插入图片描述
到此为止,训练就彻底结束了。

数据集B是任务的数据集,最后再数据集B的测试集上评价模型的表现,得到测试准确率:
在这里插入图片描述

Vision Transformer中研究了三个数据集
在这里插入图片描述
JFT是谷歌私有数据集,不对外公开。

模型的表现:

  • 在数据集A上做预训练,在数据集B上有微调,数据集B是目标数据集,在它上面计算测试准确率。

  • 当预训练数据集不够大的时候,Transformer的表现并不好

  • 用大ImageNet做预训练的数据集,用比它小的数据集做目标数据集,在它们上面做fine-tuned和计算测试准确率,结果Transformer跟ResNet准确率差不多。尽管大ImageNet有1300万张图片,对Transformer来说,这个数据集还是不够大。

  • 用最大的JFT数据集做预训练数据集,用比它小的数据集做目标数据集,结果Tranformer准确率要比ResNet准确率高1%左右。

实验表明,用越大的数据集做预训练,Transformer的优势就会越大。如果预训练的图片不到1亿张图片,Transformer可能会不如ResNet,当预训练的图片超过一亿张的时候,Transformer的表现超过了ResNet,从结果上来看,即便是有3亿张图片的JFT数据集还是不够大,如果能继续增大预训练数据集,Transformer的优势还会进一步增大。
反观ResNet,预训练数据集一亿或者三亿的时候区别不大。继续增大预训练数据集,ResNet几乎不会有提升。结论就是Transformer需要大数据做预训练,随着数据量增长,Transformer的准确率会一直增长。

原文:https://www.bilibili.com/video/BV1Ty4y137P5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值