ConvNeXt(CVPR 2022)论文解读

paper:A ConvNet for the 2020s

official implementation:https://github.com/facebookresearch/ConvNeXt

third-party implementation:https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/convnext.py

背景

在2020年代,视觉识别领域开始被Vision Transformers(ViTs)主导,这些模型迅速超越了传统的卷积神经网络(ConvNets)成为图像分类的顶尖模型。然而,虽然ViTs在图像分类任务中表现优异,但在目标检测和语义分割等计算机视觉任务中却存在困难。因此,层次化的Transformers(如Swin Transformers)重新引入了若干ConvNet的设计元素,使得Transformers在各种视觉任务中表现出色 。

本文的创新点

本文重新审视了ConvNet的设计空间,并测试了一个纯ConvNet能够达到的性能极限。作者从标准的ResNet出发,逐步“现代化”其设计,使其接近视觉Transformer的设计,并在此过程中发现了一些关键组件,这些组件有助于缩小性能差距。

具体如下

  1. ConvNeXt架构:完全由标准的ConvNet模块构建,没有使用任何基于注意力的模块,展示了纯ConvNet模型在现代计算机视觉任务中的竞争力。
  2. 现代化的ConvNet设计:通过一系列设计决策(如宏观设计、ResNeXt结构、inverted bottleneck、大核卷积和微观层级设计等),将标准的ResNet模型逐步现代化
  3. 简化和效率:ConvNeXt在保持简洁设计的同时,提供了与Transformer相当的性能,且在某些情况下效率更高。
  4. 广泛的评估:ConvNeXt在多个视觉识别任务上进行了评估,包括ImageNet分类、COCO目标检测和ADE20K语义分割,证明了其通用性和有效性。

方法介绍

Modernizing a ConvNet:  a Roadmap

作者提供了一个从ResNet到转变成一个类似于一个Transformer的ConvNet的过程轨迹,具体考虑了两种模型尺寸,一种是ResNet-50/Swin-T,FLOPs在4.5x10^9左右,另一种是ResNet-200/Swin-B,FLOPs在15.0x10^9左右。为简单起见,我们将用ResNet-50 / Swin-T模型来展示结果。对更高容量模型的结论是一致的。

作者的探索是为了研究和借鉴Swin-Transformer不同级别的设计同时保持一个标准ConvNet的简洁。具体的探索路线图如下:起点是一个ResNet-50,我们首先用vision Transformer相似的训练技巧来训练它,得到了相比原始的ResNet-50改进很多的结果,以这个作为baseline。然后我们研究了一系列的设计决策总结为 1)宏观设计 2)ResNeXt 3)inverted bottleneck 4)large kernel size 5)不同层的微观设计。图2展示了通过“网络现代化”每一步的过程和对应的结果。所有模型在ImageNet-1K上训练和评估。

Training Techniques

除了网络架构的设计外,训练过程也会影响最终的性能。Vision Transformer不仅带来了新的模块和架构设计决策,还引入了不同的训练技巧(比如AdamW优化器)。这主要涉及到优化策略和相关的超参设置。因此我们第一步是用vision Transformer的训练程序来训练一个baseline模型,ResNet-50/200。这里的训练设置类似于DeiT和Swin Transformer的。训练从90个epoch延长到300个,优化器选择AdamW,数据增强包括Mixup、Cutmix、RandAugment、Random Erasing以及正则化包括Stochastic Depth和Label Smoothing。完整的超参设置如表5所示

增强的训练方案使得ResNet-50的精度从76.1%提升到了78.8%(+2.7%),这意味着传统的卷积网络和vision Transformer之间的性能差异很大一部分是训练技巧造成的。在接下来整个“现代化”的过程中我们都使用相同的超参和训练配置。

Macro Design

Changing state compute ratio. 在ResNet中不同stage计算量分布的设计主要是经验性的,沉重的'res4' stage是为了与下游任务兼容比如目标检测,其中一个检测head作用于14x14的特征图上。Swin-T遵循相同的原理但不同stage的计算比略有不同1:1:3:1,对于更大的Swin Transformer这个比例为1:1:9:1。遵循这种设计,我们将ResNet-50不同stage中block的数量从(3, 4, 6, 3)改为(3, 3, 9, 3),这保持了和Swin-T相近的FLOPs。这步操作将模型的精度从78.8%提高到了79.4%。

Changing stem to "Pachify". 标准的ResNet中stem部分包含一个stride=2的7x7卷积和一个max pool,使得输入图像降采样4x。在vision Transfrmer中,stem阶段采用了一个更激进的"patchify"策略,它使用一个更大的卷积核(例如14或16)并且卷积核之间不重叠(即步长等于卷积核大小)。Swin Transformer用了类似的"patchify"层但使用了一个较小的patch size 4以适应架构的多级设计。我们用一个4x4-s4的卷积层作为patchify layer替换原本的stem,这一步将模型的精度从79.4%提升到79.5%。

