MMDetection 部署 ConvNeXt-V2:基于 FCMAE 预训练与 GRN 骨干的 Mask R-CNN 微调实战
2026/9/19 9:36:59 网站建设 项目流程
  • 人工智能
  • 计算机视觉
  • 深度学习
  • 模型评测

【免费下载链接】mmdetection

OpenMMLab Detection Toolbox and Benchmark

项目地址:https://gitcode.com/gh_mirrors/mm/mmdetection
点击查看免费下载

本文以 MMDetection 仓库中 projects/ConvNeXt-V2 子项目为核心,讲解如何将 ConvNeXt V2 全卷积掩码自编码器(FCMAE)预训练骨干接入 Mask R-CNN,完成 COCO 检测与实例分割任务的微调训练。读完本文,你将掌握 ConvNeXt V2 与 ConvNeXt V1 的架构差异、LSJ 大尺度抖动数据增强与分层学习率衰减的配置方法,以及如何在 MMDetection 中以 AMP 混合精度复现 52.9 box AP / 46.4 mask AP 的官方结果。

ConvNeXt-V2 项目概览:从论文到 MMDetection 落地

ConvNeXt V2 出自论文《ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders》。该工作的核心观点是:现代 ConvNet(以 ConvNeXt 为代表)虽然在监督学习下表现优异,但简单地将掩码自编码器(MAE)自监督范式套用到 ConvNeXt 上并不能取得理想效果。为此,论文提出两大创新并协同设计:

  • 全卷积掩码自编码器(Fully Convolutional Masked Autoencoder, FCMAE):一套不依赖 Transformer 位置编码的自监督预训练框架,专门适配纯卷积骨干;
  • 全局响应归一化层(Global Response Normalization, GRN):可插入 ConvNeXt 架构的新层,用于增强通道间的特征竞争(inter-channel feature competition),显著改善全卷积 MAE 预训练后模型的微调表现。

两者的协同设计产出了新的模型家族 ConvNeXt V2,在 ImageNet 分类、COCO 检测、ADE20K 分割等基准上显著提升了纯卷积网络的性能。官方公开了从 3.7M 参数的 Atto 模型(ImageNet top-1 76.7%)到 650M 参数的 Huge 模型(仅用公开数据即达 88.9% top-1)的完整预训练权重谱系。

在 MMDetection 中,projects/ConvNeXt-V2 子项目正是这条技术链路在目标检测方向的落地:把 FCMAE 预训练的 ConvNeXt V2 Base 骨干接入 Mask R-CNN,使用 LSJ(Large-Scale Jittering)增强与 3x 训练计划,在 COCO 实例分割任务上得到 box AP 52.9、mask AP 46.4 的结果。项目结构非常精简,只包含一个配置文件与本文档:

projects/ConvNeXt-V2/ ├── README.md └── configs/ └── mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco.py

使用前提:安装 MMPretrain

ConvNeXt 骨干本身不在 MMDetection 仓库内实现,而是由 OpenMMLab 的 MMPretrain 提供(MMPretrain 内置了丰富的骨干网络可供下游任务复用)。因此运行本配置前必须先安装:

pip install mmpretrain

安装后,配置文件中通过custom_imports显式导入mmpretrain.models模块,以触发 MMPretrain 内部的注册器(register_module),从而让 MMDetection 在解析type='mmpretrain.ConvNeXt'时能找到对应实现:

custom_imports = dict( imports=['mmpretrain.models'], allow_failed_imports=False)

同样的导入模式也出现在 MMDetection 官方 configs/convnext 系列配置中,例如 mask-rcnn_convnext-t-p4-w7_fpn_amp-ms-crop-3x_coco.py 采用了完全一致的写法。

官方实验结果与模型下载

projects/ConvNeXt-V2/README.md 给出了唯一的官方结果表:

MethodBackbonePretrainLr schdAugmentationMem (GB)box APmask APConfigDownload
Mask R-CNNConvNeXt-V2-BFCMAE3xLSJ22.552.946.4configmodel | log

需要特别留意的是 README 中的两条Note

  1. 该检测结果是 ConvNeXt-V2 的预发布版本(pre-release),官方微调设置当时尚未正式发布,因此该配置属于社区先行实现;
  2. 使用 ConvNeXt 骨干必须先安装 MMPretrain(见上文)。

