第十二章 原理篇:vision transformer

文章详细介绍了Transformer模型从NLP领域扩展到计算机视觉,特别是ViT(VisionTransformer)的工作原理,包括图像切片(patch)、patch嵌入、位置编码等关键步骤,并探讨了Transformer与CNN的区别。此外,文章还提到了einops库在处理图像数据时的作用,以及代码实现过程中的关键操作。最后,文章简要介绍了TNT(TransformerinTransformer)模型,强调了更细粒度的patch划分对提升模型性能的意义。

参考教程:
https://arxiv.org/pdf/2010.11929.pdf
https://zhuanlan.zhihu.com/p/340149804 【大佬总结的非常好,他的好多篇文章都很值得学习】

为什么会使用transformer

transformer在NLP领域广泛使用,它解决了RNN的并行化问题,并且能适应不同的语境。

既然如此,为什么不能在图像领域也使用这样的方法呢?
我们知道计算机视觉中普遍使用的是卷积神经网络,通过卷积核在feature上滑动窗口处理,一层一层地传递信息,并得到图像的特征。

在卷积神经网络中,有一个很重要的概念——感受野。感受野就是你站在当前层的一个像素点,能看到的原始图像的像素范围有多大。对于一张图像,你使用3*3的核进行卷积处理,在得到的featuremap中,你的感受野大小就是3*3。此时再用一个3*3的核进行卷积处理,再新的featuremap中,你的感受野就是5*5。

受卷积核大小的限制,你需要堆叠很多的层才能得到比较大的感受野。为什么不直接使用大卷积核呢?一方面来说大卷积核计算也更复杂,但是效果并不如小卷积核好。另一方面3*3卷积作为最广泛使用的卷积,针对它的底层优化也比别的大小的做的要好。

做CNN的时候是只考虑感受野红框里面的资讯,而不是图片的全局信息。所以CNN可以看作是一种简化版本的self-attention。
或者可以反过来说,self-attention是一种复杂化的CNN,在做CNN的时候是只考虑感受野红框里面的资讯,而感受野的范围和大小是由人决定的。但是self-attention由attention找到相关的pixel,就好像是感受野的范围和大小是自动被学出来的
引用自:https://zhuanlan.zhihu.com/p/340149804
ps:这个大佬文章写的真的很不错,学到了很多。

你在做卷积的时候,人为设定的卷积核决定了你每步操作时元素所能观测到的范围,感受野中的一个点也只会和这个点附近的别的点存在联系,这个大小和范围取决于你的模型架构。
self-attention中,每个元素都能观测到其余的元素,并自我学习哪个元素对自己的影响更大,所以说这个范围和大小是自动学习的。
但是这种自学习也让模型更加flexible,对训练数据的要求也就越高。所以重新训练一个比较好的transformer模型也是比较困难的,好在我们可以站在前人的肩膀上,使用别人的预训练模型。

VIT详解

论文名称:《an image is worth 16x16 words: Transformers for Image Recognition at scale》
在这里插入图片描述
论文标题通俗易懂,再配合图片使用效果更好。一眼过去我们就能直接看到作者首先把一张图片分成了多个小块,然后处理后作为transformer encoder的输入。
也就是说它把图片分块处理后,当作一段文本中的连续单词,使用transformer的encoder来寻找一个单词与别的单词的联系,也就是寻找image patch之间的关系。

method

获得patch

论文中写到,一个标准的transformer会接受一个token embeddings的序列作为输入。现在输入变成了2D的图像,那么就把图像分割成一个p*p大小的patch,并且每个patch通过flatten展开,就变成了个长度为 p 2 p^2 p2的vector,vector的个数是 N = H W / p 2 N=HW/p^2 N=HW/p2。那么这样我们的输入也就变成了一个序列。N是序列的长度, p 2 p^2 p2是序列的维度。

通常情况下,对于一个输入大小为224*224的图像,假如要分成16*16大小的patch,那你就会得到14*14个长度为256的vector。

对于一个输入大小为224*224*3的图像,分成16*16大小的patch后,每一块都为16*16*3,那么你会得到14*14个长度为768的vector。

patch embedding

我们现在得到的是一个序列,序列的长度为N,每个元素都是一个大小为 p 2 p^2 p2*c的embedding。这和我们的目标之间还有一点点差距。假如说我们期望的给transformer encoder的输入大小为N*D,那么我们已经有N了,接下来就需要把 p 2 p^2 p2*c变成D。
z 0 = [ x c l a s s ; x p 1 E ; x p 2 E ; . . . ; x p N E ] + E p o s , E ∈ R ( P 2 ∗ C ) × D , E p o s ∈ R ( N + 1 ) × D z_0 = [x_{class}; x^1_pE; x^2_pE; ...; x^N_pE] + E_{pos}, E\in R^{(P^2* C)\times D}, E_{pos}\in R^{(N+1)\times D} z0=[xclass;xp1E;xp2E;...;xpN

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值