ResNeXt-ify

在这一部分中,我们尝试采用ResNeXt的思想,它比普通的ResNet有更好的FLOPs/accuracy权衡。核心组件是分组卷积。ResNeXt的指导原则是“使用更多的组,扩大宽度”。更准确地说,ResNeXt对bottleneck block中的3×3conv层采用了分组卷积。由于这大大减少了FLOPs,网络宽度被扩大,以补偿容量损失。

本文作者使用了深度卷积,它是组卷积的一种特殊情况,group数量等于通道数。作者注意到,深度卷积类似于self-attention中的加权求和操作,它在每个通道上计算即只在空间维度进行信息的融合。depthwise卷积和1x1卷积的组合分离了空间的融合通道的融合,这也是vision Transformer的特性,即每个operation要么融合空间维度的信息要么融合通道维度的信息但不会同时进行。使用深度卷积有效降低了FLOPs,但如预期一样精度也降低了。根据ResNeXt的策略作者将网络宽度增加到了和Swin-T一样(64到96)。随着FLOPs的增加(5.3G)网络性能达到了80.5%。

Inverted Bottleneck

Transformer block的一个重要设计是它用了一个inverted bottleneck,即MLP block中隐藏层的维度是输入的4倍,如图4所示。

作者探索了inverted block的设计,图3(a)到(b)展示了这种配置。尽管深度卷积层的FLOPs有所增加,由于降采样residual block shortcut 1x1卷积层带来的FLOPs下降,整个网络FLOPs降低到了4.6G。这里带来了精度的略微提升,80.5%到80.6%。

 

Large Kernel Sizes

Vision Transformer最显著的一个特点就是非局部的self-attention,这使得每一层都有全局的感受野。而ConvNet中往往是堆叠小核(3x3)卷积层,它们在现代GPU上有高效的硬件实现。尽管Swin Transformer重新将local window引入到了self-attention block,但窗口大小至少为7x7,显著大于ResNe(X)t的3x3。因此这里作者重新研究了在ConvNet中使用大的卷积核。

Moving up depthwise conv layer. 为了探索大卷积核,一个前提是上移depthwise卷积层的位置(图3(b)到(c))。这个设计在Transformer中很明显:MSA block放置在MLP层之前。由于我们有一个inverted bottleneck block,这是一个很自然的设计选择——复杂低效的模块(MSA,大核卷积)的通道数将会变少,而高效密集的1x1卷积将会完成繁重的工作。这一中间步骤将FLOPs降低到了4.1G,精度也暂时下降到了79.9%。

Increasing the kernel size. 在有了上述前提下,采用更大核的卷积的好处是显著的。作者实验了几个kernel size,包括3、5、7、9和11,网络的性能从79.9%(3x3)提升到了80.6%(7x7),而网络的FLOPs几乎保持不变。此外作者还观察到,采用更大卷积核的增益在7x7时达到饱和点。

至此,我们结束了对宏观尺度上网络架构的研究,有趣的是,vision Transformer中采用的大部分设计选择可以直接应用于ConvNet。

Micro Design

这一部分,作者将研究微观尺度上的几个架构上的差异,这里大多数探索都是在层的级别上完成的,重点关注激活函数和normalization层的选择。

Replacing ReLU with GELU 自然语言处理和视觉架构的一个差异是具体使用的激活函数类型。ReLU由于其简洁和高效被广泛使用于ConvNet中。在原始的Transformer中也使用了ReLU。而GELU,可以被视为ReLU的平滑版本,被广泛应用于一些最先进的Transformer架构中,包括BERT、GPT-2和ViT。作者发现,在本文的ConvNet中也可以用GELU替代ReLU,尽管精度保持不变(80.6%)。

Fewer activation functions. Transformer和ResNet的一个微小区别是前者使用的激活函数更少。考虑一个有key/query/value线性embedding层的Transformer block,projection layer以及MLP block中的两个线性层,其中只在MLP block中有一个激活函数。作为对比,通常每个卷积层后都添加一个激活函数。这里作者探索了在ConvNet中用相同的策略时,性能将如何变化。如图4所示,我们从residual block中去掉所有的GELU只保留两个1x1卷积层之间的一个GELU,复制了Transformer的风格。这一步将精度提高了0.7%至81.3%,基本上match了Swin-T的性能。

Fewer normalization layers. Transformer block通常也配置较少的normalization layer。这里作者去掉了两个BN层,只保留1x1卷积前的一个BN层。这进一步将性能提升到了81.4%,已经超越了Swin-T。

