ViT
AN IMAGE IS WORTH 16X16 WORDS:
TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE
https://arxiv.org/pdf/2010.11929.pdf
这篇工作Vision Transformer基于NLP领域中大放异彩的Transformer模型来处理视觉领域的任务。作者将二维的图像数据用一个简单的方式转换为和Transformer中处理的句子序列差不多的形式, 然后使用 Transformer编码器来提取特征。
Multi-head self-Attention 多头注意力机制
Transformer的论文叫Attention is all you need, 现在在深度学习领域中提到Attention可能大家都会想到Transformer的self-Attention自注意力,其实注意力机制刚开始是应用于循环神经网络中的,self-Attention可以看成是一个更通用的版本。Attention本来是在Encoder-Decoder框架中关乎中间的隐藏状态的这么一个函数。 而self-Attention无所谓隐藏状态,只关注输入序列中向量之间的依赖关系。Transformer给出了一个非常简洁的公式 。
看到softmax就知道是在求概率,V代表的是数值,QK代表一个查字典的操作。但是这样还是很抽象,要理解的话得把矩阵拆成向量才行。这里推荐一篇可视化Transformer的博客。https://jalammar.github.io/illustrated-transformer/
我的理解就是把原向量进行三次编码,然后在计算attention结果的时候,一个编码只和自己有关,代表该token的特征,另外两个用来和序列中其他向量的编码进行匹配,得到当前向量与其他向量之间的关联程度。
卷积在视觉中占主流的原因很重要的原因是局部感受野,另外卷积的形式一坨一坨的很契合对图片数据的处理。但是,卷积的感受野是受限的,要多层抽象才能得到一个比较大的感受野。而自注意力我觉得可以理解为在输入的全局中有选择的进行权重。这个过程进行多次,就是多头自注意力机制。
把图片当作单词处理
最终的编码就长成这个样子:
对应:
图片转化为序列数据
E
将图片拆分为多个patch,每个压扁的通过线性变换E, 得到一个固定长度的特征向量,参考NLP中的习惯称为token。这个token的长度D文中使用了768,1024,1280对应三个尺寸的模型ViT-Base,Large以及Huge。
class token
另外每个序列的开头还会加上一个class token,最终用来分类的是class token 对应的特征向量。这个token的参数是可学习的,会和序列中所有其他patch所生成的token一样,正常进行查询匹配的注意力操作,我的理解是它起到了一个类似总结的作用。代码中可以看到,最终通过MLP的要么是只取class token的结果,或者也可以使用对所有token在每个位置取平均值的方法。但是论文好像没有解释取平均值会怎么样,有了解的同学欢迎补充。
#https://github.com/lucidrains/vit-pytorch/blob/4f3dbd003f004569a916f964caaaf7b9a0a28017/vit_pytorch/vit.py
def forward(self, img):
x = self.to_patch_embedding(img)
b, n, _ = x.shape
cls_tokens = repeat(self.cls_token, '() n d -> b n d', b = b)
x = torch.cat((cls_tokens, x), dim=1)
x += self.pos_embedding[:, :(n + 1)]
x = self.dropout(x)
x = self.transformer(x)
x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0] # (只使用 class token)
x = self.to_latent(x)
return self.mlp_head(x)
- 位置编码
虽然注意力可以捕捉到token和token之间的依赖关系,但是token的位置信息却无处可寻。也就是说,无论这些patch如何排序,得到的结果都是一样的。NLP领域中有非常多的解决方案,ViT使用的是可学习的位置编码,和class token 与 patch的线性变换相加得到最终编码。也许也可以用拼接,不过原Transformer中没有提到,另外Transformer中使用的是固定的编码。 总之,就是无论哪个序列,让序列中同一位置的token附带上一模一样的信息就可以了。ViT附录D3中有不同位置编码方式的对比实验结果,如果没有考虑位置信息,那么结果很差,而使用不同位置编码的结果其实差距不大。
不同编码的对比试验,编码方法可以去参看原文
既然已经通过上面的处理把图片的输入转化为Tranformer处理单词序列的形式了,那么接下来直接通过多头注意力机制多次处理,最终得到的结果是和图片中每个patch都相关的特征。就相当于替代卷积层完成了特征提取得到 z_l。
实验
不用卷积运算,训练需要的计算资源要少很多。
ViT 如果用大量数据集进行预训练,那么效果会很好。
ViT 模型更大对比同量级state-of-the-art表现更好。
swinTransformer
https://arxiv.org/pdf/2103.14030.pdf
position bias in self-attention head
不同于ViT中在输入序列中加上一个绝对的位置编码,swinTransformer使用的是相对位置偏置,加在attention内部的查询操作里。论文做了实验,如果同时使用两种方法,表现会反而下降。