MMDetection实战:从标注到训练,完整构建自己的目标检测模型
MMDetection实战:从数据标注到模型部署的全流程指南
目标检测作为计算机视觉的核心任务之一,在工业质检、自动驾驶、安防监控等领域有着广泛应用。本文将带你从零开始,使用MMDetection框架完整构建一个目标检测系统。不同于简单的工具使用教程,我们将深入探讨每个环节的最佳实践和常见陷阱。
1. 数据准备:从原始素材到标准数据集
数据是目标检测模型的基石。一个高质量的数据集往往比复杂的模型结构更能提升最终效果。我们从数据采集开始,逐步构建符合MMDetection要求的数据集。
1.1 数据采集与清洗
在实际项目中,数据采集通常有以下几种方式:
- 自有数据:企业或研究机构积累的专有数据
- 公开数据集:如COCO、VOC、OpenImages等
- 网络爬取:需注意版权和合规性问题
- 合成数据:使用Blender、Unity等工具生成
提示:数据多样性比数量更重要。确保采集的数据覆盖了所有可能的应用场景和变化条件。
清洗数据时,重点关注:
- 重复或近似重复的图像
- 低质量图像(模糊、过曝、欠曝等)
- 不相关的内容(与目标检测任务无关的图像)
1.2 标注工具选择与使用
常见的标注工具对比:
| 工具名称 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| LabelImg | 中小规模项目 | 简单易用,支持PASCAL VOC格式 | 功能较基础 |
| CVAT | 大规模协作项目 | 功能全面,支持视频标注 | 部署较复杂 |
| Makesense.ai | 快速标注需求 | 在线工具,无需安装 | 功能有限 |
| VGG Image Annotator | 学术研究 | 支持多种标注格式 | 界面较旧 |
标注过程的关键注意事项:
- 标注框应紧密贴合目标边缘
- 对于遮挡目标,按可见部分标注
- 保持标注一致性(同一类别的不同实例应采用相同标准)
- 建立明确的标注规范文档
1.3 数据格式转换与验证
MMDetection支持多种数据格式,最常用的是COCO和PASCAL VOC。以下是将标注数据转换为COCO格式的Python代码示例:
import json from PIL import Image import os def convert_to_coco(images_dir, annotations_dir, output_path): categories = [{"id": 1, "name": "cat"}, {"id": 2, "name": "dog"}] images = [] annotations = [] annotation_id = 1 for img_file in os.listdir(images_dir): img_path = os.path.join(images_dir, img_file) img = Image.open(img_path) width, height = img.size image_id = len(images) + 1 images.append({ "id": image_id, "file_name": img_file, "width": width, "height": height }) # 假设每个图像有一个对应的XML标注文件 xml_file = os.path.join(annotations_dir, os.path.splitext(img_file)[0] + ".xml") # 解析XML文件并添加到annotations列表 # ... coco_dict = { "images": images, "annotations": annotations, "categories": categories } with open(output_path, 'w') as f: json.dump(coco_dict, f)数据验证是确保训练成功的关键步骤。建议使用以下检查清单:
- 所有图像都能正常打开
- 每个标注文件与图像文件匹配
- 标注坐标在图像范围内
- 类别标签一致且正确
2. 环境配置与MMDetection安装
2.1 硬件与基础软件准备
目标检测对计算资源要求较高,推荐配置:
- GPU:NVIDIA RTX 3090或A100(显存≥24GB为佳)
- CPU:多核处理器(如Intel i9或AMD Ryzen 9)
- 内存:≥32GB
- 存储:高速SSD(NVMe协议)
软件环境:
- 操作系统:Ubuntu 20.04 LTS(对深度学习支持最佳)
- CUDA:11.3(与GPU驱动版本匹配)
- cuDNN:8.2.1
- Python:3.8+
2.2 创建隔离的Python环境
使用conda创建和管理环境是最佳实践:
conda create -n mmdet python=3.8 -y conda activate mmdet2.3 安装PyTorch与MMCV
PyTorch安装(根据CUDA版本选择):
pip install torch==1.10.0+cu113 torchvision==0.11.1+cu113 torchaudio==0.10.0 -f https://download.pytorch.org/whl/cu113/torch_stable.htmlMMCV是MMDetection的基础库,推荐安装完整版:
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10.0/index.html2.4 安装MMDetection
从源码安装可以获得最新功能和定制能力:
git clone https://github.com/open-mmlab/mmdetection.git cd mmdetection pip install -r requirements/build.txt pip install -v -e .验证安装是否成功:
import mmdet print(mmdet.__version__)3. 模型选择与配置
3.1 MMDetection支持的模型架构
MMDetection提供了丰富的预训练模型,主要分为几大类:
两阶段检测器:
- Faster R-CNN系列
- Mask R-CNN
- Cascade R-CNN
一阶段检测器:
- RetinaNet
- FCOS
- YOLO系列
Anchor-Free检测器:
- CenterNet
- CornerNet
Transformer-based检测器:
- DETR
- Deformable DETR
3.2 根据需求选择合适模型
选择模型时需考虑以下因素:
- 精度要求:两阶段检测器通常精度更高
- 速度要求:一阶段检测器推理更快
- 硬件资源:大模型需要更多显存
- 数据集规模:小数据集适合使用预训练权重微调
对于大多数应用场景,Faster R-CNN是一个不错的起点。以下是比较流行的几种配置:
| 模型 | 输入尺寸 | mAP (COCO) | 推理速度 (FPS) | 显存占用 |
|---|---|---|---|---|
| Faster R-CNN R50-FPN | 1333×800 | 37.4 | 18 | 4.2GB |
| RetinaNet R50-FPN | 1333×800 | 36.5 | 23 | 3.8GB |
| YOLOv3 Darknet53 | 608×608 | 33.0 | 45 | 3.5GB |
| DETR R50 | 800×800 | 42.0 | 12 | 6.0GB |
3.3 配置文件详解
MMDetection使用配置文件系统管理模型的所有参数。一个典型的配置文件结构如下:
# 模型配置 model = dict( type='FasterRCNN', backbone=dict(...), neck=dict(...), rpn_head=dict(...), roi_head=dict(...), train_cfg=dict(...), test_cfg=dict(...) ) # 数据集配置 dataset_type = 'COCODataset' data = dict( samples_per_gpu=2, # 批大小 workers_per_gpu=2, # 数据加载线程数 train=dict(...), val=dict(...), test=dict(...) ) # 训练策略 optimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001) lr_config = dict(policy='step', step=[8, 11]) runner = dict(type='EpochBasedRunner', max_epochs=12)关键参数调整建议:
samples_per_gpu:根据GPU显存调整,越大训练越稳定但占用更多显存lr:学习率,通常从0.01开始,小数据集可适当减小max_epochs:训练轮数,取决于数据集大小和复杂度
4. 训练与优化
4.1 启动训练过程
基本训练命令:
python tools/train.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py --work-dir work_dirs/my_exp常用训练参数:
--resume-from:从检查点恢复训练--cfg-options:覆盖配置文件中的参数--no-validate:不进行验证(加快训练速度)
4.2 训练监控与可视化
MMDetection集成了多种可视化工具:
日志监控:
tail -f work_dirs/my_exp/20230201_123456.logTensorBoard集成:
tensorboard --logdir work_dirs/my_exp训练曲线分析:
from mmdet.utils import analyze_logs analyze_logs.plot_curve('work_dirs/my_exp/20230201_123456.log', keys=['loss_rpn_cls', 'loss_rpn_bbox'])
4.3 常见问题与解决方案
问题1:训练损失不下降
- 检查学习率是否合适
- 验证数据标注是否正确
- 尝试更简单的模型或更小的数据集进行调试
问题2:显存不足
- 减小
samplers_per_gpu - 使用梯度累积:
optimizer_config = dict(type='GradientCumulativeOptimizerHook', cumulative_iters=4)
问题3:过拟合
- 增加数据增强
- 添加正则化(如Dropout、权重衰减)
- 使用早停法
4.4 高级训练技巧
学习率预热:
lr_config = dict( policy='CosineAnnealing', warmup='linear', warmup_iters=500, warmup_ratio=0.001, min_lr_ratio=1e-5)自定义数据增强:
train_pipeline = [ dict(type='LoadImageFromFile'), dict(type='LoadAnnotations', with_bbox=True), dict(type='RandomFlip', flip_ratio=0.5), dict(type='RandomShift', shift_ratio=0.2), dict(type='PhotoMetricDistortion'), dict(type='Normalize', **img_norm_cfg), dict(type='Pad', size_divisor=32), dict(type='DefaultFormatBundle'), dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']), ]模型EMA(指数移动平均):
custom_hooks = [dict(type='EMAHook', momentum=0.0002, priority='ABOVE_NORMAL')]
5. 模型评估与部署
5.1 性能评估指标
目标检测的主要评估指标:
mAP(mean Average Precision):
- 综合考虑精度和召回率
- COCO标准下计算IoU从0.5到0.95,间隔0.05的平均值
推理速度:
- FPS(Frames Per Second)
- 端到端延迟
模型大小:
- 参数量
- 文件大小
评估命令:
python tools/test.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py work_dirs/my_exp/latest.pth --eval bbox5.2 模型导出与优化
导出为ONNX格式:
python tools/deployment/pytorch2onnx.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py work_dirs/my_exp/latest.pth --output-file model.onnx使用TensorRT加速:
python tools/deployment/onnx2tensorrt.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py model.onnx --trt-file model.trt模型量化:
model = dict( type='FasterRCNN', backbone=dict(...), # 添加量化配置 quantize=True, quantize_config=dict(type='DoReFa', bit_width=8))
5.3 部署方案选择
根据应用场景选择合适部署方式:
| 部署环境 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 云端服务器 | TorchScript | 保持灵活性 | 需要Python环境 |
| 边缘设备 | TensorRT | 极致性能 | 需要转换步骤 |
| 移动端 | MNN/TNN | 跨平台 | 功能有限 |
| 浏览器 | ONNX.js | 无需安装 | 性能较低 |
5.4 创建推理API
使用Flask创建简单的推理服务:
from flask import Flask, request, jsonify import mmcv from mmdet.apis import init_detector, inference_detector app = Flask(__name__) config_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py' checkpoint_file = 'work_dirs/my_exp/latest.pth' model = init_detector(config_file, checkpoint_file, device='cuda:0') @app.route('/predict', methods=['POST']) def predict(): if 'file' not in request.files: return jsonify({'error': 'no file uploaded'}), 400 file = request.files['file'] image = mmcv.imread(file.stream) result = inference_detector(model, image) # 将结果转换为JSON可序列化格式 preds = [] for i, bboxes in enumerate(result): for bbox in bboxes: preds.append({ 'label': model.CLASSES[i], 'score': float(bbox[4]), 'bbox': [float(x) for x in bbox[:4]] }) return jsonify({'predictions': preds}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)在实际项目中,我们发现数据质量对最终模型性能的影响往往超过模型架构的选择。一个常见的误区是过早地尝试复杂模型,而忽视了基础数据的整理和清洗工作。通过规范的标注流程和严格的质量控制,即使是相对简单的Faster R-CNN模型也能达到很好的效果。
