本文主要用于个人学习总结,其中难免有理解不足之处,仅供参考,欢迎批评指正。
Attention is All You Need
回顾自注意力机制和多头自注意力机制
Vision Transformer (ViT)

Transformer应用在图像领域的工具。
ViT将输入图片分为多个patch,再将patch投影为固定长度的向量送入Transformer
代码解析
以下按照函数和类分析vit_model.py文件
在阅读pytorch版本的神经网络代码时,主要关注类中的forward函数,forward函数是数据运算执行的位置。

- class VisionTransformer
def forward:
输入图像经过forward_features得到分类输出结果
self.dist应该是和模型蒸馏(模型蒸馏是模型压缩的一种方法,是一个AI研究领域,可以暂时不深入)有关的参数def forward_features:
输入图像首先经过patch_embed,输出特征向量序列,然后将指示图像类别的cls_token按照指定维度concat到特征向量序列中。考虑到patch之间的位置关系,以加和的形式融入位置编码(原文中提到位置编码似乎对于模型效果影响不大,可能是因为patch本身空间比较大,模型已经能够很好联系不同patch间的位置信息)。然后将数据送入block模块,并经过norm操作得到最终的输出。

- class Block
- def forward
输入数据,将原有数据首先通过attention作用,然后再通过mlp得到分类结果。在block中代码实现上引入了DropPath(原论文中应该没有,DropPath可以理解为通过mask对网络分支进行选取的操作,和dropout,dropconnect类似,是为了方便网络训练引入的trick,具体内容我暂时也不是很深入)。这边x+droppath(*)用到了残差结构(Residual Block),该结构主要是提高深层网络训练效率和效果。
- def forward

- class Attention
- def forward
输入向量首先通过线性层维数扩充为原来3倍,然后reshape成注意力中的Q、K、V
经过多头注意力机制得到输出,输出向量通过线性层和dropout操作得到最终输出
- def forward

- class Mlp
- def forward
本质就是全连接层、激活函数和dropout的堆叠,没有特别的地方
- def forward
- class DropPath
- def forward

- class PatchEmbed
- def forward
将输入的patch投影到embed维度大小上(怎么理解embed,个人觉得可以理解为一个隐式特征),对于每个patch映射为embed_dim维度的向量,此时得到的是一个特征图。然后将二维特征图摊平为一维向量,即将[c,h,w]维度的特征图转化为[hw,c]维度,最后经过layer normalization(层归一化后面再介绍,这种操作主要是为了方便网络训练)完成patch embedding。
- def forward
-
以下的函数对应不同的ViT设置,设置包括数据集规模、patch划分的大小,不再赘述。
function vit_base_patch16_224
function vit_base_patch16_224_in21k
function vit_base_patch32_224
function vit_base_patch32_224_in21k
function vit_large_patch16_224
function vit_large_patch16_224_in21k
function vit_huge_patch32_224_in21k