论文解析:《A ConvNet for the 2020s》

495 阅读8分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

A ConvNet for the 2020s

 这篇文章主要是对Transformer架构横扫各个视觉任务,击败原有ConvNet主导的研究现状的探究。在Transforer进入到CV领域早起,虽然也有VIT这种能够在图像分类任务上和ConvNer分庭抗礼的架构,但在迁移到其他下游任务作为Backbone时仍然遇到了许多困难。这一情况在Swin Transformer的横空出世后得到改变,Swin Transformer与VIT的不同之处在于它是一种结构化的Transformer,重新引入了一些ConvNet的特质,属于“杂交”的架构。因此作者产生了去探寻ConVNet架构极限的方法,通过分析Swin Transformer成功的原因,将它的优秀特质装配到纯ConVNet架构的ResNet上,一步步的设计出了优于Swin Transformer的纯ConVNet模型--ConvNeXt。

引言

 CNN有许多非常重要的性质比如平移不变性、多尺度特征、关注局部,而引入这些卷积特性的swin transformer的成功也揭示了这些卷积特性并不是无关紧要的。因此许多研究人员开始尝试将这些特性重新引回到transformer中,但往往在设计上趋于复杂,而且这些特性在CNN中是古已有之的。因此CNN之所以受到挑战只是因为目前在各项视觉任务上点数不够高,而表现不好也通常是因为transformer scaling behavior的特性上,即模型增大性能增强。因此作者打算反其道而行之,探寻transformer和CNN的不同之处,找出其中决定性性的不同,反哺CNN,深挖CNN的性能极限。从ResNet出发,不断的从transformer中学习以修改架构达到更好的效果,最终得到了ConvNeXt,在多项视觉任务上和transfoermer媲美,并且简单高效。

训练策略

 训练300个轮次,使用Adam-W作为优化器,使用Mixup, Cutmix,RandAugment, Random Erasing这些数据增强技术。使用随机深度和标签平滑来实现正则。准确率从76.1%涨到了78.8%

宏观设计

分阶段比例调整

 ResNet将计算过程分为了4个阶段,每个阶段中block的数目比为{3,4,6,3},主要是依照经验确定的。在swin transformer中,采用了相似的策略,但每个阶段中block的数目比例为{2,2,6,2},更大的模型则用的是{1,1,9,1},因此将ResNet-50分阶段block的比例也设置为{3,3,9,3}。准确率从78.8%涨到了79.4%。(但其实这里分阶段模块数目调整后整体的计算量增大了,很难说是因为block数目的调整带来的提升还是模型变大所带来的提升)