配置文件中的两处 TODO 注释也印证了其预发布性质:drop_path_rate的随机深度取值({0.1, 0.2, 0.3, 0.4})尚待验证,RPN 的 NMS 类型、layer_wise学习率衰减的取值也标注了待扫参空间,复现时若结果与官方表有出入,可优先从这些超参入手排查。

配置文件逐段精读

完整的官方配置位于 projects/ConvNeXt-V2/configs/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco.py,下面分段剖析其设计意图。

基础配置继承

_base_ = [ 'mmdet::_base_/models/mask-rcnn_r50_fpn.py', 'mmdet::_base_/datasets/coco_instance.py', 'mmdet::_base_/schedules/schedule_1x.py', 'mmdet::_base_/default_runtime.py' ]

四份基础配置分别提供:Mask R-CNN 完整模型结构(mask-rcnn_r50_fpn.py)、COCO 实例分割数据集定义、1x 训练调度与默认运行环境。后续所有覆写都建立在这四份基线上。

骨干网络:以 GRN 为关键开关

checkpoint_file = 'https://download.openmmlab.com/mmclassification/v0/convnext-v2/convnext-v2-base_3rdparty-fcmae_in1k_20230104-8a798eaf.pth' # noqa image_size = (1024, 1024) model = dict( backbone=dict( _delete_=True, type='mmpretrain.ConvNeXt', arch='base', out_indices=[0, 1, 2, 3], drop_path_rate=0.4, layer_scale_init_value=0., # disable layer scale when using GRN gap_before_final_norm=False, use_grn=True, # V2 uses GRN init_cfg=dict( type='Pretrained', checkpoint=checkpoint_file, prefix='backbone.')), neck=dict(in_channels=[128, 256, 512, 1024]), ...

关键参数逐一说明:

  • _delete_=True:必须显式删除基础配置中的 ResNet50 骨干,否则会与mmpretrain.ConvNeXt产生字段冲突;
  • type='mmpretrain.ConvNeXt':骨干实现来自 MMPretrain,而非 mmdet 自身;
  • arch='base':选择 Base 规格的 ConvNeXt V2(通道数为 128/256/512/1024,与 V1 Base 的 128/256/512/1024 一致);
  • out_indices=[0, 1, 2, 3]:输出 4 个阶段的特征图,分别送入 FPN 的 4 个输入层;
  • drop_path_rate=0.4:随机深度(Stochastic Depth)丢弃率,该值在配置中标注了 TODO,属于未完全验证的超参;
  • layer_scale_init_value=0.这是 V2 的关键差异——使用 GRN 时禁用 Layer Scale 初始化。对比 V1 配置 mask-rcnn_convnext-t-p4-w7_fpn_amp-ms-crop-3x_coco.py 中layer_scale_init_value=1.0,可见 V2 用 GRN 取代了 Layer Scale 的角色;
  • use_grn=TrueV2 独有的 GRN 开关,是 ConvNeXt V2 相比 V1 的架构级新增模块(V1 配置中没有该字段),用于增强通道间特征竞争;
  • gap_before_final_norm=False:不在最后一个阶段之前做全局平均池化,保证输出的是空间特征图而非向量,适配检测/分割这类密集预测任务;
  • init_cfg:加载 FCMAE 在 ImageNet-1K 上预训练的权重,prefix='backbone.'用于剥离预训练权重中与检测任务无关的前缀,保证状态字典键名对齐。

由于骨干通道数从 ResNet50 的 256/512/1024/2048 变为 128/256/512/1024,FPN 的输入通道必须同步覆写:

neck=dict(in_channels=[128, 256, 512, 1024]),

推理设置:RCNN 分支使用 Soft-NMS

