MMDetection 接入 timm 骨干网络实战:基于 TIMMBackbone 的 RetinaNet 配置与调试指南

MMDetection 接入 timm 骨干网络实战:基于 TIMMBackbone 的 RetinaNet 配置与调试指南 MMDetection 接入 timm 骨干网络实战基于 TIMMBackbone 的 RetinaNet 配置与调试指南【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetectionMMDetection 通过mmpretrain.TIMMBackbone这一封装类可以在检测模型中直接使用 PyTorch Image Modelstimm社区提供的海量预训练骨干网络。本指南以configs/timm_example/下的两个官方示例torchvision ResNet-50 与 EfficientNet-B1 RetinaNet为主线完整讲解依赖安装、配置逐行解析、FPN 通道对齐调试以及 Vision Transformer 等特殊骨干的兼容处理读完即可在 MMDetection 中替换任意 timm 骨干进行训练与推理。背景为什么在 MMDetection 中使用 timm 骨干timmPyTorchImageModels是一个汇集了大量图像模型、网络层、工具函数、优化器、调度器、数据加载与增强方案的模型库其目标是把各类 SOTA 模型与可复现 ImageNet 训练结果的能力整合到一起。timm 中维护着远超 MMDetection 内置 backbone 列表的预训练权重因此在检测框架里复用 timm 骨干是快速对比不同主干特征提取能力的常见做法。MMDetection 并未为每个 timm 模型单独实现一遍而是借助 OpenMMLab 的层级注册表Hierarchy Registry机制MMDet、MMPretrain原 MMClassification、MMSeg 的模型注册表都继承自 MMEngine 的根注册表因此各仓库可以直接使用彼此已实现的模块。MMPretrain 中提供了TIMMBackbone封装类它在内部调用 timm 的create_model与特征提取接口把 timm 模型包装成符合 MMDetection backbone 约定的模块。相关机制说明可见 docs/en/advanced_guides/how_to.md其中既有mmpretrain.MobileNetV3等 MMPretrain 原生骨干的用法也有mmpretrain.TIMMBackbone的完整示例。因此你需要在环境中额外安装两个包timm模型来源与mmpretrain提供TIMMBackbone封装与注册。安装额外依赖原文档给出的安装命令如下pip install dataclasses; python_version3.7 pip install timm pip install mmpretrain三点说明第一行带有python_version3.7环境标记仅在 Python 低于 3.7 的旧环境才会实际安装dataclasses现代 Python3.7会自动跳过不会造成副作用。timm是 PyTorch Image Models 本体提供所有模型结构与预训练权重下载。mmpretrain提供TIMMBackbone封装类必须安装若不安装配置中typemmpretrain.TIMMBackbone将无法解析。MMPretrain 的完整安装步骤可参考其官方文档的 Installation 章节。示例配置逐行解析configs/timm_example/目录下提供了两个可直接运行的示例完整代码见 retinanet_timm-efficientnet-b1_fpn_1x_coco.py 与 retinanet_timm-tv-resnet50_fpn_1x_coco.py二者均以_base_继承 RetinaNet-R50、COCO 检测数据集、1x 训练计划与默认运行配置再以最小改动替换 backbone_base_ [ ../_base_/models/retinanet_r50_fpn.py, ../_base_/datasets/coco_detection.py, ../_base_/schedules/schedule_1x.py, ../_base_/default_runtime.py ] # please install mmpretrain # import mmpretrain.models to trigger register_module in mmpretrain custom_imports dict( imports[mmpretrain.models], allow_failed_importsFalse) model dict( backbonedict( _delete_True, typemmpretrain.TIMMBackbone, model_nameefficientnet_b1, features_onlyTrue, pretrainedTrue, out_indices(1, 2, 3, 4)), neckdict(in_channels[24, 40, 112, 320])) # optimizer optim_wrapper dict(optimizerdict(lr0.01))各关键字段的作用如下配置项含义与取值说明custom_imports通过 MMEngine 的custom_imports机制在配置加载阶段导入mmpretrain.models从而触发其中的MODELS.register_module()注册逻辑使mmpretrain.TIMMBackbone等类型名可用allow_failed_importsFalse表示导入失败直接报错。这一写法同样适用于引入其他自定义模块见 docs/en/advanced_guides/customize_models.md。_delete_True覆盖继承规则删除_base_中retinanet_r50_fpn.py定义的ResNetbackbone 字段避免新旧键合并残留详见 docs/en/advanced_guides/customize_models.md。typemmpretrain.TIMMBackbone类型名中的mmpretrain指明实现位于 MMPretrain 仓库TIMMBackbone是该仓库中封装 timm 的 backbone 类名。model_nameefficientnet_b1指定 timm 中的模型名称另一个示例使用tv_resnet50即加载 torchvision 权重的 ResNet-50。可换成任意 timm 支持的模型名。features_onlyTrue让 backbone 仅输出特征图feature map而非分类 logits这是检测场景必需的开关对应 timm 的features_only特征提取模式。pretrainedTrue自动加载该模型在 timm 中的预训练权重。out_indices(1, 2, 3, 4)指定输出第 1 到第 4 个阶段的特征图EfficientNet-B1 共 5 个 stage取后 4 个作为 FPN 输入。neckdict(in_channels[24, 40, 112, 320])必须与 backbone 实际输出通道数一致EfficientNet-B1 第 1~4 个输出 stage 的通道数分别为 24、40、112、320。optim_wrapper.optimizer.lr0.01覆盖_base_中 1x 计划默认的 0.02更换 backbone 后参数量与收敛特性改变示例统一将学习率下调为 0.01。两个示例的差异集中在 backbone 部分tv_resnet50版本不显式修改neck.in_channels因为其输出通道 [256, 512, 1024, 2048] 恰好与_base_中 FPN 默认值一致而 EfficientNet-B1 版本必须按上表改写。继承的_base_配置RetinaNet 全貌示例配置只覆盖了 backbone 与 neck 的少量字段其余结构全部来自 configs/base/models/retinanet_r50_fpn.py理解继承内容有助于排查问题数据预处理器DetDataPreprocessorImageNet 均值/方差 [123.675, 116.28, 103.53] 与 [58.395, 57.12, 57.375]bgr_to_rgbTrue、pad_size_divisor32。检测头RetinaHeadnum_classes80、4 层 stacked conv、256 维 feat_channelsanchor 由AnchorGenerator生成octave_base_scale4、scales_per_octave3、ratios[0.5, 1.0, 2.0]、strides[8, 16, 32, 64, 128]分类用FocalLossgamma2.0、alpha0.25回归用L1Loss。训练/测试设置MaxIoUAssignerpos/neg IoU 阈值 0.5/0.4PseudoSamplerFocal loss 的配套采样器测试阶段nms_pre1000、score_thr0.05、NMS IoU 阈值 0.5、max_per_img100。数据侧继承 configs/base/datasets/coco_detection.pyCocoDataset、data_rootdata/coco/、train/val 的 pipelineResize 1333×800、RandomFlip、PackDetInputs以及CocoMetric评测配置训练计划继承 configs/base/schedules/schedule_1x.pyEpochBasedTrainLoop共 12 epochs、500 步LinearLRwarmup、milestones [8, 11] 的MultiStepLR、SGDmomentum0.9、weight_decay0.0001以及auto_scale_lr dict(enableFalse, base_batch_size16)的自动学习率缩放设定。关键调试要点对齐 out_channels 与 out_strides原文档强调具体输出哪些特征图取决于所选的 backbone。tim 中不同模型的 stage 划分、各 stage 输出通道数与下采样倍数stride各不相同因此替换骨干后必须验证以下两项并在必要时修改配置backbone out_channels输出通道数训练日志会打印 backbone 各输出层的通道数需将其与model.neck.in_channels对齐。例如 EfficientNet-B1 输出 [24, 40, 112, 320]配置中neck.in_channels必须同步改为这四个数。backbone out_strides输出步长影响 FPN 的start_level与 anchor 的strides设置。若更换后的 backbone 下采样节奏与默认 ResNetstride 4 起步、逐级 ×2不同需相应调整model.neck.start_level与model.backbone.out_indices在 configs/base/models/retinanet_r50_fpn.py 中可看到默认 FPN 的start_level1、add_extra_convson_input、num_outs5。简言之先跑一个短训练或直接查看日志中的 backbone 结构信息再回头核对out_indices与in_channels这是替换 timm 骨干时最常遇到的坑。特殊情形Vision Transformer 骨干与 NumClassCheckHookMMDetection 默认启用NumClassCheckHook注册与实现见 mmdet/engine/hooks/num_class_check_hook.py该 Hook 在before_train_epoch与before_val_epoch时遍历模型中所有含num_classes属性的模块断言其数值与dataset.metainfo[classes]的长度一致用于提前发现类别数不匹配的配置错误。问题在于部分Vision Transformer 模型不支持features_onlyTrue即无法通过 timm 特征提取接口直接产出多尺度特征图这类模型在 Hook 检查阶段可能因特征行为不符合预期而报错。针对此类 backbone原文档给出的处理方法是在配置中加入custom_hooks []显式清空默认 Hook 列表从而禁用NumClassCheckHook使训练流程得以继续。同时要理解该 Hook 的检查前提它要求数据集metainfo中设置classes字段且必须是 tuple 而非字符串若classes缺失则只输出 warning。因此即便不禁用 Hook为自定义数据集正确声明classes也是规范做法。训练、测试与推理仓库提供了标准入口脚本tools/train.py、tools/test.py 以及 demo/image_demo.py配置替换完成后即可按 MMDetection 通用流程使用# 训练单卡EfficientNet-B1 示例 python tools/train.py configs/timm_example/retinanet_timm-efficientnet-b1_fpn_1x_coco.py # 多卡分布式训练 bash tools/dist_train.sh configs/timm_example/retinanet_timm-efficientnet-b1_fpn_1x_coco.py 8 # 使用训练好的 checkpoint 在 COCO val 上评测 python tools/test.py configs/timm_example/retinanet_timm-efficientnet-b1_fpn_1x_coco.py checkpoint路径 # 单图推理 python demo/image_demo.py demo/demo.jpg configs/timm_example/retinanet_timm-efficientnet-b1_fpn_1x_coco.py checkpoint路径需要说明更换 backbone 后由于预训练分布、参数量与输出结构的变化直接沿用 1x 计划并不保证与内置 ResNet 基线同等精度更稳妥的做法是以此配置为起点调整lr、out_indices与 FPN 相关参数进行针对性实验。两个示例当前记录的box AP尚待补齐属正常的示例占位状态。结果与模型RetinaNetBackboneStyleLr schdMem (GB)Inf time (fps)box APConfigDownloadR-50tv_resnet50pytorch1xconfigEfficientNet-B1-1xconfig引用若在研究中引用 timm 或本示例可使用如下 BibTeXmisc{rw2019timm, author {Ross Wightman}, title {PyTorch Image Models}, year {2019}, publisher {GitHub}, journal {GitHub repository}, doi {10.5281/zenodo.4414861}, howpublished {\url{https://github.com/rwightman/pytorch-image-models}} }小结在 MMDetection 中使用 timm 骨干的本质是通过mmpretrain.TIMMBackbone复用另一个 OpenMMLab 仓库的封装因此安装mmpretrain与timm是前提custom_imports触发注册、_delete_True覆盖_base_中的 backbone 是配置骨架而根据日志中的out_channels/out_strides对齐neck.in_channels与backbone.out_indices是调试的核心环节遇到不支持features_onlyTrue的 Vision Transformer 时用custom_hooks []禁用NumClassCheckHook即可绕过检查。以 retinanet_timm-efficientnet-b1_fpn_1x_coco.py 为模板你可以在 RetinaNet 乃至其他检测器上自由尝试 timm 社区的各种骨干。【免费下载链接】mmdetectionOpenMMLab Detection Toolbox and Benchmark项目地址: https://gitcode.com/gh_mirrors/mm/mmdetection创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考