vit:An Image is Worth 16x16 Words:Transformers for Image Recognition at Scale

一直以来都是使用卷积来处理图像数据,即使后面提出空洞卷积、特征金字塔来、注意力机制缓解其感受野受限,但是还是使用卷积计算去提取图像特征,受 NLP 中 transformer 的影响,VIT 将图像拆分为块 (patch),并将图像数据学习转为图像块序列的学习问题,这里图像块 (patches) 的处理方式同 NLP 的标记 (tokens)

什么是 vit (vision in transformer)?

  • 一直以来都是使用卷积来处理图像数据,即使后面提出空洞卷积、特征金字塔来、注意力机制缓解其感受野受限,但是还是使用卷积计算去提取图像特征
  • 受 NLP 中 transformer 的影响,VIT 将图像拆分为块 (patch),并将图像数据学习转为图像块序列的学习问题,这里图像块 (patches) 的处理方式同 NLP 的标记 (tokens)
  • 注意:Transformers 缺乏 CNN 固有的一些归纳偏置 (inductive biases) —— 如平移等效性和局部性 (translation equivariance and locality),因此在数据量不足时,训练不能很好地泛化

Vit 如何将 2D 图像转为 transformer 输入?

  • tansformer 是 3D 输入的,即 (B, S, L),分别表示 batch size、sequence size、sequence length,计算机视觉的输入一般是 (B, C, H, W),从 (B, C, H, W)-> (B, S, L)的过程中,可以认为 B 不变,C 表示 L,关键是如何将 (H,W)转为 S?
  • 对于 2D 的图像,将其拆分成多个 PxP 的互不重叠区域,则共有 S=HW/(P×P)S=HW/(P\times P) 个区域,则 (B,C,H,W)(B, C, H, W) 可被拆分为 (B,C×P×P,HW/(P×P))(B, C\times P\times P, HW/(P\times P)) ,即 (B,C,S)(B, C', S) ,这就可以被 tansformer 接收
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class EmbedLayer(nn.Module):
        def __init__(self, args):
            super(EmbedLayer, self).__init__()
            self.args = args
            # 卷积获得图片的所有tokens,每个大小是patch_size
            self.conv1 = nn.Conv2d(args.n_channels, args.embed_dim, kernel_size=args.patch_size, stride=args.patch_size)
            self.cls_token = nn.Parameter(torch.zeros(1, 1, args.embed_dim), requires_grad=True)  # Cls Token
            self.pos_embedding = nn.Parameter(torch.zeros(1, (args.img_size // args.patch_size) ** 2 + 1, args.embed_dim), requires_grad=True)  # Positional Embedding,这里是可学习的pos_embedding
        def forward(self, x):
            x = self.conv1(x)  # B C IH IW -> B E IH/P IW/P
            x = x.reshape([x.shape[0], self.args.embed_dim, -1])  # B E IH/P IW/P -> B E S
            x = x.transpose(1, 2)  # B E S -> B S E
            x = torch.cat((torch.repeat_interleave(self.cls_token, x.shape[0], 0), x), dim=1) # 加上cls_token
            x = x + self.pos_embedding # 加上pos_embedding
            return x

Vit 的结构?

  • 输入:输入图片 (B, C, H, W),经过 Patch 对图像分块,得到 (B,HW/(P×P),C×P×P)(B, HW/(P\times P), C\times P\times P),将其类比为 (B, N, L),然后增加 Position Embeddings 和 cls_token ,最终 Encoder 输入变为:(B, N+1, L)
  • Encoder:对输入 (B, N+1, L),使用 transformer 学习 N+1个 patch 的全局注意力,输出是(B, N+1, L)
  • Decoder:从 (B, N+1, L)取出 cls_token,得到 (B, 1, L),然后使用 Linear 编码该特征,输出 (B, L’),L’为类别数量,最后使用 softmax 进行分类

Vit 为什么要加 Cls_token 节点?

  • 经过 VIT 的编码器后,得到 N+1 个 Patch 的隐向量,即 (B,N+1,L),论文使用 2 种方法去获得最后的分类结果
  • 方法 1:从训练开始就没有增加cls_token,然后对N个L取平均,得到一张图的向量表示,即(B,N,L)->(GAP)->(B1i=1N(Li)/N)=(B,L^)(B,1,\sum_{i=1}^N(L_i)/N )=(B,\hat L),然后对(B,L^)(B,\hat L)进行分类
  • 方法2:增加cls_token,然后只取cls_token进行分类
  • 方法 1 是所有隐向量的线性组合,表达能力弱,方法 2 是网络学习的一部分,更有效,成本更低

Vit 为什么要使用 Position Embedding?

  • 不同于 CNN,Transformer 需要位置嵌入来编码 patch tokens 的位置信息,这主要是由于 自注意力 的 扰动不变性 (Permutation-invariant),即打乱 Sequence 中 tokens 的顺序并不会改变结果,若不给模型提供图像块的位置信息,那么模型就需要通过图像块的语义来学习拼图,这就额外增加了学习成本。表现为如果不加位置编码,可能出现全部序列都预测出来,但是位置不正确
  • 论文比较了4种嵌入编码的方式,效果差不多,因为分类任务对位置信息不敏感,如果是其他的transformer处理的任务,如果不加,效果很差

Vit 上不同网络位置的 transoformer block 在注意力上有什么差异?

  • Mean Attention Distance主要体现自注意力机制的影响范围,比如认定注意力>0.5的两个位置形成注意力,然后计算满足这个阈值的位置平均距离,这就类比于 CNN 的感受野。结果表明:前面层的 “感受野” 虽然差异很大,但总体相比后面层 “感受野” 较小;而模型后半部分 “感受野” 基本覆盖全局,和 CNN 比较类似,说明 ViT 也最后学习到了类似的范式

Vit 与 CNN 的区别?

  • 归纳偏置 (Inductive bias):Vision Transformer 的图像特定归纳偏置比 CNN 少得多。在 CNN 中,局部性、二维邻域结构和平移等效性存在于整个模型的每一层中。而在 ViT 中,只有 MLP 层是局部和平移等变的,因为自注意力层都是全局的。二维邻域结构的使用非常谨慎:在模型开始时通过将图像切分成块,并在微调时调整不同分辨率图像的位置嵌入 (如下所述)。此外,初始化时的位置嵌入不携带有关图像块的 2D 位置的信息,图像块之间的所有空间关系都必须从头开始学习
  • 混合架构 (Hybrid Architecture):作为原始图像块的替代方案,输入序列可由 CNN 的特征图构成。在这种混合模型中,图像块嵌入投影被用在 经 CNN 特征提取的块 而非 原始输入图像块。作为一种特殊情况,块的空间尺寸可以为 ,这意味着输入序列是通过 简单地将特征图的空间维度展平并投影到 Transformer 维度 获得的。然后,如上所述添加了分类输入嵌入和位置嵌入,再将三者组成的整体馈入 Transformer 编码器。简单来说,就是先用 CNN 提取图像特征,然后由 CNN 提取的特征图构成图像块嵌入。由于 CNN 已经将图像降采样了

参考:

  1. https://blog.csdn.net/qq_39478403/article/details/118704747