本文为稀土技术社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!
作者简介:秃头小苏,致力于用最浅显的语言描绘问题
往期回忆:CV攻城狮入门VIT(vision transformer)之旅——近年超火的Transformer你再不了解就晚了!
近期方针:写好专栏的每一篇文章
支撑小苏:点赞、收藏⭐、留言
CV攻城狮入门VIT(vision transformer)之旅——VIT原理详解篇
写在前面
在上一篇,我现已详细为咱们介绍了NLP邻域中的Transformer,足足写了10000+字,酝酿了许多天才着笔,也写了好久,自以为写的还算是浅显全面。如若你对Transformer还没什么了解,主张你点击☞☞☞了解详情。
其实,作为CV程序猿的咱们,学习NLP邻域的Transformer更像是被逼之举,究竟现在根据Transformer的算法在CV邻域可谓是大杀特杀。那么今日我就为咱们带来将Transformer引入到视觉物体分类中的一篇文章,标题为 AN IMAGE IS WORTH 16X16 WORDS:TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE
,这篇文章发表于2021年,下载链接如下:download
那么这篇文章将为咱们详细解说VIT的原理,下一篇将给咱们带来VIT的代码实战。
准备好了嘛,滴滴滴,让咱们坐上入门VIT旅途的观光车,一览VIT的风采。
VIT模型全体结构✨✨✨
咱们先来看看VIT的全体结构,如下图所示:
从全体上来看,VIT模型的结构是很少的,事实上的确如此。假如你明白了我上一篇解说的Transformer的话,那这篇文章真的就特别简略了,能够说没什么难点。这篇文章作者妄图不改动Transformer的结构来完成物体分类使命,咱们能够来看一下VIT中的Transformer Encoder 结构,根本是和Transformer中是相同的。留意我这儿说的是根本喔,你比照两篇论文中Encoder的结构你会发现,Norm这个结构的方位是有所变化的,至于为什么这样做,作者也没有提及,个人感觉这个改动对结构影响不会很大,感兴趣的能够改动这个结构测验测验作用。别的一点是在VIT中没有运用Decoder结构,这儿咱们需求留意一下。
全体结构咱们有个印象就好,必定还有一些不清楚的地方。不必忧虑,后面我会详细的为咱们讲述一些结构上的细节!!!
VIT细节梳理✨✨✨
首要,我觉得咱们有必要想想NLP中的Transformer和CV中的VIT这两个结构输入有什么区别?从变量的类型来看,两者都是一个tensor张量;而从变量的维度来看,NLP中的输入往往是二维的tensor,而CV中往往是一个三维的RGB图画。【都忽略了Batch维度】 这种维度的不统一会导致咱们不能直接将图片数据喂入到Transformer结构中去,而是需求进行一定的维度转换,行将三维的tensor转换成二维的tensor,这个进程被称为patch_embedding。
那论文中是如何将三维的tensor转化为二维的tensor的呢?如下图所示:
能够看到,上图将一张RGB图片分成了9个相同巨细的小块。假定原图尺度为HWCHWC, 每个块的巨细为mnCmnC ,关于上图咱们总共分成了9块,应有Hm=3\frac{H}{m} = 3 、Wn=3\frac{W}{n} = 3。不知道咱们发现没有,其实就进行这样的一个操作咱们就现已把三维的tensor转化为二维的tensor了,即由原图的 HWC→9(mnC)HWC \to 9(mnC)。【注:此刻每个小块的图片尺度都是mnCmnC,咱们将其展平其实便是一个维度】
上文为咱们介绍了三维tensor到二维tensor的转换,理论上很简略,代码其实就更简略了,就只需求调用一个函数即可,详细什么函数不知道的咱们能够参阅这篇文章。
我这儿没有讲这个函数是由于我参阅的代码并不是这样做维度变换的,而是通过卷积的方法进行。听上去是不是很美妙呢,下面就跟我一同来看看吧。为便利咱们了解,这儿咱们拿详细的数字来举例。设原图的尺度为224*224*3,每个块(patch)的尺度为16∗16∗316*16*3,则咱们总共会得到22416∗22416=14∗14=196\frac {224}{16}*\frac {224}{16} =14*14=196个patchs, 所以经分块后,一个224*224*3的三维tensor会变成一个196*(16*16*3),即196*768的二维张量。那么由224*224*3变换到196*768的这个进程是能够由卷积完成的,即咱们对原图进行卷积,卷积核巨细为16*16*3 ,步长为16,padding=0,卷积核个数为768,卷积后,咱们会得到特征图,其尺度为14*14*768,接着将前两个维度展平,就得到了维度为196*798的tensor。其大致进程如下:
我以为这步运用卷积真的很巧妙,咱们得到的196*798的二维向量,其实每一行即1*798都包含了原图中16*16*3巨细的patch,这便是卷积的提取特征的功能嘛。【我这样介绍不知道咱们会不会有这样的思路——我先用一些CNN模型来对图片提取特征,只要使CNN最后的输出维度为196*768,最后再送入Transformer模型中。其实这就将CNN和Transformer很好的结合在一同了,这种办法是可行的,咱们能够自己测验测验喔】
现在咱们现已得到了196*768维的tensor,咱们假定其为x。接下来咱们会运用一个维度为1*768维的Class token来和x进行Concat操作,输出成果为197*768维的tensor。这儿必定有人有疑问了,为什么这儿会加一个Class token,在上篇讲述的Transformer中可没有这个操作。–小傻瓜–由于这篇文章咱们要用来对物体进行分类啊!!!说不定你现在有点置疑自己了,由于是分类使命所以要加上Class token?这两个还有因果关系不成?一个个问号从你脑海中冒出,百思不得其解。其实啊,这可没什么啥因果关系,仅仅咱们在分类使命中加上Class token可能会作用更好。
与其介绍为什么加上Class token会作用更好,不如咱们先来看看不加Class token会发生什么作用。假如咱们不加Class token,直接将196*768维的tensor输入Encode中,咱们的输出同样是196*768,即196个1*768维的向量,这时候咱们应该拿哪个向量来当作最后的输出向量从而进行物体分类使命呢?这咱们是很难确定的。所以咱们爽性在输入Encode前就加上一个1*768维的向量(这个1维向量放在196*768维向量前面),这样在输出时向量的维度就会是197*768,然后咱们只需求通过切片的方法获得第一个1*768维向量并将其送入分类头进行分类即可。在代码中这个Class token是一个可学习的向量,初始为全0的1*768维向量。
Class token和x拼接后,输出尺度变成了197*768,此刻咱们会加上一个方位编码向量position Embedding,其维度为197*768。关于这部分我在上一篇介绍Transformer中现已很详细的介绍过了,这儿不再过多论述原理。但咱们能够看一下假如咱们不运用方位编码,那么下面两幅图输出的成果将是一致的,这显然是有违咱们直觉的。
图片来源于yutubu Shusen Wang老师
需求留意的是,在上一篇咱们采用的是正弦方位编码的方法,而这儿咱们将方位编码向量设置为一个可学习的向量,初始为全0的197*768维向量。至于这两种编码方法哪个好我也没有做过试验,感兴趣的能够查查资料,做做试验,个人感觉运用可学习的方位编码作用应该不会差!
接下来咱们将通过方位编码的输入喂入encoder网络中,并重复L次encoder结构,encoder的结构如下:
这部分我也不再细讲了,不明白的能够看我上一篇关于Transformer中Encoder的解说。通过L个encoder结构后,输入维度没有发生变换,仍为197*768维。【到这儿咱们可能就发现了VIT模型许多结构都和Transformer很类似,所以咱们搞懂了Transformer再来看这篇文章真的就很简略了】
通过encoder结构后,输出的维度维197*768,此刻咱们会通过切片的方法提取出Class token的信息,其维度为1*768。接着会拿这个1*768维的Class token通过MLP Head层。MLP Head层的结构如下:
其中Pre-Logits这部分是可选的,其便是一个全连接层加上一个tanh激活函数,详细咱们会鄙人一篇代码实战部分进行解说。Linear就用于分类了,输出节点个数为咱们使命的类别数。
这样,咱们VIT的整个流程就都学完了,是不是发现还蛮简略的呢。最后,我找到了一张整个进程的动态图,咱们能够参阅:【图片来源于此篇博客】
VIT模型参数
在论文中给出了三个模型(Base Large Huge)的参数,如下:
Model | Patch size | Layers | Hidden Size | MLP size | Heads | Params |
---|---|---|---|---|---|---|
VIT-Base | 16*16 | 12 | 768 | 3072 | 12 | 86M |
VIT-Large | 16*16 | 24 | 1024 | 4096 | 16 | 307M |
VIT-Huge | 14*14 | 32 | 1280 | 5120 | 16 | 632M |
这儿对上表中某些参数做个简要的介绍。Patch size为将一张图片分成小块每小块的尺度,在咱们的代码中其实便是卷积核的尺度。Layers表示encoder结构重复的次数。Hidden Size为通过输入encoder前每个token的维度,在咱们上文举的例子中为768,鄙人篇代码中其实便是卷积核的个数。MLP size是在encoder结构中的MLP Block中第一个全连接层的节点个数,这个咱们再代码部分细讲。Heads表示Multi-Head Attention的Heads数目。params表示模型所用参数巨细。
试验定论
这部分论文中还是放了好几张图的,这儿我就介绍一张比较要害的,如下图所示:
这幅图展现了什么呢——作者分别在ImageNet、ImageNet-21k和JFT-300M这三个数据集上做试验。【注:这三个数据集数据量越来越大】
咱们发现,当在小数据集ImageNet上做预练习时,VIT的模型架构作用普遍低于BiT【注:BiT是用ResNet建立的结构】;当在中等数据集ImageNet-21k上做预练习时,VIT的模型架构根本位于BiT最好和最差的之间;而当在大数据集JFT-300M上做预练习时,VIT的模型架构最好的作用现已超过了BiT。
这个试验告知咱们什么呢?——VIT模型需求在大数据集上进行预练习,在大数据集上预练习的作用会比卷积神经网络的上限高!
小结
VIT的原理就为咱们介绍到这儿啦,是不是发现还是很简略的呢。假如你还有一些细节没用了解,不必忧虑,鄙人一篇我将为咱们介绍VIT的源码部分,信任到时咱们能有更深的感悟。少年,一同加油吧!!!
参阅连接
Vision Transformer详解
Vision Transformer 超详细解读 (原理剖析+代码解读) (二)
Vision Transformer(vit)网络详解
Vision Transformer (ViT) 用于图片分类
如若文章对你有所协助,那就