Substituting BN with LN. BatchNorm是ConvNet中一个重要组成部分因为它提高了收敛性减少了过拟合。但BN也有许多复杂的问题,这可能会对模型的性能产生不利影响。另一方面,Transformer中使用了更简单的Layer Normalization并在不同的场景中表现出了良好的性能。在GN的文章中作者提到用LN替换BN会带来次优的性能。但经过上述对网络架构和训练技巧的修改后,本文作者发现用LN训练ConvNet没有任何问题,性能还稍微提高了一点到81.5%。

Separate downsampling layers. 在ResNet中,降采样是在每个stage开始的residual block中进行的,通过3x3-s2的卷积实现(shortcut中通过1x1-s2的卷积)。在Swin Transformer中,在每个stage之间有一个单独的降采样层。本文探索了一种类似的策略,即使用2x2-s2的卷积进行降采样。结果作者发现这种修改会导致训练发散,进一步研究发现,在改变分辨率的地方添加归一化层有助于稳定训练。经过这一步,精度提升到了82.5%,超越了Swin-T的81.3%。

至此就得到了本文的最终结构,作者称之为ConvNeXt。ResNet、Swin Transformer和ConvNeXt的block结构如图4所示。网络详细的结构配置如表9所示。

实验结果

不同大小的ConvNeXt的配置如下

作者在ImageNet上进行了两组实验,一组是直接在ImageNet-1K上进行训练与评估,另一组是在ImageNet-22K上进行预训练并在ImageNet-1K上微调,两组实验的结果如表1所示。其中上半部分是直接在ImageNet-1K上进行训练的结果,可以看到在精度-计算权衡方面ConvNeXt和两个强ConvNet基线(RegNet和EfficientNet)相比取得了具有竞争力的结果。在相似计算量的前提下,ConvNeXt在所有计算量的范围中都超过了Swin Transformer。

在ImageNet-22K上预训练的结果如表1下半部分所示,进行这组实验的原因是:一个普遍的观点是,vision Transformer有更少的归纳偏置,因此在更大规模数据的预训练下可以比卷积网络表现得更好。通过实验结果可知,在大规模数据预训练下,ConvNeXt的性能表现不比Swin Transformer差,表明了ConvNeXt也是一个scalable架构。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/666723.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

面试杂谈k8s

其实看我之前的博客,k8s刚有点苗头的时候我就研究过,然后工作的时候间接接触 也自己玩过 但是用的不多就忘记了,正苦于不知道写什么,水一篇 用来面试应该是够了 支持云应用开发、运行与运维一体化的云应用平台软件应运而生 k8s核…

JVM 指针压缩

运用java内存对齐填充,对java内存进行8字节划分,java对象指针映射到每个划分区域上,使得4个字节(32位)表示2^32个地址,从而使4个字节指针映射32G内存空间。 1.为什么进行指针压缩: jvm从32位变…

【DSP】xDAIS算法标准

