【论文泛读】ConvNeXt:A ConvNet for the 2020s(新时代的卷积)

【论文泛读】ConvNeXt:A ConvNet for the 2020s(新时代的卷积)


近几年,许许多多的深度学习模型都在图像分类中大放光彩,首先是2012年的AlexNet作为卷积神经网络的开山鼻祖,掀起了卷积神经网络的热潮,比较震撼人心的是,在2016斩获CVPR的best paper的ResNet,第一次在CIFAR数据集上超越了人的准确率,这无疑踏出了关键性的一步,紧接着又有许许多多的模型出现,包括2017年的DenseNet和ResNet的作者又在ResNet改进得到了ResNeXt。

卷积神经网络如雨后春笋般涌入计算机视觉领域中,但是,自从ViT提出之后,在过去的一年里(2021年),基于transformer的模型在计算机视觉各个领域全面超越CNN模型。然而,这很大程度上都归功于Local Vision Transformer模型,Swin Transformer是其中重要代表,Swin Transformer在图像领域(分类下游任务)的全面大幅度超越 CNN模型, 仿佛印证了 Attetion 论文中 “Attention Is All You Need ”。

Introduction 介绍

在新时代中,是否卷积神经网络就已经被时代淘汰了呢!FaceBook研究所的“A ConvNet for the 2020s”,即ConvNeXt 这篇文章,通过借鉴 Swin Transformer 精心构建的 tricks,卷积在图像领域反超 Transform。这些技巧对分类问题下游downstream的问题也有效果。简单的来说,似乎就是说明,用Swin Transformer的丹方,在卷积神经网络中炼丹也有很好的效果。

本篇文章就是基于这个新时代的卷积神经网络,本文为ConvNeXt篇,就此展开卷积的新时代,讲述从ConvNeXt的一个过程和方法,简要介绍设计的思想和方法,以及结合相关代码的思想和方法,最终给出实验结果。

Modernizing a ConvNet:a Roadmap

ConvNeXt是基于ResNet-50的结构,参考Swin Transformer的思想进行现代化改造,直到卷积模型超过trans-based方法的SOTA效果。ConvNeXt 从原始的 ResNet 出发,逐步加入Swin Transformer 的 trick,来改进模型。论文中适用 ResNet模型:ResNet50和ResNet200。其中ResNet50和Swin-T有类似的FLOPs(4G vs 4.5G),而ResNet200和Swin-B有类似的FLOPs(15G)。首先做的改进是调整训练策略,然后是模型设计方面的递进优化:宏观设计->ResNeXt化->改用Inverted bottleneck->采用large kernel size->微观设计。由于模型性能和FLOPs强相关,所以在优化过程中尽量保持FLOPs的稳定,也就是希望,在计算能力相同的情况下,比较模型性能的优劣。

在这里插入图片描述

图表 1 ResNet-50 -> ConvNeXt 的Roadmap

Training methods 训练方法

在ConvNeXt中,它的优化策略借鉴了Swin Transformer。具体的优化策略包括:

(1)将训练Epoch数从90增加到300;

(2)优化器从SGD改为AdamW;

(3)更复杂的数据扩充策略,包括Mixup,CutMix,RandAugment,Random Erasing等;

(4)增加正则策略,例如随机深度,标签平滑,EMA等。

更具体的预训练和微调的超参数如图。AdamW, 300epoch,预训练学习率4e-3,weight decay= 0.05,batchsize = 4096;微调学习率 5e-5, weight decay= 1e-8 ,batchsize = 512,这样的方法,精度直接从76.1升到了78.8

在这里插入图片描述

图表 2 训练方式

Statio ration

卷积神经网络发展了这么多年,其结构都是经过无数研究者之手雕琢出来的,比如多阶段设计思想。如下图的ResNet50 为例,多阶段 block 数为 [3,4,6,3]。Swin Transformer参考了这样的多阶段结构,相应比例为 [2,2,6,2],更大的Swin为 [2,2,18,2],于是,ConvNeXt 就参考了一下 Swin Transformer 高比例的设置,将多阶段 block 数从 ResNet 的 [3,4,6,3] 变成了 [3,3,9,3],这样做精度涨了 0.6个点左右->79.4%

在这里插入图片描述

图表 3 ResNet的结构

实际上,在RegNet和EfficientNetV2的论文中都有指出,后面的stages应该占用更多的计算量。所以说,将后面的stage调为9是对结果有好处的。ConvNeXt参考这样的设计,根据不同的计算量FLOPs,设计不同的参数大小的网络结构。

在这里插入图片描述

图表 4 ConvNeXt的改进

Patchy

对于ImageNet数据集,我们通常采用 224x224的输入尺寸,这个尺寸对于ViT等基于Transformer的模型来说是非常大的,它们通常使用一个步长为4,大小也为4的卷积将其尺寸降采样到 56x56 。因为这个卷积的步长和大小是完全相同的,所以它又是一个无覆盖的卷积,或者叫Patchify的卷积。这一部分在Swin-Transformer中叫做stem层,它是位于输入之后的一个降采样层。

在ConvNeXt中,Stem层也是一个步长为4,大小也为4的卷积操作,这一操作将准确率从79.4%提升至79.5%,GFLOPs从4.5降到4.4%。也有人指出使用覆盖的卷积(例如步长为4,卷积核大小为7的卷积)能够获得更好的表现。

stem = nn.Sequential( 
    nn.Conv2d(in_chans, dims[0], kernel_size=4, stride=4), 
    LayerNorm(dims[0], eps=1e-6, data_format="channels_first") 
) 

ResNeXt-ify