“stem”到“patchfiy”

 CNN的前几层往往会使用下采样手段来将原始的输入变换到合适的大小以去除图像中的冗余,通常是以7*7步长为2的卷积再接2*2的池化来实现,对原图进行4×4\times下采样。而在swin transformer中则是更激进的将图像进行patch embdedding划分为多个4*4的patch,因此作者将stem cell替换成4*4步长为4的卷积(无重叠卷积)。准确率从79.4%涨到了79.5%。(其实不是很明显,有可能是因为去除了池化层减少了信息的丢失1

ResNext-fiy

 采纳了ResNext中的分组卷积思路。ResNext是ResNet和Inception结合的产物,融合了前者的参差连接和后者的多尺度思路,具体而言是将Inception模块进行了标准化设计,舍弃了其中多尺度的想法,加入了split-transform-merge的模式。在原本ResNet的基础上,将一条主路分组成多条支路再求和得到输出,第一层原本是用64个卷积核卷积,现在变成了用128个卷积核来处理,得到的结果再分为32组送入支路单独处理(也就是分组卷积)2

1.png 而本文作者采用了更激进的思路,使用了深度卷积3来代替分组卷积,即分组数等于通道数。由此大大减少了网络的计算量,相应的可以增加网络的宽度来补足这节省下来的计算量。将ResNet的宽度从64提升至96。准确率从79.5%到了80.5%。(这里的深度卷积思路很像另一片掀翻transformer的文章)

Inverted bottleneck

 bottleneck层描述的是残差连接方式特征图样的通道数目由多->少->多的过程4,也就是用1*1卷积来减少计算量。而inverted bottleneck则是在模块中将通道数目从少->多->少。swin transformer中跟在attention后的MLP层就是以这种方式工作。将ResNext中的模块同样依此方法设计,如下图将a转变成b实现inverted bottleneck。准确率从80.5%提升到80.6%(大模型上提升效果更好),由于输入端short cut的成本变低,即使depth wise卷积成本变高,计算量也有所下降。

2.png

large kernel size

 如今cnn往往推崇使用连续堆叠的小卷积核,而swin transformer却使用了7*7大小的窗口,因此尝试在ResNeXt中也使用大窗口。首先要将depth wise卷积的位置提前,这有两个目的:

  1. 减少计算量;
  2. 将depth wise卷积视为卷积版本的Local attention模块的话,它的位置应该放在全连接层,也就是1*1卷积层之前,和swin transformer对应; 3.png 此番操作使得准确率从80.5%降低到了79.9%

而后调节卷积核的大小,发现size提升到7*7时,对准确率的提升效果达到了饱和,来到了80.6%,同时由于之前调整了depth wise卷积层卫位置减小了计算量,替换成7*7卷积后计算量没有增加。(有理由怀疑是先调整了卷积核大小,发现效果不好计算量还增大,就想办法换了位置减小计算量)

微观设计

激活函数

 使用GeLu替换Relu,准确率没有提升。

减少激活函数数目

 swin transformer中一个非常不同于CONV的点是非线性激活使用的非常克制,很多地方都是单纯的线性映射。因此去除了残差模块中过多的激活函数,只留下了中间层的。如下图:

4.png 此举使得准确率从80.6%上升至81.3%

归一化策略

 同样的,swin transformer中使用LN来进行归一化也很克制,而CNN中同样是一层一个,只留下第一层的BN,使得准确率从81.3%提升至81.4%;将BN替换成LN准确率提升至81.5%

下采样策略

 ResNet中通常是在每个阶段的开始使用步长为2的3*3卷积来对特征图样下采样,而swin transformer中则是在阶段间添加了分离的下采样层。因此依样使用步长为2的2*2卷积来下采样,但这样使得损失不收敛,后续发现在图像分辨率发生改变的地方加入LN层可以有效加快网络收敛,而这也与Swin transformer的设计是一致的。准确率从81.5%来到了82.0%。

实验

 经过上述改进,得到了完全基于CNN的ConvNeXt,在ImageNet分类任务上的表现已经超过了swin transformer。但这并不足够,如之前所说,swin transformer的强大之处在于scale behavior,即模型越大,性能越好。给出不同大小的模型在ImageNet上结果对比如下,可以看出ConvNeXt同样具有很强的scale bility。

5.png  在各项下游任务上,ConvNeXt的结果也可以和swin transformer分庭抗礼,而且虽然ConvNeXt使用了深度卷积,按理会运行缓慢且吃内存,但实验发现在推断过程中ConvNeXt的速度是要比swin transforer要快的,而且训练时需要的内存也更少。

总结

 总的看来,ConvNeXt架构相对于ResNet的提升主要依赖于以下几点:

  1. 更好的训练策略:这还是很显然的,现在的优化器以及数据增强研究都比之前要更深入了。
  2. 深度卷积:看来深度卷积或者是分组卷积这种“老古董”可能又要被挖回来了,如之前那篇文章一样,深度卷积所蕴含的稀疏性思想可能真的很重要,和local attention异曲同工。最早GoogLeNet的设计本来也是沿着这个思路,走着走着就向多尺度方向发展了。
  3. 更少激活:这点还是挺奇妙的,以前习惯是无脑堆非线性激活增强拟合能力,网络不收敛就加残差连接,加归一化;但这里却发现做减法却能达到更好的效果。

参考文献

Footnotes

  1. A ConvNet for the 2020s 论文解读

  2. ResNeXt与分组卷积

  3. A Basic Introduction to Separable Convolutions

  4. Residual, BottleNeck, Inverted Residual, MBConv的解释和Pytorch实现