1. 简介 在安装DSP开发支持包时,有名为 “xdais_7_21_01_07”文件夹。xDAIS全称: TMS320 DSP Algorithm Standard(算法标准)。39条规则,15条指南。参考文档。参考文章。 2. 三个层次 3.接口 XDAIS Digital Media。编解码引擎。VISA(Video&…

18.Redis之哨兵

1.哨兵机制的介绍 通过自动化的手段,来解决主节点挂了的问题~~ 哨兵机制, 是通过独立的 进程 来体现的.和之前 redis-server 是不同的进程!! redis-sentine| 不负责存储数据,只是对其他的 redis-server 进程起到监控的效果~~ 通常哨兵节点,也会搞一个集合~~(多个哨兵节点构成的…

汽车MCU虚拟化--对中断虚拟化的思考(2)

目录 1.引入 2.TC4xx如何实现中断虚拟化 3.小结 1.引入 其实不管内核怎么变,针对中断虚拟化无非就是上面两种,要么透传给VM,要么由Hypervisor统一分发。汽车MCU虚拟化--对中断虚拟化的思考(1)-CSDN博客 那么,作为车规MCU龙头…

基于ES安装IK分词插件

前言 IK分词器插件是为Elasticsearch设计的中文分词插件,由Elasticsearch的官方团队之外的开发者medcl开发。它主要针对中文文本的分词需求,提供了较为准确的中文分词能力。以下是IK分词器插件的一些特点: 智能分词:IK分词器采用基…

thinkphp6 自定义的查询构造器类

前景需求&#xff1a;在查询的 时候我们经常会有一些通用的&#xff0c;查询条件&#xff0c;但是又不想每次都填写一遍条件&#xff0c;这个时候就需要重写查询类&#xff08;Query&#xff09; 我目前使用的thinkphp版本是6.1 首先自定义CustomQuery类继承于Query <?p…

戴尔科技:一盆冷水浇醒了AIPC

这年头&#xff0c;只要沾上英伟达的公司&#xff0c;不论美股还是大A,都跟着鸡犬升天几轮过&#xff0c;但昨晚英伟达蒸发1064亿美元&#xff0c; 跟着遭罪的也不少&#xff0c;有没有一夜惊魂梦醒的感觉&#xff1f; 今天我们来说说——戴尔科技。 昨晚戴尔科技大跌5.18%&a…

R语言ggplot2包绘制网络地图

重要提示&#xff1a;数据和代码获取&#xff1a;请查看主页个人信息&#xff01;&#xff01;&#xff01; 载入R包 rm(listls()) pacman::p_load(tidyverse,assertthat,igraph,purrr,ggraph,ggmap) 网络节点和边数据 nodes <- read.csv(nodes.csv, row.names 1) edges…

网页截图并添加美观外壳:无需PS轻松实现的方法

在日常生活和工作中&#xff0c;我们经常需要截取网页的屏幕快照&#xff0c;以便于分享、保存或用于其他用途。尽管许多人认为使用Photoshop&#xff08;PS&#xff09;是最佳选择&#xff0c;但实际上&#xff0c;有许多更简单、快捷的方法可以帮助我们实现这一目标&#xff…

时间控件,开始时间和结束时间限制

****开始时间必须小于结束时间 如果选择了结束时间&#xff0c;开始时间必须小于结束时间 //开始时间<el-date-pickerstyle"width:190px;"v-model"searchForm.clsjdate"placeholder"请选择日期"type"date"value-format"yyyy-…

【学习笔记】数据结构(二)

线性表 文章目录 线性表1、线性结构2、线性表2.1 线性表定义2.2 类型定义2.2 顺序存储结构&#xff08;Sequence List&#xff09;2.3 链式存储结构2.3.1 单链表2.3.2 循环链表2.3.3 双链表2.3.4 单链表、循环链表、双向链表的时间效率比较2.3.5 链式存储结构优缺点 2.4 顺序表…

可用于嵌入式的解释器调研对比,及lua解释器介绍

嵌入式不一定只能用C! ---------------------------------------------------------------------------------------手动分割线-------------------------------------------------------------------------------- 本文章参考了以下文章&#xff1a; 这里是引用 ------------…

城市之旅:使用 LLM 和 Elasticsearch 简化地理空间搜索(二)

我们在之前的文章 “城市之旅&#xff1a;使用 LLM 和 Elasticsearch 简化地理空间搜索&#xff08;一&#xff09;”&#xff0c;在今天的练习中&#xff0c;我将使用本地部署来做那里面的 Jupyter notebook。 安装 Elasticsearch 及 Kibana 如果你还没有安装好自己的 Elasti…

字符串 | 字符串匹配之 KMP 算法以及 C++ 代码实现

目录 1 为什么使用 KMP&#xff1f;2 什么是 next 数组&#xff1f;2.1 什么是字符串的前后缀&#xff1f;2.2 如何计算 next 数组&#xff1f; 3 KMP 部分的算法4 完整代码 &#x1f608;前言&#xff1a;这篇文章比较长&#xff0c;但我感觉自己是讲明白了的 1 为什么…

迈的普拉姆利普绘图:深入解析与实战应用

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;matplotlib绘图的基本原理 代码案例 二、深入了解&#xff1a;matplo…

Android更新优化 - 增量更新是如何节省用户时间和流量的

增量更新和全量更新 我想玩过大型手游的人都知道&#xff0c;手游的安装包非常大&#xff0c;因为资源图片众多。而你每次更新都把所有文件都更新下来&#xff0c;是非常耗时的&#xff0c;对吧。耗时是一个方面&#xff0c;有些人在户外开的是移动网络&#xff0c;动不动就几…

vue3 侦听器

侦听器示例 计算属性允许我们声明性地计算衍生值。然而在有些情况下&#xff0c;我们需要在状态变化时执行一些“副作用”&#xff1a;例如更改 DOM&#xff0c;或是根据异步操作的结果去修改另一处的状态。 在组合式 API 中&#xff0c;我们可以使用 watch 函数在每次响应式…

模型构建器之迭代器

上一篇我们介绍了模型构建器的基础&#xff0c;将一个工作流串联起来&#xff0c;然后做成模型工具。今天我们介绍模型构建器的第二个重要功能——迭代&#xff0c;也就是程序中的循环。 先来看一个例子。要给数据库中所有要素类添加一个相同的字段&#xff0c;该怎么做&#…

Diffusion Model, Stable Diffusion, Stable Diffusion XL 详解

文章目录 Diffusion Model生成模型DDPM概述向前扩散过程前向扩散的逐步过程前向扩散的整体过程 反向去噪过程网络结构训练和推理过程训练过程推理过程优化目标 详细数学推导数学基础向前扩散过程反向去噪过程 Stable Diffusion组成结构运行流程网络结构变分自编码器 (VAE)文本编…