mmDetection 实战:Faster RCNN 训练自定义数据集的完整流程

📅 发布时间:2026/7/10 4:16:50 👁️ 浏览次数:
mmDetection 实战:Faster RCNN 训练自定义数据集的完整流程
1. 从零开始为什么选择 mmDetection 和 Faster RCNN如果你刚接触目标检测面对网上各种框架和网络模型可能会有点懵。我刚开始那会儿也一样试过不少工具踩过不少坑。今天我想跟你聊聊为什么对于训练自己的数据集mmDetection加上Faster RCNN是一个特别靠谱的起点。mmDetection 是一个基于 PyTorch 的开源目标检测工具箱由商汤和港中文的团队维护。它最大的好处就是“全”。里面集成了几十种主流的检测模型从经典的 RCNN 系列到 YOLO、RetinaNet再到 DETR 这类 Transformer 模型应有尽有。你不用再为了复现不同论文的模型去折腾各种不同的代码仓库和环境。更棒的是它把数据加载、模型构建、训练流程、评估指标这些繁琐的活儿都封装好了提供了一个高度统一的配置化系统。这意味着你换模型、换数据集很多时候只需要改一个配置文件而不是重写一大堆代码。这对于我们这些想要快速验证想法、把精力集中在业务数据上的开发者来说简直是福音。那为什么在这么多模型里我首推 Faster RCNN 来入门呢Faster RCNN 虽然不算是最新的模型但它可以说是两阶段目标检测的“基石”。它提出的区域提议网络RPN和 RoI Pooling 的思想影响深远。从学习的角度来说搞懂了 Faster RCNN你再去理解 Mask RCNN、Cascade RCNN 这些进阶模型会容易得多。从实践的角度看Faster RCNN 的精度和速度平衡得比较好在 mmDetection 里经过多年优化非常稳定。对于自定义数据集尤其是目标尺寸变化大、需要高定位精度的场景比如工业缺陷检测、遥感图像分析Faster RCNN 的表现通常很扎实不容易出幺蛾子。所以这套组合拳的定位很清晰mmDetection 提供稳定、易用的“战场”Faster RCNN 提供经久考验的“武器”。我们的任务就是学会如何在这个战场上用这件武器来训练我们自己的“士兵”——也就是自定义数据集。整个过程就像拼装一个精密的模型说明书配置文件已经给了零件模型组件都是现成的我们只需要按自己的图纸数据调整几个参数就能让它运转起来。接下来我就带你一步步走完这个拼装和调试的全过程。2. 实战第一步生成属于你的配置文件很多新手朋友拿到 mmDetection第一个迷惑操作就是我该直接改configs文件夹里那些现成的配置文件吗我的经验是千万别原生的配置文件是“模板”我们要做的是基于模板“复制”一份出来然后在副本上修改。这样做有两个巨大好处一是保持原始代码库的干净方便未来升级二是你的所有实验配置都有独立的记录不会互相覆盖管理起来清晰无比。那么怎么生成这个专属的配置文件呢核心思想是通过运行训练脚本并指定基础配置文件作为参数让系统自动生成一份副本到work_dirs目录下。这时候你可能会问我数据集还没准备好运行不是会报错吗没错会报错但没关系这个报错通常发生在数据加载阶段而在那之前配置文件已经成功复制出来了。我们就是要利用这个“报错”来达到目的。具体操作上我给你推荐两种方式你可以根据习惯选一种。2.1 方法一终端命令最直接打开你的终端Windows 用 CMD 或 PowerShellLinux/macOS 用 Terminal切换到你的 mmDetection 项目根目录。然后输入下面这条命令python tools/train.py configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py这条命令的意思是运行tools/train.py这个 Python 脚本并且告诉它这次训练要依据的配置是configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py。执行后你会看到程序开始启动加载模型然后大概率在尝试读取 COCO 数据集时失败并报错。别慌去看你的项目根目录下是不是多了一个work_dirs文件夹进去之后你会发现一个以当前日期时间命名的子文件夹例如faster-rcnn_r50_fpn_1x_coco/20241027_143022里面就躺着我们要的faster-rcnn_r50_fpn_1x_coco.py。这个文件就是你可以随意修改而不怕影响原版的“安全区”。2.2 方法二IDE运行配置方便调试如果你用的是 PyCharm、VSCode 这类集成开发环境直接在 IDE 里配置和运行会更方便特别是后面需要加断点调试的时候。以 PyCharm 为例你打开tools/train.py文件在代码编辑区的空白处右键找到“修改运行配置”或“Edit Configurations”。在弹出的窗口里你需要关注两个地方形参Parameters在这里填入你的基础配置文件路径比如F:\mmdetection-main\configs\faster_rcnn\faster-rcnn_r50_fpn_1x_coco.py请替换成你的实际绝对路径。运行目录Working directory这里要设置为你的 mmDetection 项目根目录的路径比如F:\mmdetection-main。设置好后点击“应用”和“确定”。然后你就可以直接在 IDE 里点击运行按钮那个绿色的小三角来执行train.py了。效果和终端命令一模一样同样会在work_dirs里生成你的配置文件副本。我个人在开发阶段更喜欢用这种方式因为查看日志、跟踪变量值都更直观。生成的新配置文件是你所有修改的起点请务必牢记它的位置。接下来我们就要准备“喂”给模型的数据了。3. 准备弹药自定义数据集的整理与放置数据是模型的粮食粮食没准备好再好的厨子也做不出饭。mmDetection 默认支持 COCO 和 VOC 等格式其中COCO 格式因为标注信息丰富、通用性极强成为了事实上的标准。所以我们的目标就是把你的图片和标注整理成 COCO 格式的样子。COCO 数据集的目录结构长这样你的数据集目录/ ├── annotations/ │ ├── instances_train2017.json │ ├── instances_val2017.json │ └── instances_test2017.json (可选) ├── train2017/ │ ├── 000001.jpg │ └── ... ├── val2017/ │ ├── 000002.jpg │ └── ... └── test2017/ (可选) ├── 000003.jpg └── ...关键点来了为了最大程度地减少对配置文件的修改我强烈建议你“模仿”这个结构。也就是说在你的 mmDetection 项目里或者任何一个你喜欢的目录创建一模一样的文件夹和文件名。图片把你的训练图片全部扔进train2017文件夹验证图片扔进val2017测试图片如果有扔进test2017。文件夹名字就叫train2017别自己起别的名这样可以“骗过”配置文件里写死的路径。标注文件这是重中之重。你需要将标注信息生成三个 JSON 文件instances_train2017.json,instances_val2017.json,instances_test2017.json然后放到annotations文件夹下。这个 JSON 文件的结构必须符合 COCO 格式。通常你可以使用labelme、CVAT等工具标注后用脚本转换成 COCO 格式。一个最简单的 JSON 里必须包含images图片信息列表、annotations标注框和类别列表、categories类别列表这三个核心字段。这里我分享一个我踩过的坑类别 ID 一定要从 1 开始而不是 0。在 COCO 格式中0 通常被保留为背景类。如果你的自定义类别是[‘cat’ ‘dog’ ‘person’]那么在categories列表里它们的id应该是 1 2 3。很多转换脚本默认从0开始会导致训练时类别错乱。务必检查你生成的 JSON 文件把数据和标注按这个结构放好你就完成了最繁琐的一步。这样做的好处是配置文件里关于数据集路径的部分通常是data_root和ann_file、img_prefix几乎不用动因为它们默认就是指向data/coco/下的这些文件夹名。你只需要在配置文件里把data_root改成你的数据集根目录路径就行了后面会讲到。4. 核心改造修改代码与配置以适配自定义类别数据准备好了现在要告诉模型“嘿别认 COCO 那 80 个类了来认识一下我的这几个新类别。” 这需要修改三个地方前两个是“全局定义”最后一个是“模型配置”。4.1 修改数据集元信息coco.py首先找到mmdet/datasets/coco.py这个文件。打开它你会看到文件顶部附近有类似这样的代码块CLASSES (‘person’ ‘bicycle’ ‘car’ … ‘toothbrush’) # COCO的80类 PALETTE [(220 20 60) (119 11 32) …] # 对应的颜色我们的任务是把这两行注释掉或者直接替换换成我们自己的。比如我的数据集是检测象棋棋子有6类CLASSES (‘king’ ‘queen’ ‘rook’ ‘bishop’ ‘knight’ ‘pawn’) # 颜色可以随便定义用于可视化只要是个RGB元组列表就行 PALETTE [(106 0 228) (119 11 32) (165 42 42) (0 0 192) (197 226 255) (153 153 153)]这个修改是告诉数据集加载器当读取 COCO 格式的标注文件时应该使用我们定义的类别名和对应的显示颜色。4.2 修改评估函数中的类别名class_names.py模型在测试和评估时需要知道类别名来输出结果。这个定义在mmdet/evaluation/functional/class_names.py文件中。打开这个文件找到coco_classes这个函数。注意这里通常有两处需要修改一处是函数内部的if dataset ‘coco’:判断分支下的返回列表另一处可能是在文件更靠前的位置定义的一个叫COCO_CLASSES的全局变量不同版本可能位置略有差异。你需要把这两处对应的 COCO 80类列表都替换成你的自定义类别列表。比如# 修改第一处可能在函数内 def coco_classes(): return [‘king’ ‘queen’ ‘rook’ ‘bishop’ ‘knight’ ‘pawn’] # 修改第二处可能在文件开头 COCO_CLASSES (‘king’ ‘queen’ ‘rook’ ‘bishop’ ‘knight’ ‘pawn’)务必仔细搜索并全部修改否则在模型验证或测试时可能会因为类别数量对不上而报错或者导致评估指标计算错误。4.3 修改模型配置你的新配置文件现在打开我们在work_dirs下生成的那个新配置文件。我们需要找到模型定义的部分修改分类头的输出通道数。使用编辑器的搜索功能查找num_classes。你可能会在好几个地方看到它比如roi_head下的bbox_head里。重点修改bbox_head下的num_classes。COCO 默认是 80你的数据集有几类就改成几。比如我的棋子有6类就改成model dict( type‘FasterRCNN’ … # 其他参数 roi_headdict( type‘StandardRoIHead’ bbox_headdict( type‘Shared2FCBBoxHead’ # 将这里的 num_classes 从 80 改为你的类别数 num_classes6 … # 其他参数 ) ) )有时候在rpn_head部分也可能有一个num_classes但那个通常指的是“前景”和“背景”两类一般不需要动保持为1。只改bbox_head里的即可。完成这三步模型就从认识80种通用物体“变身”为专精于你自定义任务的模型了。这个过程就像给一个博学的学者指定了一个新的研究方向他原有的知识架构特征提取能力还在但最后的输出层分类头已经为你定制好了。5. 启动训练参数调整与监控万事俱备只欠“开练”。回到终端或你的 IDE运行训练命令。但这次我们传入的不再是那个基础模板而是我们修改好的新配置文件python tools/train.py work_dirs/faster-rcnn_r50_fpn_1x_coco/faster-rcnn_r50_fpn_1x_coco.py如果你的数据集路径没有放在默认的data/coco下记得还需要在新配置文件中修改data_root。找到配置文件里data字典的部分类似这样data dict( traindict( type‘CocoDataset’ ann_file‘data/coco/annotations/instances_train2017.json’ img_prefix‘data/coco/train2017/’ …), valdict(…), testdict(…) )把里面的data/coco替换成你的数据集根目录的相对路径或绝对路径。比如你的数据放在F:/my_data/那就改成ann_file‘F:/my_data/annotations/instances_train2017.json’和img_prefix‘F:/my_data/train2017/’。对于大多数朋友尤其是用个人电脑训练的硬件资源是首要限制。在配置文件里你可以调整这些关键参数来适应你的机器学习率lr在optimizer配置部分。如果减少了batch_size通常需要同比降低学习率。例如batch_size从16减到4学习率大概除以4。批次大小batch_size在data字典下的samples_per_gpu。这个值直接取决于你的显卡显存。一张 8GB 的 GTX 1070跑 Faster RCNN 可能只能设batch_size2。如果爆显存OOM就调小它。训练轮数epochs在train_cfg里可能不直接叫epochs而是由runner类型的max_epochs控制。比如runnerdict(type‘EpochBasedRunner’ max_epochs12)就是训练12轮。对于小数据集几十轮可能就够了大数据集可能需要上百轮。训练开始后控制台会打印日志。更重要的信息在work_dirs下你本次实验的文件夹里。里面会生成*.log和*.log.json文本和 JSON 格式的详细训练日志。*.py你本次训练使用的完整配置文件备份。epoch_*.pth按周期保存的模型权重文件。latest.pth最新一次的权重文件方便恢复训练。我习惯一边训练一边用 TensorBoard 来可视化监控。mmDetection 默认支持 TensorBoard你只需要在配置文件中找到vis_backend和visualizer相关配置确保其启用新版本默认是开启的。然后在另一个终端运行tensorboard --logdir ./work_dirs打开浏览器就能看到损失曲线、学习率曲线、验证集精度等实时变化非常直观。通过观察损失是否平稳下降、精度是否稳步提升你能判断训练过程是否健康。6. 模型测试与结果可视化训练完成后我们肯定要看看模型在没见过的新图片上表现如何。使用tools/test.py脚本并指定测试用的配置文件和训练好的权重python tools/test.py \ work_dirs/faster-rcnn_r50_fpn_1x_coco/faster-rcnn_r50_fpn_1x_coco.py \ work_dirs/faster-rcnn_r50_fpn_1x_coco/epoch_12.pth \ --show-dir results_vis这条命令做了三件事1加载我们修改后的配置文件2加载训练好的第12个周期的模型权重3将测试集图片的预测结果带检测框的可视化图保存到results_vis文件夹。--show-dir参数非常实用它能让你直观地看到每张图片上模型的预测框和置信度方便快速定性评估模型好坏。除了看图片定量评估更重要。命令执行后控制台会打印出 COCO 风格的评价指标主要包括AP (Average Precision)在所有 IoU 阈值下的平均精度是核心指标。AP50IoU阈值为0.5时的精度可以理解为“宽松”的检测标准。AP75IoU阈值为0.75时的精度是“严格”的检测标准。AR (Average Recall)平均召回率。对于你的自定义任务重点关注mAPmean AP所有类别的 AP 平均值。这个值越高说明模型整体性能越好。你可以对比不同训练轮数比如epoch_6.pthvsepoch_12.pth的权重看看模型是否还有提升空间或者是否已经过拟合。如果结果不理想别灰心目标检测调参是常态。回头检查一下数据标注质量框得准不准、漏没漏标、类别是否平衡、训练轮数是否足够、学习率设置是否合适。有时候在自定义数据集上稍微调整一下锚框anchor的尺寸比例在配置文件rpn_head的anchor_generator部分让它更匹配你目标物体的大小也能带来不错的提升。这个过程需要一些耐心和实验但每解决一个问题你对模型和数据的理解就会更深一层。