1、简介

论文原文: ConvNeXt)

自从Vit(Vision Transformer)在CV领域大放异彩, 越来越多的研究人员开始涌入Transformer中, 2021年在CV领域的文章绝大多数都是基于Transformer的, 比如2021年的ICCV的best paper (Swin transformer), 而卷积神经网络已经开始慢慢淡出舞台中央。 卷积网络要被Transformer取代 了吗, 也许会在不久的将来。2022年一份月, Facebook AI Research和UC Berkeley一起发表了一篇文章A ConvNet for the 2020s, 在文章中提出了ConVNeXt纯卷积神经网络, 它对标的就是2021年非常火的Swin Transformer, 通过一系列实验对比, 在相同的FLOPs下, ConvNeXt相比Swin Transformer拥有更快的推理速度以及更高的准确率, 在ImageNet 22k上ConvNeXt-XL达到了87.8%的准确率。

image-20231110171124691

仔细阅读这篇文章, 你会发现ConvNeXt使用的都是现有的结构和方法, 无任何结构或者方法上的创新,而且源码也非常精简, 100多行代码就能搭建完成。 相比Swin Transformer简直不要太简单。 之前看Swin transformer时,滑动窗口, 相对位置索引, 不光原理理解起来很吃力,源码也让人绝望(但不可否认Swin Transformer的成功以及巧妙的设计思想)。为什么基于Transformers结构的模型比卷积神经网络要好呢, 论文中的作者认为可鞥就是随着技术的不断发展, 各种新的架构以及优化策略促使Transformer模型的效果更好, 那么使用相同的策略去训练卷积神经网络也能达到相同的效果吗?

In this work, we investigate the architectural distinctions between ConvNets and Transformers and try to identify the confounding variables when comparing the network performance. Our research is intended to bridge the gap between the pre-ViT and post-ViT eras for ConvNets, as well as to test the limits of what a pure ConvNet can achieve.

设计方案

作者首先利用训练网络Vision Transformers的策略去训练原始的ResNet50模型, 发现比原始效果要好很多, 并将此结果作为后续实验额的基准baseline, 接下来的实验包含如下部分。

macro design

ResnetXt

inverted bottleneck

large kernel size

variout layer-wise micro designs

Our starting point is a ResNet-50 model. We first train it with similar training techniques used to train vision Transformers and obtain much improved results compared to the original ResNet-50. This will be our baseline. We then study a series of design decisions which we summarized as 1) macro design, 2) ResNeXt, 3) inverted bottleneck, 4) large kernel size, and 5) various layer-wise micro designs.

下图展现了每个方案对最终结果的影响。 很显然最后得到的ConNetX在相同FLOPs下准确率已经超过了Swin Transformer。

image-20231110172201944


Macro design

在这个部分主要研究两个方面

Changing stage compute ratio. 在原ResNet网络中, 一般conv4_x(即stage3)堆叠的block的次数是最多的, 如下图中的ResNet50中stage1到stage4堆叠block的次数是(3, 4, 6, 3)比例大概是1:1:2:1,但在Swin Transformer中, 比如Swin-T的比例是1:1:3:1, Swin-L的比例是1:1:9:1。很明显, 在Swin Transformer中, stage3堆叠block的占比更高。所以作者将ResNet50中的堆叠次数由(3, 4, 6, 3)调整成(3, 3, 9,3),和Swin-T拥有相似的FLOPs。进行调整后, 准确率78.8%提升到了79.4%。

image-20231110174426233

Changing stem to “Patchify”, 在之前的卷积神经网络中, 一般最初始的下采样模块stem一般都是通过一个卷积核大小为7×7步距为2的卷积层以及一个步距为2的最大池化下采样层共同组成。 高和宽都是下采样的4倍。 但在Transformer模型中一般都是通过一个卷积核非常大而且相邻窗口之间没有重叠的(即stride 等于kernel_size)卷积层进行下采样。比如在Swin transformer中采用的是一个卷积核大小为4×4步距为4的卷积层构成patchify, 同样是下采样4倍。所以作者将ResNet中的stem也换成了和Swin Transformer一样的patchify, 替换后准确率从79.4%提升到79.5%, 并且FLOPs也降低了一点。


ResNeXt-ify

接下来作者借鉴了ResNeXt中的组卷积grouped convolution, 因为ResNeXt相比普通的ResNet而言在FLOPs以及accuracy之间做到了更好的平衡。 而作者采用的是更激进的depthwise convolution. 即group数和通道数channel相同。 之前在讲MobileNet时讲解过这个。这样做的另外一个原因是作者认为depthwise convolution和self-attention中的加权求和操作很相似。

We note that depthwise convolution is similar to the weighted sum operation in self-attention

接着作者将最初的通道数由64调整成96和Swin Transformer保持一致, 最终准确率达到了80.5%。