test_cfg=dict( rpn=dict(nms=dict(type='nms')), # TODO: does RPN use soft_nms? rcnn=dict(nms=dict(type='soft_nms')))

这里覆写了基础配置 mask-rcnn_r50_fpn.py 中的测试设置:RPN 阶段沿用普通 NMS,而 RCNN 阶段改用Soft-NMS以保留更多重叠目标;nms_pre=1000max_per_img=100score_thr=0.05mask_thr_binary=0.5等其余测试参数均继承自基础配置。

LSJ 数据增强流水线

LSJ(Large-Scale Jittering,源自 DETR/Sparse R-CNN 的大尺度抖动策略)是本配置的数据增强核心:

train_pipeline = [ dict(type='LoadImageFromFile', backend_args=_base_.backend_args), dict(type='LoadAnnotations', with_bbox=True, with_mask=True), dict( type='RandomResize', scale=image_size, ratio_range=(0.1, 2.0), keep_ratio=True), dict( type='RandomCrop', crop_type='absolute_range', crop_size=image_size, recompute_bbox=True, allow_negative_crop=True), dict(type='FilterAnnotations', min_gt_bbox_wh=(1e-2, 1e-2)), dict(type='RandomFlip', prob=0.5), dict(type='PackDetInputs') ]

各环节的作用:

  1. RandomResize:以 (1024, 1024) 为基准尺度,缩放在0.1x ~ 2.0x的宽大范围内随机进行(保持宽高比),这是 LSJ 名称中 "large-scale jittering" 的来源——极端缩小与极端放大交替出现,极大扩充了尺度多样性;
  2. RandomCrop:使用crop_type='absolute_range'crop_size=(1024, 1024)做绝对尺寸随机裁剪;recompute_bbox=True表示裁剪后重新计算标注框坐标,allow_negative_crop=True允许裁剪出不含任何目标的区域;
  3. FilterAnnotations:过滤掉裁剪后过小的标注(min_gt_bbox_wh=(1e-2, 1e-2));
  4. RandomFlip:0.5 概率水平翻转;
  5. PackDetInputs:将图像与标注打包为检测器输入格式。

LSJ 训练计划的参考实现还可以在 configs/common/lsj-200e_coco-instance.py 等公共配置中看到同类写法。

训练调度与学习率

train_dataloader = dict( batch_size=4, # total_batch_size 32 = 8 GPUS x 4 images num_workers=8, dataset=dict(pipeline=train_pipeline)) max_epochs = 36 train_cfg = dict(max_epochs=max_epochs) param_scheduler = [ dict( type='LinearLR', start_factor=0.001, by_epoch=False, begin=0, end=1000), dict( type='MultiStepLR', begin=0, end=max_epochs, by_epoch=True, milestones=[27, 33], gamma=0.1) ]
  • 单卡 batch size 为 4,注释明确说明总 batch size 32 由8 卡 × 4 张构成,复现官方指标时需保持该全局 batch 规模;
  • 训练 36 epoch(即 "3x" 计划):前 1000 次迭代以LinearLR(起始系数 0.001)做 warmup,之后在第 27、33 epoch 处分别将学习率衰减 10 倍(MultiStepLR,gamma=0.1)。

优化器:AMP 混合精度 + 分层学习率衰减

optim_wrapper = dict( type='AmpOptimWrapper', constructor='LearningRateDecayOptimizerConstructor', paramwise_cfg={ 'decay_rate': 0.95, 'decay_type': 'layer_wise', # TODO: sweep layer-wise lr decay? 'num_layers': 12 }, optimizer=dict( _delete_=True, type='AdamW', lr=0.0001, betas=(0.9, 0.999), weight_decay=0.05, )) default_hooks = dict(checkpoint=dict(max_keep_ckpts=1))

该优化器配置同时启用了两套关键机制:

其一,AMP 混合精度AmpOptimWrapper以自动混合精度(Automatic Mixed Precision)训练显著降低显存占用——这也解释了结果表中 22.5 GB 显存的关键来源。

其二,ConvNeXt 专用的分层学习率衰减constructor='LearningRateDecayOptimizerConstructor'指向 mmdet 内置构造器 mmdet/engine/optimizers/layer_decay_optimizer_constructor.py,其实现要点如下:

  • num_layers会被内部+2扩展为总层数(Base 骨干 12 个 block,即 14 层),decay_rate=0.95控制层间衰减幅度;
  • 参数按层号layer_id分组,第layer_id组的学习率为decay_rate ** (num_layers - layer_id - 1)乘以基础学习率,即越深的层学习率越高(该函数中lr_scale的计算见 layer_decay_optimizer_constructor.py);
  • 层号分配由get_layer_id_for_convnext(layer_wise 模式)或get_stage_id_for_convnext(stage_wise 模式)决定,两者均针对backbone.stagesbackbone.downsample_layers等 ConvNeXt 特有参数名做解析(见 layer_decay_optimizer_constructor.py),因此该构造器目前仅为 ConvNeXt 类骨干设计,换成其他骨干会直接抛出NotImplementedError
  • 权重衰减按参数形状分流:维度为 1 的参数、.biaspos_embedcls_token不施加 weight decay,其余参数统一使用weight_decay=0.05(见 layer_decay_optimizer_constructor.py);
  • default_hooksmax_keep_ckpts=1只保留最近一份 checkpoint,节省磁盘。

训练与测试:命令行实操

在安装好 mmdet、mmengine、mmpretrain 及各自依赖的前提下,可基于仓库标准工具脚本启动训练。8 卡分布式训练:

bash tools/dist_train.sh projects/ConvNeXt-V2/configs/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco.py 8

单卡训练:

python tools/train.py projects/ConvNeXt-V2/configs/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco.py

加载官方权重做推理评测:

python tools/test.py projects/ConvNeXt-V2/configs/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco.py \ https://download.openmmlab.com/mmdetection/v3.0/convnextv2/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco/mask-rcnn_convnext-v2-b_fpn_lsj-3x-fcmae_coco_20230113_110947-757ee2dd.pth

注意:tools/dist_train.shtools/train.pytools/test.py均为仓库根目录下 tools 的标准入口。由于该配置需要 8 卡 × batch 4 才能对齐官方 32 的全局 batch,显存不足时需同步调整 batch size 与学习率,否则指标会有偏差。

ConvNeXt V2 与 V1 配置对比:升级点一目了然

将本配置与官方 V1 代表配置 mask-rcnn_convnext-t-p4-w7_fpn_amp-ms-crop-3x_coco.py 对照,可清晰看出两代骨干在检测集成上的差异:

配置项ConvNeXt V1 (tiny)ConvNeXt V2 (base)
骨干类型mmpretrain.ConvNeXtmmpretrain.ConvNeXt
GRN 开关无该字段(V1 无 GRN)use_grn=True
Layer Scale 初始化layer_scale_init_value=1.0layer_scale_init_value=0.(使用 GRN 时禁用)
FPN 输入通道[96, 192, 384, 768][128, 256, 512, 1024]
分层 LR 衰减层数num_layers=6num_layers=12
预训练权重ImageNet-1K 监督(noema)FCMAE 自监督(ImageNet-1K)
数据增强MS crop(多尺度 + 随机裁剪)LSJ(0.1x~2.0x 大尺度抖动)
RCNN NMS默认 NMSSoft-NMS

从源码结构看,V1 与 V2 复用同一个mmpretrain.ConvNeXt类,差异完全由use_grnlayer_scale_init_value等参数驱动;而预训练范式的区别(监督 vs FCMAE 自监督)则体现在checkpoint_file指向的不同权重。这种"同构骨干 + 参数开关 + 不同预训练"的设计,使得在 MMDetection 中切换两代骨干只需修改少量配置行。

引用与总结

若在科研或工程中使用了该实现,请按论文规范引用:

@article{Woo2023ConvNeXtV2, title={ConvNeXt V2: Co-designing and Scaling ConvNets with Masked Autoencoders}, author={Sanghyun Woo, Shoubhik Debnath, Ronghang Hu, Xinlei Chen, Zhuang Liu, In So Kweon and Saining Xie}, year={2023}, journal={arXiv preprint arXiv:2301.00808}, }

总结而言,projects/ConvNeXt-V2 子项目以极低的接入成本,在 MMDetection 中复现了 ConvNeXt V2 的检测能力:FCMAE 自监督预训练权重由 MMPretrain 提供,use_grn=Truelayer_scale_init_value=0.两个开关完成了从 V1 到 V2 的架构升级,LSJ 增强、3x 计划、分层学习率衰减与 AMP 混合精度则共同支撑起 52.9 box AP / 46.4 mask AP 的官方结果。需要注意的是该结果仍属预发布版本,配置中残留的 drop_path_rate、RPN NMS 类型、layer-wise 衰减系数等 TODO 项在自定义复现时值得进一步验证与调优。更丰富的 ConvNeXt 检测配置(含 V1 的 tiny/small 变体、cascade Mask R-CNN 变体)可在 configs/convnext 中继续探索。

  • 人工智能
  • 计算机视觉
  • 深度学习
  • 模型评测

【免费下载链接】mmdetection

OpenMMLab Detection Toolbox and Benchmark

项目地址:https://gitcode.com/gh_mirrors/mm/mmdetection
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询