时隔三月再次看ViT的认识与收获

嘿,太累了,就休息一会吧。

闲谈

转眼间2021年就剩下一个月了,回顾十一月,没有太多的收获,拖延症及其严重,总是在学习和不想学习之间徘徊。SGD的精髓就是梯度够大,可以一直跑,慢慢总是能收敛。我总不能找到某个方向一直去努力,总是来回波动。“简单,粗暴但效果很好”的东西,我很喜欢。非常符合我喜欢的话“规则简单易懂,粗暴却完美!“关注大的方向,而不局限于细节。

ViT

前言

回顾三个月前初识ViT

Paper:arxiv.org/abs/2010.11… Code:github.com/google-rese…

到现在为止这篇文章引用量为1629

论文题目:An Image is Worth 16x16 Words:Transformers for Image Recognition at Scale

为什么题目要叫16✖️16 word呢? N=224✖️224 W=224/16 H=14 N=14✖️14=196

这就相当于把224✖️224的图片切分成196个16✖️16的patch,此时196个patch就相当于NLP的word组成一个整体。

Transformer做大规模的图像识别。

CNN常说的两种Inductive bias(归纳偏置)

  • Locality(局部性)。即卷积神经网络是以滑动窗口进行滑动卷积的,所以假设图片相邻区域有相邻特征。这个假设非常合理。
  • Translation equivariance(平移等价性)。即无论先做卷积还是先做平移,最后的结果是一样的。

而Transformer 没有先验信息,都是自己学得到。

Vit是在公开数据集ImageNet-21k和Google自家的数据集JFT-300M上做预训练。结果发现大规模的预训练毕归纳偏置好。

论文详解

在大规模数据集上做预训练,然后迁移到中小型数据集使用,效果非常好。

以ViT-B/16为例,将输入图片(224✖️224)按照16✖️16大小的patch进行划分,划分后会得到(2242/162)=142=1961个patch,接着通过线性映射将每个patch映射到一维向量中,以ViT-B/16为例,每个patch数据shape为[16,16,3]通过映射得到一个长度为768的向量。

对于标准的Transformer模块要求输入的是token(向量)序列,即二维矩阵[num_token,token_dim]。对于图像数据而言,其数据格式为[H,W,C]是三维矩阵。明显不是Transformer模块想要的。所以需要先通过一个Embedding层对数据做变换。

在输入Transformer encoder之前需要加入class token以及position embedding。此时[196,768]--> [197,768]。这里的class token参考了BERT网络(已经阅读了,还未更新文章,我是真的太懒了)。

ViT模型框架由三个模型块组成:

  • Linear Projection of Flattened Patches(Embedding层)
  • Transformer encoder
  • MLP Head(最终用于分类的层结构)

MLP Head

注意⚠️,在Transformer Encoder前有个Dropout层,后有一个Layer。 训练ImageNet-21K时是由Linear+TanH激活函数+Linear,但是迁移到ImageNet-1K上或者你自己的数据集上,只有一个Linear。

为什么不能在N个输出上**GAP(Globally Average Pooling)**得到最后的特征,为什么要加 class token去输出呢?

通过实验,得出这两种方法都可以,你可以做GAP得到一个全局特征做分类,也可用class token。作者是为了说明标准的Transformer也一样可以做视觉。

公式(1)是加入class token后的结果;公式(2)是多头自注意力得出的结果;公式(3)是整体的结果;公式(4)就是class token所对应的输出当作整体图像的一个特征,做最后的分类。

实验

  • Layers是Transformer Encoder中重复堆叠Encoder Block的次数;
  • Hidden Size是通过Embedding层后每个token的dim(向量的长度);
  • MLP Size 是Transformer Encoder中MLP Block第一个全连接的节点个数(是Hidden Size的四倍);
  • Heads代表Transformer中Multi-Head Attention的Head数。

更小的Patch size计算更贵,因为序列长度增加了。

在Google JFT数据集或在ImageNet-21K进行预训练,发现结果差别不大。作者从另一个角度,即在TPUv3上的训练天数来进行对比。

随着数据集的大小不断增加,Vit的表现越来越来好。得出:小数据集用CNN较好,当数据集大小到达ImageNet-21k时,用Vit更好。

用vision transformer作小样本学习是非常有前途的方向

左边是在五个数据集上的平均效果,发现模型现在也未到达饱和。右边是在ImageNet数据集上的表现。Hybrid是传统CNN和Transformer混合模型。

头28个主成分。

余弦相似度。这里的patches大小是32✖️32的224/32=7,所以是7✖️7大小。

这里有16个Head,也就是每层对应有16个点,一共有24层。

如果训练次数比较少,混合模型的精确度略高一点;在迭代更多的epoch后,ViT精度会超过ViT混合模型。

注意⚠️,在最后效果一样的地方,学习率不同,所以需要好好调参,做一个优秀的练丹师

不使用位置编码比使用位置编码效果差很多,但是使用相对位置编码和绝对位置编码效果差不多,所以既可用相对位置编码,也可用绝对位置编码。因为图像块小,所以排列组合小块区别不大。

用1D和2D效果区别也不大。在源码中使用的是1D。

这篇文章还进行了大规模自监督训练。

ViT的应用

おすすめ

転載: juejin.im/post/7036973197421445157