mmdetection v2.x 实战指南:环境搭建、配置修改与模型训练全流程

发布时间:2026/10/20 21:04:13
mmdetection v2.x 实战指南:环境搭建、配置修改与模型训练全流程 1. 为什么 mmdetection v2.x 至今仍值得投入精力如果你最近一两年才接触目标检测大概率一上来用的就是 mmdetection 3.x 甚至更新的版本。但只要你翻一翻 GitHub 上大量开源项目的 issue 区或者接手过一些两三年没动过的老仓库就会发现一个很现实的问题大量已经落地、已经调好参、已经跑出论文结果的工程仍然跑在 mmdetection v2.x 上。这不是大家懒得升级而是 v2.x 和 3.x 之间的配置体系、注册机制、API 命名差异非常大迁移成本高很多团队宁愿把 v2.x 的环境锁死。我自己就踩过这个坑。手头一个工业质检的检测项目模型是两年前基于 v2.x 训出来的权重、配置文件、数据增强流程全都是 v2.x 那一套。后来想直接迁到 3.x结果 config 里的img_norm_cfg、train_pipeline、optimizer_config这些字段全变了光是改配置就花了大半天最后发现某些自定义的 backbone 注册方式也不兼容。从那以后我就学乖了老项目就老老实实用 v2.x别折腾。所以这篇内容我想聊的就是 mmdetection v2.x 从环境搭建、数据准备、配置修改、模型训练到测试推理这一整条链路。它适合几类人一是接手了老检测项目、需要快速把模型跑起来的工程师二是想复现某些经典检测算法比如 Faster R-CNN、RetinaNet、Cascade R-CNN论文结果的学生三是想搞明白检测框架底层配置逻辑、不想只会调 API 的进阶学习者。我会尽量把每一步的“为什么这么做”讲清楚而不是甩一堆命令让你照抄。需要提前说明的是v2.x 的版本号跨度也不小从 2.0 到 2.28 之间有些细节有差异。我下面讲的内容以2.20 到 2.28 这个区间为主这也是当年最稳定、用得最广的一段。如果你用的是更早的 2.0 附近版本个别字段名可能略有出入我会在关键位置提醒。2. 环境搭建版本对齐是成败的第一步2.1 为什么 v2.x 的环境比想象中难搞很多人觉得装个检测框架不就是pip install一下的事吗在 mmdetection v2.x 这里真不是。它依赖三个核心组件PyTorch、MMCV、MMDetection三者之间有严格的版本对应关系。尤其是 MMCVv2.x 的 mmdet 对 mmcv 的版本卡得非常死装错一个小版本就可能出现ImportError或者某些算子找不到的问题。我见过太多人在这一步翻车随便装了个最新版 mmcv然后 mmdet 一跑就报ModuleNotFoundError: No module named mmcv._ext。这个报错本质上是 mmcv 的 C 扩展没编译好或者版本和 mmdet 不匹配。所以第一步不是急着装而是先查对应表。下面这张表是我根据实际使用经验整理的常见组合可以直接参考mmdetection 版本推荐 MMCV 版本推荐 PyTorchPython2.20mmcv-full 1.3.171.6 ~ 1.83.7 / 3.82.24mmcv-full 1.4.81.8 ~ 1.93.7 / 3.82.25mmcv-full 1.5.01.8 ~ 1.103.82.28mmcv-full 1.6.01.9 ~ 1.133.8 / 3.9注意这里的 mmcv 一定要用mmcv-full不要用精简版的mmcv。精简版没有编译 CUDA 算子训练时像RoIAlign、DeformConv这些会直接报错。2.2 用 conda 隔离环境的具体操作我强烈建议用 conda 建独立环境别在 base 环境里折腾。命令大致是这样conda create -n mmdet2x python3.8 -y conda activate mmdet2x # 安装 PyTorch注意 cudatoolkit 版本要和你显卡驱动匹配 conda install pytorch1.10.0 torchvision0.11.0 cudatoolkit11.3 -c pytorch -y # 安装 mmcv-full用官方提供的预编译包别自己编译太慢 pip install mmcv-full1.6.0 -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html这里有个关键点mmcv-full 的安装链接里cu113 和 torch1.10 必须和你实际装的 PyTorch、CUDA 版本对应。如果你装的是 cu102 的 PyTorch链接里的 cu113 就要改成 cu102否则装出来的 mmcv 和 PyTorch 的 CUDA 版本对不上运行时照样报错。装完 mmcv 之后再装 mmdetgit clone https://github.com/open-mmlab/mmdetection.git cd mmdetection git checkout v2.28.0 pip install -v -e .用-e是开发模式安装好处是你改了源码里的东西能直接生效方便调试。装完之后验证一下python -c import mmdet; print(mmdet.__version__)能打印出版本号就说明基本 OK 了。2.3 环境验证时最容易忽略的一步很多人装完就急着跑训练结果一跑就崩。我建议装完后先跑一个官方的推理 demo确认整个链路是通的python demo/image_demo.py demo/demo.jpg \ configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \ checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \ --device cuda:0如果这一步能正常输出带框的图片说明 PyTorch、CUDA、mmcv 的算子、mmdet 的推理流程全部正常。这一步能帮你排除掉 90% 的环境问题比直接上训练省心得多。如果这里就报错那问题一定在环境层面别往下走。3. 配置文件体系v2.x 的灵魂所在3.1 继承机制到底怎么工作的mmdetection v2.x 的配置系统是它最优雅也最容易让人懵的地方。它用的是继承 覆盖的机制。比如你想训一个 Faster R-CNN不需要从头写几百行配置只要这样_base_ ../faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py data_root data/my_dataset/ classes (defect_a, defect_b, defect_c) data dict( traindict( ann_filedata_root annotations/train.json, img_prefixdata_root train/, classesclasses), valdict( ann_filedata_root annotations/val.json, img_prefixdata_root val/, classesclasses), testdict( ann_filedata_root annotations/val.json, img_prefixdata_root val/, classesclasses))_base_指向的那个基础配置里已经定义好了模型结构、优化器、学习率策略、数据增强 pipeline 等等。你只需要覆盖数据集相关的部分就行。这种设计的好处是同一套模型结构可以复用到不同数据集上改的只是数据部分。但这里有个坑继承是递归的。基础配置本身可能还继承了更底层的配置比如faster_rcnn_r50_fpn_1x_coco.py又继承了faster_rcnn_r50_fpn.py和coco_detection.py。所以当你覆盖某个字段时要清楚它最终生效的是哪一层。我一般会先用工具把完整配置打印出来看python tools/misc/print_config.py configs/my_config.py这个命令会把继承合并后的完整配置输出非常有用。改配置之前先打印一遍能避免很多“我明明改了怎么没生效”的问题。3.2 类别数修改新手最容易翻车的地方自定义数据集最常见的问题就是类别数不对。COCO 是 80 类你的数据集可能是 3 类。这时候要改的地方不止一处model dict( roi_headdict( bbox_headdict(num_classes3)), # 如果是 RPN 相关的还要注意 )对于两阶段检测器Faster R-CNN、Cascade R-CNN要改的是roi_head.bbox_head.num_classes。对于单阶段检测器RetinaNet、FCOS改的是bbox_head.num_classes。改错了地方训练时不会报错但 loss 会一直不下降或者测试时框全乱。我踩过的一个典型坑改了num_classes但忘了改data里的classes元组结果训练能跑但测试时类别名对不上可视化出来的标签全是错的。所以这两个地方一定要同步改。3.3 学习率与 batch size 的联动调整v2.x 的默认配置基本都是8 卡、每卡 2 张图总 batch size 16对应的学习率是 0.02。如果你只有单卡batch size 变成 2那学习率也要按比例缩小new_lr base_lr * (new_batch_size / base_batch_size) 0.02 * (2 / 16) 0.0025这个线性缩放规则在检测任务里是经验法则不是绝对的但作为起点很靠谱。配置里这样写optimizer dict(typeSGD, lr0.0025, momentum0.9, weight_decay0.0001) lr_config dict( policystep, warmuplinear, warmup_iters500, warmup_ratio0.001, step[8, 11])step[8, 11]表示在第 8 和第 11 个 epoch 时学习率衰减。总 epoch 是 12。如果你数据量小可以适当减少总 epoch比如改成 6step 改成[4, 5]。提示warmup 在检测任务里很重要尤其是 batch size 小的时候。它能防止训练初期 loss 爆炸。别嫌麻烦保留它。4. 数据准备与格式转换的实操细节4.1 为什么推荐 COCO 格式而不是 VOCmmdetection v2.x 支持 VOC 和 COCO 两种主流格式但我强烈建议用COCO 格式。原因有三一是 COCO 格式的表达能力更强支持一张图多个类别、密集小目标二是 v2.x 里 COCO 格式的评估指标更全AP、AP50、AP75、APs、APm、APl三是很多数据增强和 pipeline 对 COCO 格式支持更好。COCO 格式的标注文件是一个大 JSON结构大致是{ images: [{id: 1, file_name: 001.jpg, width: 640, height: 480}], annotations: [ {id: 1, image_id: 1, category_id: 1, bbox: [x, y, w, h], area: 1234, iscrowd: 0} ], categories: [{id: 1, name: defect_a}] }注意bbox是左上角 x、y 加宽高不是右下角坐标。这个细节在转换脚本里最容易搞错一旦搞错框会整体偏移。4.2 从 VOC 转 COCO 的脚本思路如果你手头是 VOC 的 XML 标注可以用官方提供的转换脚本python tools/dataset_converters/pascal_voc.py \ data/VOCdevkit \ --out-dir data/coco_format \ --xml-dir annotations但官方脚本有时候不完全符合你的目录结构我一般会自己写一个小转换脚本核心逻辑就是遍历 XML解析出bndbox然后按 COCO 结构组装。这里有个经验转换完之后一定要抽样可视化几张图确认框的位置和类别都对。我见过太多人转换完直接开训训了半天发现框全是错的白白浪费算力。4.3 数据增强 pipeline 的取舍v2.x 默认的 train pipeline 大致是这样train_pipeline [ dict(typeLoadImageFromFile), dict(typeLoadAnnotations, with_bboxTrue), dict(typeResize, img_scale(1333, 800), keep_ratioTrue), dict(typeRandomFlip, flip_ratio0.5), dict(typeNormalize, **img_norm_cfg), dict(typePad, size_divisor32), dict(typeDefaultFormatBundle), dict(typeCollect, keys[img, gt_bboxes, gt_labels]), ]这里面有几个点值得说。Resize的img_scale(1333, 800)是 COCO 的标准设置短边缩到 800长边不超过 1333。如果你的图片本身很小比如工业质检里的 512x512可以适当调小比如(800, 480)这样能加快训练。Pad的size_divisor32是因为 FPN 有 5 层下采样总共 32 倍所以图片尺寸要能被 32 整除。这个不能省否则会报维度不匹配。如果你想加数据增强比如RandomCrop、PhotoMetricDistortion、MosaicYOLO 那套可以插在RandomFlip前后。但要注意增强不是越多越好。小数据集上堆太多增强反而会让模型学不到东西。我的经验是先跑 baseline看指标再针对性加增强。5. 模型训练从启动到收敛的完整过程5.1 单卡与多卡训练的启动方式单卡训练python tools/train.py configs/my_config.py \ --work-dir work_dirs/exp1 \ --seed 42多卡训练假设 4 卡bash tools/dist_train.sh configs/my_config.py 4 \ --work-dir work_dirs/exp1 \ --seed 42--seed这个参数我建议一定要加。检测任务对随机种子比较敏感固定种子能让你的实验可复现。--work-dir指定工作目录日志、权重、配置文件副本都会存在那里。5.2 训练日志怎么看训练启动后终端会不断输出日志格式大致是Epoch [1][50/500] lr: 2.5e-03, eta: 0:12:34, loss: 0.8234, loss_rpn_cls: 0.1234, ...重点看几个东西total loss 是否在下降、各分支 loss 是否合理、lr 是否符合预期。如果 total loss 一直震荡不降可能是学习率太大如果某个分支 loss 是 NaN可能是数据里有非法框比如宽高为 0。日志还会定期做验证输出bbox_mAP、bbox_mAP_50等指标。mAP_50 是最直观的指标一般训练几个 epoch 后应该能看到明显上升。5.3 训练中断了怎么办训练到一半机器崩了、或者你想加 epoch可以用--resume-from恢复python tools/train.py configs/my_config.py \ --resume-from work_dirs/exp1/latest.pth \ --work-dir work_dirs/exp1注意latest.pth是最近一个 epoch 的权重epoch_X.pth是每个 epoch 的存档。如果你要改总 epoch 数记得同时改total_epochs和lr_config.step否则学习率衰减的时机就乱了。实操心得我习惯把checkpoint_config里的interval设成 1每个 epoch 都存一次。虽然占空间但万一训练崩了损失最小。磁盘紧张的话设成 2 或 3 也行。6. 测试与推理把模型真正用起来6.1 用测试集评估模型训练完之后用tools/test.py在验证集或测试集上评估python tools/test.py configs/my_config.py \ work_dirs/exp1/latest.pth \ --eval bbox \ --out results.pkl--eval bbox表示评估检测框指标。--out把结果存成 pkl方便后续分析。如果只想看指标不加--out也行。评估结果会打印出类似Average Precision (AP) [ IoU0.50:0.95 | area all | maxDets100 ] 0.412 Average Precision (AP) [ IoU0.50 | area all | maxDets100 ] 0.623AP50 到 0.6 以上通常算可用0.7 以上算不错。当然具体看任务难度工业质检这种场景往往要求更高。6.2 单张图片推理与可视化评估指标是一回事实际看效果是另一回事。我一般会用demo/image_demo.py或者自己写个小脚本把预测结果画出来from mmdet.apis import init_detector, inference_detector import mmcv config_file configs/my_config.py checkpoint_file work_dirs/exp1/latest.pth model init_detector(config_file, checkpoint_file, devicecuda:0) result inference_detector(model, test.jpg) model.show_result(test.jpg, result, score_thr0.3, out_fileresult.jpg)score_thr0.3是置信度阈值低于这个值的框不显示。这个阈值要根据实际场景调召回优先就调低精度优先就调高。6.3 批量推理与结果导出实际部署时往往要批量处理图片这时候可以写个循环import os from mmdet.apis import init_detector, inference_detector model init_detector(config_file, checkpoint_file, devicecuda:0) img_dir data/test_images/ for img_name in os.listdir(img_dir): img_path os.path.join(img_dir, img_name) result inference_detector(model, img_path) # 把 result 里的 bbox、label、score 导出成 json 或 csv这里有个性能优化的点inference_detector每次都会重新做预处理如果图片尺寸一致可以自己组 batch 推理速度能快不少。不过 v2.x 的 API 对 batch 推理支持不算特别友好需要手动改一些东西这个后面可以单独展开。7. 常见问题与排查技巧实录7.1 训练相关的高频报错报错信息可能原因解决方法CUDA out of memorybatch size 太大或图片分辨率太高减小 batch size或调小img_scaleloss is NaN学习率过大或数据有非法框降低 lr检查标注里是否有宽高为 0 的框AssertionError: Thenum_classesof bbox_head should be consistent类别数没改对检查num_classes和classes是否一致KeyError: xxx is not in the models registry自定义模块没注册检查DETECTORS.register_module()是否加了mmcv._ext not foundmmcv 版本不对或没装 full 版重装对应版本的 mmcv-full7.2 指标不上升的排查思路如果训练 loss 在降但 mAP 不涨或者涨得很慢可以按这个顺序排查数据对不对抽样可视化几张训练图确认框和标签正确。学习率合不合适太大 loss 震荡太小收敛慢。可以画 lr-loss 曲线看。预训练权重加载了吗v2.x 默认会加载 ImageNet 预训练 backbone如果没加载收敛会慢很多。检查配置里的pretrained字段。评估流程对不对确认val的ann_file和img_prefix指向正确类别数一致。是不是过拟合了训练 mAP 高但验证 mAP 低说明过拟合加数据增强或正则化。7.3 几个我踩过的坑坑一改了配置但没生效。原因是配置继承层级太深我改的那一层被更底层覆盖了。解决办法就是前面说的先print_config看完整配置。坑二多卡训练时 batch size 理解错。v2.x 里samples_per_gpu是每卡的 batch size总 batch 是samples_per_gpu * num_gpus。我一开始以为samples_per_gpu是总数学习率调错了训了半天效果很差。坑三测试时忘了切 eval 模式。虽然tools/test.py会自动处理但自己写推理脚本时如果忘了model.eval()BN 层和 Dropout 会保持训练状态结果会不稳定。坑四权重文件加载了但没完全加载。用load_from加载预训练权重时如果类别数不一致分类头的权重会被跳过这是正常的。但如果你发现 backbone 的权重也没加载那就要检查 key 名是否匹配。8. 一些让训练更顺手的经验补充8.1 日志可视化v2.x 支持 TensorBoard配置里加一行log_config dict( interval50, hooks[ dict(typeTextLoggerHook), dict(typeTensorboardLoggerHook) ])然后tensorboard --logdir work_dirs/exp1就能看 loss 曲线和 mAP 曲线。曲线比数字直观得多尤其是判断过拟合和欠拟合的时候。8.2 学习率策略的选择v2.x 默认是 step 策略但 cosine 策略在很多任务上表现更平滑。改法lr_config dict( policyCosineAnnealing, warmuplinear, warmup_iters500, warmup_ratio0.001, min_lr_ratio1e-5)cosine 的好处是不用手动设 step学习率平滑下降对超参没那么敏感。我最近几个项目都换成了 cosine效果稳定。8.3 模型集成的简单做法如果单模型指标差一点可以试试 WBFWeighted Boxes Fusion或者简单的 NMS 集成。v2.x 本身不直接提供 WBF但可以自己写后处理。思路是把多个模型的预测结果合并用 WBF 算法融合。这个在竞赛里很常用能涨一两个点。8.4 导出 ONNX 的注意事项如果要把模型部署到其他平台可能需要导出 ONNXpython tools/deployment/pytorch2onnx.py \ configs/my_config.py \ work_dirs/exp1/latest.pth \ --output-file model.onnx \ --input-img test.jpg \ --shape 800 1333这里--shape要和训练时的输入尺寸匹配。导出后建议用onnxruntime验证一下输出是否和 PyTorch 一致避免部署时才发现问题。我个人在实际操作中的体会是mmdetection v2.x 虽然版本老但它的配置体系和训练流程设计得非常清晰把这一套吃透之后再去看 3.x 或者其他检测框架会发现底层逻辑是相通的。真正花时间的从来不是敲命令而是理解每个配置项背后的意图以及遇到问题时知道往哪个方向排查。最后再分享一个小技巧每次开新实验前把配置文件、日志、关键指标记到一个表格里实验多了之后回头看能快速定位哪种配置组合效果最好比凭记忆靠谱得多。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询