在我们的第二部分中详细描述了ResNeXt网络,这一部分主要使用到了深度可分离卷积,深度可分离卷积最先是在MobileNet中提出的,目的是为了解决在嵌入式设备中进行推理的过程。深度可分离卷积对参数和精度有一个很好的trade off,所以ConvNeXt也参照ResNeXt的思想,将普通卷积替换成深度可分离卷积,为了和Swin-T的FLOGs相近,论文使用深度卷积即极限的分组卷积并将宽度从64扩展为96,这样也得到了很好的结果,精度上升了1%->80.5%

在这里插入图片描述

图表 5 深度可分离卷积

Inverted Bottleneck

除此之外,我们发现 Transformer 的 FFN 层是一个 Inverted Bottleneck 结构。ResNeXt的Bottleneck的设计是大通道维度->小通道维度(3×3卷积)->大通道维度,所以借鉴MobileNetV2的中的Inverted Bottleneck和参考Swin Transformer的设计,ConvNext的Bottleneck设计为小通道维度->大通道维度(3×3卷积)->小维度。Inverted Bottleneck 特点是两头窄中间宽,于是 ConvNeXt Block 在 Res Block 上做了改进,维度变化为96->384->96,精度:80.5%->80.6%(ResNet-200:81.9%->82.6)。

在这里插入图片描述

图表 6 Inverted Bottleneck

Large Kernel Sizes

ViT由于non-local自注意力的实现方式,使得每一层都具有全局感受野,虽然Swin Transformer在自注意力模块中引入了local windows,但是window的尺寸也不会小于7×7,不同于当下卷积网络使用3×3卷积堆叠代替大卷积核以获得更好的精度。在2014年论文的VGG中说,利用堆叠的3x3的卷积核进行提取特征,并且论文中说通过堆叠多个3x3的窗口可以替代一个更大的窗口,所以现在主流的卷积神经网络都是采用3x3大小的窗口。不过这样子也会存在一些缺陷,会导致感受野的范围比较小,而利用大的卷积核可以增大感受野,在某一程度可以得到更多的信息。

接着作者将depthwise conv的卷积核大小由3x3改成了7x7(和Swin Transformer一样),当然作者也尝试了其他尺寸,包括3, 5, 7, 9, 11发现取到7时准确率就达到了饱和。并且准确率从79.9% (3×3)增长到80.6% (7×7)。并且比较神奇的是,发现取到7的时候,我们的精度达到了最大,并且这个也是Swin Transformer的窗口大小一样的。

Micro Design

除此之外,还有一些更小的差异,比如激活函数和Normalization等等,我们可以比较一下关于Swin Transformer和ConvNeXt的不同。

在这里插入图片描述

图表 7 ConvNeXt Block

替换ReLU为GeLU:在Transformer中激活函数基本用的都是GELU,而在卷积神经网络中最常用的是ReLU,于是将激活函数替换成了GELU,替换后发现准确率没变化;

更少的激活函数:使用更少的激活函数。在卷积神经网络中,一般会在每个卷积层或全连接后都接上一个激活函数。但在Transformer中并不是每个模块后都跟有激活函数,比如MLP中只有第一个全连接层后跟了GELU激活函数。接着在ConvNeXt Block中也减少激活函数的使用,改动后ConvNext只保留了两个1×1卷积之间的激活函数,精度: 80.6%->81.3%

更少的正则化层:使用更少的Normalization。同样在Transformer中,Normalization使用的也比较少,接着也减少了ConvNeXt Block中的Normalization层,只保留了depthwise conv后的Normalization层。此时准确率已经达到了81.4%,已经超过了Swin-T,精度:81.3%->81.4%

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

独立的下采样层:ResNet的下采样操作是在每个阶段的开始阶段使用步长为2的3×3卷积和直连步长为2得1×1卷积完成,Swin Transformers中则是在不同阶段之间进行独立得下采样,ConvNext采用相同得策略,使用步长为2得2×2卷积进行空间下采样,这个改动会导致训练不稳定,所以在下采样操作前、Stem后以及全局池化层之后加入了一些LN层来稳定训练,精度:81.5%->82.0%

class Block(nn.Module):
    def __init__(self, dim, drop_rate=0., layer_scale_init_value=1e-6):
        super().__init__()
        self.dwconv = nn.Conv2d(dim, dim, kernel_size=7, padding=3, groups=dim)  # depthwise conv
        self.norm = LayerNorm(dim, eps=1e-6, data_format="channels_last")
        self.pwconv1 = nn.Linear(dim, 4 * dim)  # pointwise/1x1 convs, implemented with linear layers
        self.act = nn.GELU()
        self.pwconv2 = nn.Linear(4 * dim, dim)
        self.gamma = nn.Parameter(layer_scale_init_value * torch.ones((dim,)),
                                  requires_grad=True) if layer_scale_init_value > 0 else None
        self.drop_path = DropPath(drop_rate) if drop_rate > 0. else nn.Identity()

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        shortcut = x
        x = self.dwconv(x)
        x = x.permute(0, 2, 3, 1)  # [N, C, H, W] -> [N, H, W, C]
        x = self.norm(x)
        x = self.pwconv1(x)
        x = self.act(x)
        x = self.pwconv2(x)
        if self.gamma is not None:
            x = self.gamma * x
        x = x.permute(0, 3, 1, 2)  # [N, H, W, C] -> [N, C, H, W]

        x = shortcut + self.drop_path(x)
        return x

ConvNeXt Variants 各种的ConvNeXt

对于ConvNeXt网络,论文提出了T/S/B/L四个版本,计算复杂度刚好和Swin Transformer中的T/S/B/L相似, 下图给出了他们的参数结构和在ImageNet-1K的Top-1的准确率

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45508265/article/details/128590103