Inverted Bottleneck

作者认为Transformer block中的MLP模块非常像MobileNetV2中的Inverted Bottleneck模块, 即两头细中间粗。下图a是ResNet中采用的Bottleneck模块, b是MobileNetV2采用的Inverted Bottleneck模块。c是ConvNeXt采用的是Inverted Bottleneck模块。

image-20231110175852997

作者采用Inverted Bottleneck模块后, 在较小的模型上准确率由80.5%提升到了80.6%, 在较大的模型上准确率由81.9%提升到了82.6%。


Larget Kernel Sizes

在Transformer中一般都是对全局做self-attention, 比如Vision Transformer, 即使是Swin Transformer也有7×7大小的窗口。但现在主流的卷积神经网络都是采用3×3大小的窗口, 因为之前VGG论文中说通过堆叠多个3×3的窗口可以替代一个更大的窗口。而且现在的GPU设备针对3×3大小的卷积核做了很多的优化, 所以会更高效, 接着作者做了如下两个改动:

Moving up depthwise conv layer, 即将depthwise conv模块上移, 原来是1×1 conv->depthwise conv->1x1 conv, 现在变成了depthwise conv->1×1 conv->1x1 conv,这么做是因为在Transformer中, MAS模块是放在MLP模块之前的, 所以这里进行效仿, 将depthwise conv上移, 这里改动后, 准确率下降到了79.9%, 同时FLOPs也减少了。

Increasing the kernel size, 接着作者将depthwise conv的卷积核大小由3×3改成了7×7(和swin Transformers一样), 当然作者也尝试了其他尺寸, 包括3, 5, 7, 9, 11发现取到7时准确率达到了饱和, 并且准确率从79.9%增长到80.6%(7×7)。


Micro Design

接下来作者再聚集到更细小的差异, 比如激活函数以及Normalization.

Replacing ReLU with GELU, 在Transformer中激活函数基本用的都是GELU, 而在卷积神经网络中最常用的是ReLU, 于是作者又将激活函数替换成了GELU, 替换后发现准确率没发生变化。

Fewer activation functions, 使用更少的激活函数, 在卷积神经网络中, 一般会在每个卷积层或全连接层后接上一个激活函数, 但在Transformer中并不是每个模块后都跟有激活函数, 比如MLP中只有第一个全连接层后跟了GELU激活函数, 接着作者再ConvNeXt中也减少了激活函数的使用, 如下图所示, 减少后发现准确率增长到了81.3%。

SwinTransformerBlock

Fewer normalization layers: 使用更少的Normalization. 同样在Transformer中, Normalization使用的也比较少, 作者也减少了ConvNeXt Block中的Normalization层, 只保留了depthwise conv后的Normalization层, 此时准确率达到了81.4%, 已经超过了Swin-T。

Substituting BN with LN, 将BN替换成LN。Batch Normalization(BN)在卷积神经网络中是非常常用的操作了,它可以加速网络的收敛并减少过拟合(但用的不好也是个大坑)。但在Transformer中基本都用的Layer Normalization(LN),因为最开始Transformer是应用在NLP领域的,BN又不适用于NLP相关任务。接着作者将BN全部替换成了LN,发现准确率还有小幅提升达到了81.5%。

Separate downsample layers. 单独的下采样层。在ResNet网络中stage2-stage4的下采样都是通过将主分支上3x3的卷积层步距设置成2,捷径分支上1x1的卷积层步距设置成2进行下采样的。但在Swin Transformer中是通过一个单独的Patch Merging实现的。接着作者就为ConvNext网络单独使用了一个下采样层,就是通过一个Laryer Normalization加上一个卷积核大小为2步距为2的卷积层构成。更改后准确率就提升到了82.0%。


对于ConvNeXt网络, 作者提出了T/S/B/L四个版本, 计算复杂度刚好和Swin Transformer中的T/S/B/L相似。

这四个版本的配置如下:

ConvNeXt-T: C = (96, 192, 384, 768), B = (3, 3, 9, 3)
ConvNeXt-S: C = (96, 192, 384, 768), B = (3, 3, 27, 3)
ConvNeXt-B: C = (128, 256, 512, 1024), B = (3, 3, 27, 3)
ConvNeXt-L: C = (192, 384, 768, 1536), B = (3, 3, 27, 3)
ConvNeXt-XL: C = (256, 512, 1024, 2048), B = (3, 3, 27, 3)

其中C代表4个stage中输入的通道数, B代表每个stage重复堆叠block的次数。


ConvNeXt-T结构图

下图是根据源码绘制的网络结构图, 会发现ConvNeXt Block中还有一个Layer Scale操作, 其实它就是将输入的特征乘以上一个可训练的参数, 该参数就是一个向量, 元素个数与特征层channel相同, 即对每个channel的数据进行缩放。

ConvNeXt