资讯动态

MMDetection新手避坑指南:环境搭建与自定义数据集训练全流程

发布时间:2026/10/17 4:32:45 来源:尧图企业网站定制
新手学目标检测十有八九都会卡在环境配置这一步。我也一样当年从跑通一个模型到真正理解整个流程前前后后折腾了快两周。后来帮几个刚入门的同学环境配置发现最耗时的根本不是代码本身而是MMDetection这套框架的依赖关系、版本匹配、数据格式。这东西文档写得不算差但信息太分散新手很容易迷失。所以这篇指南我不会去讲那些高大上的原理推导就聚焦一件事如何从零开始把你的电脑变成能跑 MMDetection 的环境并且成功训练一个自定义数据集上的目标检测模型。你可以把它看成一份带避坑注解的实操记录我会把每一步为什么这么做的原因也讲清楚这样你后面遇到问题才有能力自己排查而不是只会跟着命令敲。这一篇是整个系列的开篇先把地基打好——环境搭建、数据准备、配置修改和单卡训练跑通这几个环节我会尽量把你可能踩的坑都提前标出来。1. 为什么选MMDetection以及它在整个项目里的位置很多新手会问目标检测框架那么多为什么非要选 MMDetection我用过一次之后就基本放弃了自己手写训练循环原因很直接它把这些年目标检测领域的主流模型都实现了而且接口统一。你今天用 Faster R-CNN明天想试 DDQ不需要大改代码只需要换配置文件这种效率上的优势在科研或者快速做验证的时候特别明显。在开始动手之前我强烈建议你先想清楚一个问题你用它来做什么是课程实验、毕业设计还是某个具体项目的前期验证目的不同路径差别很大。比如课程实验可能只需要看懂某个模型的原理并跑通就行但如果是项目前期的可行性验证你很可能需要准备自己的数据集对训练策略做一些调整。这篇指南默认你属于后者——手头有一批自己的图片和标注想要尽快跑出一个像样的检测结果。MMDetection 在整个项目体系里承担的是训练和推理引擎的角色。你喂给它图片和标注它负责加载模型、计算损失、更新权重、输出预测结果。当然它也自带一些常用数据集的加载器比如 COCO、VOC但这些数据集要想完整下载下来体量不小对很多同学来说网速和硬盘都是问题。所以更现实的路径是先学会用自定义数据格式跑通流程后面再根据需求切换数据集这才是真正考验你对框架理解的地方。另外要说的一点是MMDetection 基于 PyTorch 开发所以你的深度学习基本功里PyTorch 的使用经验是前提。如果之前完全没接触过 PyTorch建议先把它的数据加载和训练循环大体过一遍不要求精通但至少要知道是怎么组织数据的。2. 版本匹配问题要提前弄清楚否则后面全是泪我见过太多同学卡在第一个晚上就是因为从官网随便复制了安装命令装完发现版本对不上报错信息千奇百怪。MMDetection 跟 PyTorch、CUDA 之间的版本耦合非常紧某一个版本不匹配轻则某一模块无法导入重则直接编译失败。2.1 CUDA、PyTorch 和 MMDetection 三者的三角关系先解释一下为什么要关注这个三角关系。MMDetection 的核心计算部分——比如 deformable convolution、ROI align 这些操作——是用 CUDA 扩展写的需要编译成 PyTorch 能调用的算子。PyTorch 本身又是基于特定 CUDA 版本编译的如果你系统里的 CUDA 驱动和 PyTorch 要求的版本差太远运行时会因为找不到对应设备上下文而报错甚至直接崩掉。具体到实操层面你不需要装整套 CUDA 工具包现代 PyTorch 的 pip 安装包会自带它需要的 CUDA 运行库你只需要保证显卡驱动版本足够新就行。而编译 MMDetection 扩展时需要使用与 PyTorch 匹配的 CUDA 工具链如果你的机器上已经装了好几个版本的 CUDA编译可能会因为 PATH 环境变量指向不对而失败。为了让你心里有数我给一个大致的匹配参考具体版本以官方文档为准但思路不变CUDA 版本PyTorch 安装方式示例备注CUDA 11.7pip install torch2.0.x 对应版本比较稳妥的组合CUDA 11.8pip install torch2.0.x 对应版本很多实验室服务器在用CUDA 12.1pip install torch2.1.x 对应版本新卡建议用这个我的建议是先选 PyTorch 版本再倒推 CUDA 要求。比如现在最新的 MMDetection 3.x 支持到 PyTorch 2.x那我就优先考虑 PyTorch 2.0 或 2.1然后根据这台机器上的显卡驱动选择对应的 CUDA 版本。如果你连驱动版本都不想折腾可以先用nvidia-smi查看自己驱动支持的最高 CUDA 版本然后向下兼容安装。2.2 一个可以直接照抄的安装顺序环境安装的顺序真的很重要。我强烈建议你不要在已经有多个 Python 环境的系统里裸装而是用 conda 创建虚拟环境把依赖隔离干净。# 1. 创建独立环境指定 Python 版本 conda create -n mmdet python3.9 -y conda activate mmdet # 2. 安装 PyTorch这里以 CUDA 11.8 为例请根据自己硬件选择 pip install torch2.0.1 torchvision0.15.2 --index-url https://download.pytorch.org/whl/cu118 # 3. 安装 mmcv关键一步要先装 mmcv再装 mmdet pip install mmcv2.0.1 -f https://download.openmmlab.com/mmcv/dist/cu118/torch2.0/index.html这里要详细说下步骤 3。MMDetection 依赖 MMCV而 MMCV 分为 CPU 版本和 CUDA 版本后者决定了你能不能使用那些需要编译的算子。上面的命令直接指定了cu118和torch2.0的预编译包这样免去了本地编译的等待时间。很多人会在这里踩坑pip install mmcv默认装的是纯 CPU 版训练时用到某些 CUDA 算子直接报不支持然后困惑半天。如果你好奇自己的 mmcv 是哪个版本可以进入 Python 环境执行import mmcv; print(mmcv.__version__)。环境弄好后再装 MMDetection 本体就很简单了。我建议从 GitHub 克隆源码并以开发模式安装这样你能随时看到模型定义和配置文件的源代码学习起来方便。而且以后自己改代码调试开发模式不会像 pip 安装那样难以追踪文件位置。git clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install -v -e .装完之后顺手验证一下python -c from mmdet.apis import inference_detector; print(ok)没有报错就说明核心模块能导入但注意这还不代表所有自定义算子都能用真正验证是要跑通一次模型前向。提示如果你用的是 Windows 系统编译 CUDA 算子的过程会更痛苦一些。建议要么尽早切到 WSL2要么直接装一个 Ubuntu 双系统。我个人的经验是WSL2 里跑这套东西基本没有什么障碍很多实验室的服务器也是 Linux 环境你用 WSL2 等于提前熟悉了服务器工作流。3. 准备自己的数据集格式转换是绕不开的一道坎环境只是敲门砖真正决定模型效果的是数据。很多新手犯的错误是拿 COCO 的某个小规模子集试试手就要部署但对于绝大多数个人项目一套自己的数据才是核心。这里我把一个标准的自定义数据集准备工作拆开讲。3.1 最省事的数据标注方案用现成工具生成 JSON目标检测数据集的标注格式五花八门LabelMe 出来的是 JSONLabelImg 出来的是 VOC 格式 XML还有 YOLO 的 txt 格式。MMDetection 原生支持 COCO 格式和 VOC 格式但我的建议是统一转入 COCO 格式因为它的信息结构最完整MMDetection 对它支持也最成熟。手动写一个格式转换脚本其实不难核心是把每张图片对应的标注框、类别、面积、iscrowd 这些字段整理成 COCO 的 JSON 结构。如果你用的是 LabelMe它有官方的转换脚本labelme2coco.py但那个脚本输出格式有时候字段不全我一般会自己改一版。真正重要的是图片和 JSON 的目录组织方式。对于 MMDetection我一般这样放data/ └── mydataset/ ├── annotations/ │ ├── train.json │ └── val.json ├── train/ │ ├── 000001.jpg │ └── ... └── val/ ├── 000001.jpg └── ...训练集和验证集在文件层面严格分开这个习惯能省掉很多后续数据筛选的麻烦。标注文件里images字段中的file_name需要写相对train/或val/目录的文件名这样在配置文件里只需写一次数据根路径。3.2 标注前要想好的几个细节问题我建议你在开始标注前花半小时想清楚这几个问题类别定义类别的 id 从 1 开始还是从 0 开始很多人标注时从 0 开始调试起来容易跟背景类搞混。我建议从 1 开始分配 id避免和背景混淆。类别数量尽量控制在几个到十几个不要一开始就追求细粒度分类。类别越细你需要的数据量越大模型犯错的可能性也越高。标注质量标注框尽量贴合目标边缘对于一些遮挡严重的目标宁可不要也不要标一个带大量背景噪音的框。在后续训练时这个因素直接决定模型学到的特征是否干净。数据集划分划分训练集和验证集时注意类别的分布要均衡最好抽样后统计一下每个类别在两边出现的次数差异不大否则你的验证结果会虚高或虚低。这些听起来琐碎但实际跑下来你就会发现80% 的调试时间都花在“为什么模型这个类检测不到”上而答案往往就藏在数据标注的某个细节里。4. 写一个最小可用的配置文件从内置配置改起MMDetection 的配置系统我是真的很喜欢用了很多别的框架最后还是觉得它这套最清晰。它把所有参数都用 Python 字典组织起来虽然有层级嵌套但读起来就像一张结构化的参数说明书。对于新手来说最稳妥的配置文件修改方法不是从零写而是找到官方提供的某个标准模型配置文件然后像改填空题一样替换成自己的参数。4.1 配置文件里最重要的几个板块先到mmdetection/configs目录下找一个简单的模型我第一次接触时选的是configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py。这个模型结构经典、参数量适中、训练周期也短用来做入门再合适不过。打开配置文件后_base_是首先要理解的东西它负责把更基础的配置串起来。MMDetection 对公共部分做了拆解比如数据预处理、模型结构、训练策略分别放在不同的文件里通过_base_引用。这意味着你不需要把每个参数都写在同一个文件里改的时候要追着引用路径走。重点需要修改的板块有这几个data_root数据集的根路径改成你自己的数据目录。metainfo类别列表。这里的名字和顺序一定要跟标注的类别 id 一一对应最好写个脚本核对一遍。train_dataloader、val_dataloader里面的dataset部分要指定data_root、ann_file、data_prefix。num_classes它通常在模型结构的roi_head或bbox_head里声明需要和类别数一致。optim_wrapper和train_cfg新手阶段先用默认参数后面再谈调优。我常说MMDetection 配置文件改起来不费脑子但很费眼睛。因为变量名特别全动不动就嵌套五六层新手很容易改错的地方。尤其是dataset里的data_prefix它有img和seg两个子字段检测任务只要设置img指向图片文件夹路径即可不要额外设置 seg否则会报找不到语义分割标注。4.2 类别数不匹配是所有新手都会经历的血泪事件我记得自己第一次训练自定义数据时觉得把num_classes写成类别数加 1加上背景就行了结果跑训练的时候 loss 直接变 NaN。后来排查了半天发现MMDetection 的num_classes只需要填真实目标类别数框架内部会自动加上背景类。这个细节非常折磨人。所以请在训练前养成一个新习惯写一个小脚本读取你配置文件里的num_classes和 JSON 标注里的类别 id 集合做一次全自动比对如果不匹配就抛异常。这在数据反复更新时能帮你省下大量无效训练时间。4.3 修改配置后检查有效性配置文件改完后不要急着开训。先加载配置做一次冒烟测试。MMDetection 提供了一种方式但最简单的是先尝试启动训练马上终止观察日志里有没有报配置错误。如果你是修改后不知道从哪里看起可以直接在 Python 里运行from mmengine.config import Config cfg Config.fromfile(your_config.py) print(cfg.model.roi_head.bbox_head.num_classes)打印出来确认数值跟你的预期一致再进行下一步。5. 单卡训练实操从启动命令到看懂日志当环境、数据、配置都就位后训练本身反而是最简单的一步。你要做的只是输入一条命令。但“能跑”和“跑得好”之间差的很远至少得学会看训练日志判断模型是在正常学习还是在原地踏步。5.1 训练启动命令假设你的显卡显存在 6GB 到 12GB 之间建议使用单卡训练。以我们改好的 Faster R-CNN 配置为例执行python tools/train.py configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py第一次训练如果你用的是自定义数据集大概率会碰到一个之前没预料到的问题训练迭代次数max_epochs还是 COCO 默认的 12但你的数据量可能只有几百张图跑 12 个 epoch 会导致严重的过拟合。所以我给你一个经验公式对新手来说很实用如果你的训练集只有几百张图先不要追求大的 batch size把它调到 4 或 8相应的学习率也要做缩放。学习率跟 batch size 成正比公式大致是new_lr base_lr * new_bs / default_bs。官方默认配置里通常 batch size 是 16学习率是 0.02。如果你 batch size 只有 4那么学习率应该相应调低到 0.005 左右。学习率设高了训练会出现明显的震荡loss 降不下去设低了模型学得太慢半天看不到效果。5.2 训练日志里到底要看什么训练开始后你会看到每过一个迭代就打印一条日志里面字段很多但新手重点关注这几个loss_rpn_cls和loss_rpn_bboxRPN 网络的分类和回归损失它们会在最初的迭代里快速下降如果持续不降优先怀疑数据是否有问题。loss_cls最终检测头的分类损失。过拟合的一个信号是它降得特别低然后在验证集上表现很差。loss_bbox检测框回归损失。这个值如果相对 loss_cls 一直很大可能是框的尺度分布差异太大或者标注框本身不准确需要回到数据层面排查。data_time从数据加载到送入 GPU 的时间。如果这个时间占比特别大通常意味着你的数据读取瓶颈在磁盘可以开启persistent_workersTrue或增加num_workers。真正有价值的习惯是记录每个 epoch 的训练损失和验证集上的指标变化曲线而不是只看最后一步的数值。因为训练过程中的震荡是正常的但方向应该在逐步走好。5.3 训练过程的阶段划分与可视化MMDetection 默认会在每个 epoch 结束时在验证集上做一次评估前提是你配置了val_evaluator。评估会输出coco/bbox_mAP、coco/bbox_mAP_50这样格式的指标。对新手来说先看bbox_mAP_50即可它表示交并比阈值 0.5 下的平均精度更贴近“到底框得准不准”的感觉。等到你对模型有信心了再关注bbox_mAP的细节。另外强烈建议把训练过程中的产物可视化出来。MMDetection 提供了一些工具但最简单的是训练脚本日志里已经自带了图片上的预测结果但你也可以在验证阶段保存一些图像并目测检查。这个步骤很重要因为数值指标再高如果预测框在图上明显偏移直觉上就不可信。我发现很多新手只盯着 mAP完全不看预测图结果模型学了奇怪的特异性关联都没发现。6. 推理与测试阶段用官方 demo 检验训练成果训练完手动停止之后模型权重会保存在work_dirs目录下。你要用它对新图片做预测其实不需要写复杂的代码MMDetection 的 inference 接口已经封装得很干净。但在这个环节我也遇到过不少问题逐一说明。6.1 单张图片推理的四种方式第一种方式是用现成脚本python demo/image_demo.py test.jpg \ configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \ work_dirs/xxx/epoch_12.pth第二种方式更灵活适合你在 Jupyter Notebook 里交互调试。我自己实践中更常用这一段代码因为可以自由控制保存逻辑from mmdet.apis import init_detector, inference_detector import mmcv model init_detector(your_config.py, work_dirs/best_coco_bbox_mAP_epoch_12.pth, devicecuda:0) result inference_detector(model, test.jpg) model.show_result(test.jpg, result, out_fileoutput.jpg, score_thr0.3)score_thr这个参数非常关键。低于这个置信度的框会被过滤掉。很多新手看到“检测结果一片混乱”其实就是score_thr设得太低模型把一堆低置信度的候选框全画出来了。我一般先设 0.5 看图再逐步降低找到一个平衡点。第一种方式适合快速看一眼结果第二种方式才是你以后写脚本、批量处理图片的基础一定要吃透。6.2 置信度阈值的选择不要只会抄 0.5 和 0.3这里多说一句很多人习惯性设 0.5但 0.5 未必适合所有场景。如果你的类别是“针孔瑕疵”这类小目标、低对比目标模型给出的置信度普遍偏低0.5 会把很多真目标过滤掉如果你的类别是“车辆”这类特征明显的大目标0.3 又会有很多误检框混进来。我建议你在验证集上用不同阈值跑一遍观察 recall 和 precision 的变化然后选一个让两者平衡的值。脚本不复杂但能帮你避免之后在部署阶段反复调参的尴尬。6.3 批量推理与结果保存假设你有一批图片需要跑模型并不建议在循环里反复init_detector这会重复加载模型权重很浪费时间。正确做法是初始化一次然后用for循环推理import glob from tqdm import tqdm model init_detector(config, weight, devicecuda:0) for img_path in tqdm(glob.glob(test_images/*.jpg)): result inference_detector(model, img_path) model.show_result(img_path, result, out_fileoutputs/ img_path.split(/)[-1], score_thr0.3)批量推理时输出目录记得提前建好。整个过程下来你会在目录里看到一张张标注好的结果图集中浏览一遍对模型的真实水平就能得到一个比较直观的认知。7. 常见问题速查表新手在基础阶段最常踩的坑我在帮别人调环境、跑训练的过程中发现新手遇到的问题高度集中。于是我把它们整理成一张速查表遇到同样的问题可以直接对照能省下很多搜索和猜测的时间。现象核心原因解决方案安装 mmcv 时报错找不到匹配版本CUDA 版本或 PyTorch 版本和 mmcv 预编译包不匹配先确认torch.version.cuda再按 mmcv 官网指引找对应链接导入 mmdet 时报No module named ‘mmcv._ext’mmcv 装成了 CPU 版使用带-f参数的预编译 CUDA 版 mmcv 重新安装训练开始后 loss 一直很大或为 NaN学习率太高或标注数据存在极端值调低学习率检查标注框是否越界验证时 mAP 为 0类别 id 不匹配或标注框没有归一化打印 JSON 中的 category_id 与配置文件对比显存不足batch size 太大或图片分辨率太高调低 batch size或使用梯度累积accumulative_counts参数训练很慢GPU 利用率低数据加载是瓶颈增加num_workers开启persistent_workers在同一张图上重复画满框score_thr 太低提高置信度阈值到 0.4-0.5推理结果完全没有检测框权重加载错误、类别数不匹配或测试图片本身没有目标检查 checkpoint 对应的配置文件是否一致这些问题的根源绝大多数不是代码 bug而是配置和数据层面的粗心。所以你排查时请不要一头扎进源码里读而是先检查自己的输入是否合理。除了这些常规问题我还有一个非常个人的排查技巧遇到看起来莫名其妙的现象先看数据。比如某个类在训练集里只出现了几次那模型学不到它是正常的。先用脚本把数据的类别分布打印出来手工数一遍图片数量很多“玄学”问题会瞬间变得合理起来。另外再分享一个调试思维上的建议不要指望一次训练就成功。目标检测模型的训练周期通常比较长但训练前的环境冒烟测试和数据校验一定要舍得花时间。也可以在一次训练中同时对多个候选学习率做小规模 test再选择最优的一个跑完整训练。虽然看起来多花了时间但整体上它是效率最高的一种方式。8. 这一篇的收尾下一篇的基础到这里你已经完成了从环境搭建、数据准备、配置修改、单卡训练到推理验证的全流程。不要小看这一整套流程它是以后做任何目标检测项目的地基。后面你会碰到更花哨的模型、更复杂的训练策略但本质上都离不开这套“数据-配置-训练-评估-推理”的骨架。我个人在实际操作中的体会是MMDetection 的学习曲线前期有点陡峭但只要完整跑通一次后面就会非常顺畅。很多操作甚至不需要记肌肉记忆会自动形成。如果这篇文章帮你少踩了几个坑那它的价值就达到了。下一篇我会重点讲一讲训练策略的调优思路包括学习率调度、数据增强策略的选择以及如何利用 MMDetection 的日志和可视化工具做更细致的分析。在那之前你可以先用自己的数据集多跑几个模型对比一下比如 Faster R-CNN、RetinaNet、SSD 各跑一遍感受一下它们在精度和速度上的差异这会为你后续选择模型提供非常直观的感知。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