MMDetection框架入门教程 ## 一、MMDetection 概述### 1.1 什么是 MMDetectionMMDetection 是一个基于 PyTorch 的开源目标检测工具箱由 OpenMMLab 团队开发和维护。它包含了丰富的主流目标检测、实例分割和全景分割算法支持 Faster R-CNN、Mask R-CNN、YOLO 系列、SSD、RetinaNet、DETR 等 20 种经典和现代模型。整个 OpenMMLab 家族除了 MMDetection还包含针对目标跟踪的 MMTracking、针对 3D 目标检测的 MMDetection3D 等开源项目它们都以 PyTorch 和 MMCV/MMEngine 为基础。### 1.2 框架核心优势- **模块化架构**将检测模型拆分为 Backbone、Neck、Head 等可独立替换的组件- **丰富的预训练模型库**提供 COCO、Pascal VOC 等数据集的预训练权重- **高效的训练和推理**支持多 GPU 训练和分布式训练- **易于扩展**提供清晰的接口和文档方便添加新算法、数据集和评估指标- **多硬件支持**兼容 NVIDIA GPU、AMD GPU 及 CPU 推理### 1.3 框架整体架构MMDetection 主要由 7 个核心部分组成| 部分 | 功能 ||------|------|| **apis** | 提供模型推理的高层 API || **structures** | 提供 bbox、mask、DetDataSample 等数据结构 || **datasets** | 支持目标检测、实例分割、全景分割的各种数据集 || **transforms** | 包含丰富的数据增强变换 || **models** | 检测器的核心组件包含 backbone、neck、dense_heads、roi_heads、losses 等 || **engine** | 运行时组件包含 runner、schedulers、optimizers、hooks || **evaluation** | 提供不同的模型评估指标 |## 二、环境搭建### 2.1 安装 Anaconda在搭建环境之前需要先安装 Anaconda 或 Miniconda 来管理 Python 环境。从官方网站下载并安装 Miniconda。### 2.2 创建并激活 Conda 环境bash# 创建环境Python 3.8conda create --name openmmlab python3.8 -y# 激活环境conda activate openmmlab### 2.3 安装 PyTorch根据你的 CUDA 版本从 PyTorch 官网选择合适的版本进行安装。以 CUDA 11.3 为例bashpip install torch1.12.1cu113 torchvision -f https://download.pytorch.org/whl/torch_stable.html**注意**安装 GPU 版本的 PyTorch 前需要通过 nvidia-smi 查看显卡的 CUDA 版本是否支持。### 2.4 安装 MMCVMMCV 是 OpenMMLab 的基础库提供了注册器、Runner、Hook 等核心功能。需要根据 PyTorch 和 CUDA 版本选择合适的 MMCV 版本。bashpip install -U openmimmim install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.12.0/index.html### 2.5 安装 MMDetection有两种安装方式**方式一直接安装适合快速使用**bashpip install mmdet**方式二源码安装适合开发或修改代码**bashgit clone https://github.com/open-mmlab/mmdetection.gitcd mmdetectionpip install -v -e .### 2.6 验证安装运行以下 Python 代码验证安装是否成功pythonfrom mmdet.apis import init_detector, inference_detectorprint(MMDetection installed successfully!)## 三、核心机制详解### 3.1 注册机制Registry注册机制是 MMDetection 管理模块的核心方式。在 MMCV 中注册器可以看作一个**从字符串到类或函数的映射表**——一个注册器中的类通常有相似的接口但实现不同的算法或支持不同的数据集。#### 3.1.1 Registry 的工作原理pythonfrom mmcv.utils import Registry# 创建一个注册器MODELS Registry(models)# 使用装饰器注册模块MODELS.register_module()class MyBackbone:def __init__(self, depth):self.depth depth注册的核心逻辑是将模块名称如 MyBackbone和模块类保存到注册器的 _module_dict 字典中。之后通过配置文件中的 type 字段如 typeMyBackbone框架就能自动找到对应的类并实例化。#### 3.1.2 常用的注册器MMDetection 中预定义了多个注册器来管理不同类型的模块| 注册器 | 管理内容 ||--------|----------|| DATASETS | 数据集类 || BACKBONES | 主干网络 || NECKS | Neck 组件 || HEADS | Head 组件分为 DenseHead 和 RoIHead || LOSSES | 损失函数 |#### 3.1.3 模块的调用通过配置字典可以实例化已注册的模块python# 配置字典cfg dict(typeMyBackbone, depth50)# 从注册器构建模块backbone MODELS.build(cfg)### 3.2 Hook 机制Hook钩子是一种在训练流程的特定节点插入自定义操作的机制。它允许用户在训练的不同阶段执行额外逻辑而无需修改核心训练代码。#### 3.2.1 Hook 的执行节点从训练开始到结束共有约 20 个节点可以插入 Hook。常见的插入点包括- 训练开始/结束前- 每个 Epoch 开始/结束前- 每个 Iteration 开始/结束前- 反向传播前后- 优化器更新前后#### 3.2.2 常用的内置 Hook| Hook 名称 | 功能 ||-----------|------|| CheckInvalidLossHook | 检查损失是否为 NaN || MemoryProfilerHook | 记录内存使用信息 || NumClassCheckHook | 检查类别数配置是否正确 || SyncNormHook | 同步批归一化 || YOLOXLrUpdaterHook | YOLOX 学习率更新策略 |#### 3.2.3 使用 Hook在配置文件中通过 custom_hooks 字段添加 Hookpythoncustom_hooks [dict(typeMemoryProfilerHook, interval50),]### 3.3 Runner执行器Runner 是控制训练流程的核心组件。MMDetection 中最常用的是 EpochBasedRunner它按 Epoch 组织训练循环。Runner 负责调度训练过程并在各个节点触发 Hook 的回调函数。## 四、配置文件配置文件是 MMDetection 的灵魂。通过配置文件用户可以在不修改代码的情况下组合不同的数据集、模型、训练策略和运行时设置。### 4.1 配置文件结构配置文件的三个基本组件类型位于 config/_base_ 目录下- **dataset**数据集配置- **model**模型配置- **default_runtime**运行时默认设置日志、检查点等- **schedule**训练策略配置### 4.2 配置继承MMDetection 支持配置文件的继承机制通过 _base_ 字段实现python# 继承基础配置_base_ ../faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py# 修改必要参数model dict(roi_headdict(bbox_headdict(num_classes5 # 修改为自定义数据集的类别数)))data dict(traindict(ann_filepath/to/train/annotation.json,img_prefixpath/to/train/images/))### 4.3 配置文件命名规范配置文件的命名遵循以下格式{model}_[model setting]_{backbone}_{neck}_[norm setting]_[misc]_[gpu x batch]_{schedule}_{dataset}例如faster_rcnn_r50_fpn_1x_coco.py### 4.4 查看完整配置可以通过以下命令查看经过继承合并后的完整配置bashpython tools/misc/print_config.py /PATH/TO/CONFIG.py### 4.5 通过命令行修改配置运行训练或测试时可以通过 --cfg-options 动态修改配置bash# 修改模型参数python tools/train.py config.py --cfg-options model.backbone.norm_evalFalse# 修改数据流程python tools/train.py config.py --cfg-options data.train.pipeline.0.typeLoadImageFromWebcam## 五、数据集### 5.1 使用标准数据集MMDetection 内置支持 COCO、Pascal VOC、Cityscapes 等多个标准数据集。使用标准数据集时只需在配置文件中指定数据集类型和标注文件路径即可。### 5.2 自定义数据集MMDetection 支持三种方式使用自定义数据集1. **转换为 COCO 格式**推荐2. **转换为中间格式**3. **实现新的 Dataset 类**#### 5.2.1 方法一转换为 COCO 格式将数据转换为 COCO 格式是最简单的方式。COCO 格式的 JSON 标注文件需要包含三个必要的键json{images: [{file_name: image001.jpg, height: 427, width: 640, id: 1}],annotations: [{bbox: [192.81, 224.8, 74.73, 33.43], category_id: 0, image_id: 1, id: 1}],categories: [{id: 0, name: cat},{id: 1, name: dog}]}数据转换完成后修改配置文件python_base_ ./cascade_mask_rcnn_r50_fpn_1x_coco.py# 定义类别classes (cat, dog)# 修改数据集配置data dict(traindict(typeCocoDataset,classesclasses,ann_filepath/to/train.json,img_prefixpath/to/train/images/),valdict(typeCocoDataset,classesclasses,ann_filepath/to/val.json,img_prefixpath/to/val/images/))# 修改模型类别数model dict(roi_headdict(bbox_headdict(num_classeslen(classes) # 2)))#### 5.2.2 方法二实现自定义 Dataset 类如果需要更复杂的自定义逻辑可以继承 CustomDataset 并重写相应方法pythonfrom mmdet.datasets import CustomDataset, DATASETSDATASETS.register_module()class MyDataset(CustomDataset):def load_annotations(self, ann_file):# 加载标注文件返回数据列表passdef get_ann_info(self, idx):# 返回第 idx 个样本的标注信息pass## 六、模型构建### 6.1 模型的模块化分解MMDetection 将一个完整的检测模型拆分为三个主要部分- **Backbone主干网络** 负责提取图像特征如 ResNet、VGG、EfficientNet 等- **Neck颈部网络** 负责特征融合和增强如 FPN、PAFPN、NASFPN 等- **Head头部网络** 负责最终的目标检测预测其中 Head 又分为两类- **DenseHead**用于单阶段检测器如 YOLO、RetinaNet位于 mmdet/models/dense_heads/- **RoIHead**用于两阶段检测器如 Faster R-CNN、Mask R-CNN位于 mmdet/models/roi_heads/### 6.2 自定义模型组件添加新的模型组件需要三个步骤**Step 1实现组件类并注册**python# mmdet/models/backbones/my_backbone.pyfrom mmdet.models import BACKBONESfrom mmengine.model import BaseModuleBACKBONES.register_module()class MyBackbone(BaseModule):def __init__(self, depth, *args, **kwargs):super().__init__(*args, **kwargs)# 初始化网络层def forward(self, x):# 前向传播return x**Step 2导入模块**在 mmdet/models/backbones/__init__.py 中添加pythonfrom .my_backbone import MyBackbone**Step 3在配置文件中使用**pythonmodel dict(backbonedict(typeMyBackbone,depth50),# ...)### 6.3 跨库调用模块MMEngine 的注册器支持跨软件包的模块构建。例如在 MMDetection 中使用 MMClassification 的 Backbonepython# 在配置中添加 custom_importscustom_imports dict(imports[mmcls.models], allow_failed_importsFalse)model dict(backbonedict(typemmcls.ConvNeXt, # 使用 mmcls 中的 ConvNeXt# ...))## 七、训练与测试### 7.1 训练模型完成数据准备和配置文件后使用训练脚本启动训练bash# 单 GPU 训练python tools/train.py configs/my_config.py# 多 GPU 训练bash tools/dist_train.sh configs/my_config.py 8### 7.2 测试与评估bash# 单 GPU 测试python tools/test.py configs/my_config.py work_dirs/epoch_12.pth --eval bbox# 多 GPU 测试bash tools/dist_test.sh configs/my_config.py work_dirs/epoch_12.pth 8 --eval bbox### 7.3 推理MMDetection 提供了高层 API 用于图像推理pythonfrom mmdet.apis import init_detector, inference_detectorimport mmcv# 初始化模型config_file configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.pycheckpoint_file checkpoints/faster_rcnn_r50_fpn_1x_coco.pthmodel init_detector(config_file, checkpoint_file, devicecuda:0)# 推理img mmcv.imread(demo/demo.jpg)result inference_detector(model, img)# 可视化from mmdet.apis import show_result_pyplotshow_result_pyplot(model, img, result)MMDetection 3.0 还提供了更简洁的 DetInferencer 接口pythonfrom mmdet.apis import DetInferencerinferencer DetInferencer(modelrtmdet_tiny_8xb32-300e_coco)result inferencer(demo/demo.jpg, showTrue)## 八、自定义扩展### 8.1 自定义损失函数pythonfrom mmdet.models import LOSSESimport torch.nn as nnLOSSES.register_module()class MyLoss(nn.Module):def __init__(self, reductionmean):super().__init__()self.reduction reductiondef forward(self, pred, target):# 计算损失loss ...return loss### 8.2 自定义数据预处理流程数据预处理通过 Pipeline 的方式组织pythonfrom mmcv.transforms import BaseTransformfrom mmdet.datasets import TRANSFORMSTRANSFORMS.register_module()class MyTransform(BaseTransform):def __init__(self, param):self.param paramdef transform(self, results):# 处理数据return results### 8.3 自定义 Hookpythonfrom mmengine.hooks import Hookclass MyCustomHook(Hook):def __init__(self, interval100):self.interval intervaldef after_train_iter(self, runner, batch_idx, data_batchNone, outputsNone):if batch_idx % self.interval 0:# 执行自定义操作pass在配置文件中使用pythoncustom_hooks [dict(typeMyCustomHook, interval50)]## 九、常见问题与实用技巧### 9.1 模块未注册问题如果遇到 KeyError: xxx is not in the registry 错误通常是因为模块文件没有被导入。需要在 __init__.py 中导入该模块或在配置中添加 custom_imports。### 9.2 查看完整配置bashpython tools/misc/print_config.py configs/my_config.py### 9.3 冻结主干网络在训练时冻结 Backbone 的参数pythonmodel dict(backbonedict(frozen_stages4 # 冻结前4个stage))### 9.4 使用预训练权重python# 在配置中指定预训练权重load_from path/to/pretrained.pth### 9.5 多尺度训练pythontrain_pipeline [dict(typeLoadImageFromFile),dict(typeResize, scale[(1333, 640), (1333, 800)], keep_ratioTrue),# ...]## 十、总结本文系统地介绍了 MMDetection 框架的各个方面1. **框架概述**了解了 MMDetection 的定位、核心优势和整体架构2. **环境搭建**掌握了从零搭建 MMDetection 开发环境的完整流程3. **核心机制**深入理解了注册器Registry和 Hook 两大核心机制的工作原理4. **配置文件**学会了配置文件的继承、修改和动态调整5. **数据集**掌握了使用标准数据集和自定义数据集的方法6. **模型构建**理解了模型的模块化分解和自定义组件的开发流程7. **训练与推理**学会了训练、测试和推理的完整操作8. **自定义扩展**了解了损失函数、数据预处理和 Hook 的自定义方法MMDetection 通过**模块化设计**和**配置驱动**的理念极大地降低了目标检测算法的开发门槛提高了代码复用率。无论是工业应用中的快速部署还是学术研究中的算法创新MMDetection 都是一个强大且实用的工具。