DL

ViT, 视觉新范式

Vision Transformer

Posted by Wzghzw on August 30, 2021

Transformer in CV

从NLP来的Transformer

由于Transformer适合于构建大模型,在NLP任务中表现出来了非常强的特征表示能力,ViT的工作是将Transformer尽可能保持原结构的情况下,应用在视觉领域,以取代ResNet结构,并用于大模型(JFT-300M)中。

Vision Transformer结构

Patch Embedding

对于二维图像,先通过Patch Embedding转换成一维向量。对于大小为$\mathbb{R}^{H\times W\times C}$的图片,先确定Patch的大小$P\times P$,切分后得到$(H\times W)/P^2$个Patch,每个Patch特征维度为$P^2 \times C$,对每个Patch使用一个线性层处理,对特征维度进行压缩,得到$D$维的Patch Embedding.生成的向量也被称为是(Image) token.

所谓的Embedding来源于特征降维,认为特征处于一个高维空间中时,实际上是一个低维流形在高维空间中的Embedding.Patch Embedding的意思则是将特征从高维降到低维,起到特征降维的作用.实际上在ViT的原文实现中,作者设置恰好为$D = P^2 \times C$.

Position Embedding

位置嵌入的目的是给token提供位置编码信息,对于输入encoder的token,他们之间互换顺序是不会影响结果的,也就是说本身token之间没有任何顺序信息.使用位置嵌入,在token中添加位置信息,便于后续学习特征.使用不同的策略提供的位置嵌入效果相近,相比于没有位置嵌入都有比较好的效果.为了便于处理,可以把token看作二维图像切割后一维排列序列来编码.

在这里,位置嵌入的选取是采用了学习的策略.在送入Encoder之前,将位置嵌入与Patch嵌入相加.

Class Token

感觉这个设计思路是来源于Bert,在Bert中,Patch Embedding的输出是对应的单词级表示,所以需要一个额外的头来汇总Encoder的信息,获得句子级的分类结果.

将CLS token放在0的位置上,可以避免Patch分块带来的切分后数量不同,导致cls token的position embedding 变化,从而影响分类的情况.根据原作者的说法,可以选择使用例如池化或者其他类似方式来聚合所有的token特征,这样可以免于使用cls token.这部分的cls token和对应的位置嵌入都是使用随机初始化训练得到的.

Transformer

使用的与Attention is all you need中相同的Transformer Encoder结构,也就是MSA多头自注意力+MLP. \(Attention(Q,K,V) = Softmax(\frac{QK^T}{\sqrt{d_k}})V\) Q, K, V是通过一个可学习的矩阵得到三个向量,$Q, K, V\in \mathbb{R}^{N\times d}$ 后接一个MLP(两层),组成了Encoder结构.具体如图中右侧Encoder所示. 代码见https://github.com/lucidrains/vit-pytorch

最后接一个Layer Norm之后就可以对输出进行分类了.

ViT中的参数

Img Lost

  1. Layers 这个表示的是Transformer中堆叠的block数量,也就是第一幅图中,右侧灰色框内的Transformer Encoder部分

  2. D 每个Patch经过Linear Projection之后得到的那个压缩特征的维度也就是D

  3. MLP size 根据网上的说法设置为D的4倍,应该表示的为MLP宽度.

  4. Heads Attention中的注意力头数量.