用Transformer完全替代CNN-ViT

date
Nov 20, 2021
Last edited time
May 5, 2022 09:13 AM
status
Published
slug
用Transformer完全替代CNN-ViT
tags
DL
CV
summary
转载
type
Post
Field
Plat

1. Story

近年来,Transformer 已经成了 NLP 领域的标准配置,但是 CV 领域还是 CNN(如 ResNet, DenseNet 等)占据了绝大多数的 SOTA 结果。
最近 CV 界也有很多文章将 transformer 迁移到 CV 领域,这些文章总的来说可以分为两个大类:
  1. 将 self-attention 机制与常见的 CNN 架构结合;
  1. 用 self-attention 机制完全替代 CNN。
本文采用的也是第 2 种思路。虽然已经有很多工作用 self-attention 完全替代 CNN,且在理论上效率比较高,但是它们用了特殊的 attention 机制,无法从硬件层面加速,所以目前 CV 领域的 SOTA 结果还是被 CNN 架构所占据。
文章不同于以往工作的地方,就是尽可能地将 NLP 领域的 transformer 不作修改地搬到 CV 领域来。但是 NLP 处理的语言数据是序列化的,而 CV 中处理的图像数据是三维的(长、宽和 channels)。
所以我们需要一个方式将图像这种三维数据转化为序列化的数据。文章中,图像被切割成一个个 patch,这些 patch 按照一定的顺序排列,就成了序列化的数据。(具体将在下面讲述)
在实验中,作者发现,在中等规模的数据集上(例如 ImageNet),transformer 模型的表现不如 ResNets;而当数据集的规模扩大,transformer 模型的效果接近或者超过了目前的一些 SOTA 结果。作者认为是大规模的训练可以鼓励 transformer 学到 CNN 结构所拥有的 translation equivariance (解释看这里) 和 locality.

2. Model

模型的结构其实比较简单,可以分成以下几个部分来理解:
notion image

a. 将图像转化为序列化数据

作者采用了了一个比较简单的方式。如下图所示。首先将图像分割成一个个 patch,然后将每个 patch reshape 成一个向量,得到所谓的 flattened patch。
具体地,如果图片是 维的,用 大小的 patch 去分割图片可以得到 个 patch,那么每个 patch 的 shape 就是 ,转化为向量后就是 维的向量,将 个 patch reshape 后的向量 concat 在一起就得到了一个 的二维矩阵,相当于 NLP 中输入 transformer 的词向量。
notion image
从上面的过程可以看出,当 patch 的大小变化时(即 变化时),每个 patch reshape 后得到的 维向量的长度也会变化。为了避免模型结构受到 patch size 的影响,作者对上述过程得到的 flattened patches 向量做了 Linear Projection(如下图所示),将不同长度的 flattened patch 向量转化为固定长度的向量(记做 维向量)。
notion image
综上,原本 维的图片被转化为了 维的二维矩阵。

b. Position embedding

notion image
由于 transformer 模型本身是没有位置信息的,和 NLP 中一样,我们需要用 position embedding 将位置信息加到模型中去。
如上图所示 1,编号有 0-9 的紫色框表示各个位置的 position embedding,而紫色框旁边的粉色框则是经过 linear projection 之后的 flattened patch 向量。文中采用将 position embedding(即图中紫色框)和 patch embedding(即图中粉色框)相加的方式结合 position 信息。
对训练好的pos_embedding进行可视化, 如下所示
notion image

c. Learnable embedding

notion image
如果大家仔细看上图,就会发现带星号的粉色框(即 0 号紫色框右边的那个)不是通过某个 patch 产生的。这个是一个 learnable embedding(记作 ),其作用类似于 BERT 中的 [class] token。在 BERT 中,[class] token 经过 encoder 后对应的结果作为整个句子的表示;类似地,这里 经过 encoder 后对应的结果也作为整个图的表示。
至于为什么 BERT 或者这篇文章的 ViT 要多加一个 token 呢?因为如果人为地指定一个 embedding(例如本文中某个 patch 经过 Linear Projection 得到的 embedding)经过 encoder 得到的结果作为整体的表示,则不可避免地会使得整体表示偏向于这个指定 embedding 的信息(例如图像的表示偏重于反映某个 patch 的信息)。而这个新增的 token 没有语义信息(即在句子中与任何的词无关,在图像中与任何的 patch 无关),所以不会造成上述问题,能够比较公允地反映全图的信息。

d. Transformer encoder

notion image
Transformer Encoder 结构和 NLP 中 transformer 结构基本上相同,所以这里只给出其结构图,和公式化的计算过程,也是顺便用公式表达了之前所说的几个部分内容。
Transformer Encoder 的结构如下图所示:
notion image
对于 Encoder 的第 层,记其输入为 ,输出为 ,则计算过程为:
其中 MSA 为 Multi-Head Self-Attention(即 Transformer Encoder 结构图中的绿色框),MLP 为 Multi-Layer Perceptron(即 Transformer Encoder 结构图中的蓝色框),LN 为 Layer Norm(即 Transformer Encoder 结构图中的黄色框)。
Encoder 第一层的输入 是通过下面的公式得到的:
其中 即未 Linear Projection 后的 patch embedding(都是 维),右乘 维的矩阵 表示 Linear Projection,得到的 都是 维向量;这 维向量和同样是 维向量的 concat 就得到了 维矩阵。加上 维 position embedding 拼成的 维矩阵,即得到了 encoder 的原始输入
 

3. 混合结构

文中还提出了一个比较有趣的解决方案,将 transformer 和 CNN 结合,即将 ResNet 的中间层的 feature map 作为 transformer 的输入。
和之前所说的将图片分成 patch 然后 reshape 成 sequence 不同的是,在这种方案中,作者直接将 ResNet 某一层的 feature map reshape 成 sequence,再通过 Linear Projection 变为 Transformer 输入的维度,然后直接输入进 Transformer 中。

4. Fine-tuning 过程中高分辨率图像的处理

在 Fine-tuning 到下游任务时,当图像的分辨率增大时(即图像的长和宽增大时),如果保持 patch 大小不变,得到的 patch 个数将增加(记分辨率增大后新的 patch 个数为 )。但是由于在 pretrain 时,position embedding 的个数和 pretrain 时分割得到的 patch 个数(即上文中的 )相同。则多出来的 个 positioin embedding 在 pretrain 中是未定义或者无意义的。
为了解决这个问题,文章中提出用 2D 插值的方法,基于原图中的位置信息,将 pretrain 中的 个 position embedding 插值成 个。这样在得到 个 position embedding 的同时也保证了 position embedding 的语义信息。

5. 实验

实验部分由于涉及到的细节较多就不具体介绍了,大家如果感兴趣可以参看原文。(不得不说 Google 的实验能力和钞能力不是一般人能比的…)
主要的实验结论在 story 中就已经介绍过了,这里复制粘贴一下:在中等规模的数据集上(例如 ImageNet),transformer 模型的表现不如 ResNets;而当数据集的规模扩大,transformer 模型的效果接近或者超过了目前的一些 SOTA 结果。
比较有趣的是,作者还做了很多其他的分析来解释 transfomer 的合理性。大家如果感兴趣也可以参看原文,这里放几张文章中的图。
notion image
notion image

参考

  1. https://openreview.net/forum?id=YicbFdNTTy

© Lazurite 2021 - 2024