Commit 20e33356 authored by luopl's avatar luopl
Browse files

init

parents
Pipeline #1587 canceled with stages
# 精度评测(待更新)
本教程收集了任何如何使用 MMDetection 进行 xxx 的答案。 如果您遇到有关`如何做`的问题及答案,请随时更新此文档!
## 使用 MMPretrain 的骨干网络
MMDet、MMPretrain、MMSeg 中的模型注册表都继承自 MMEngine 中的根注册表,允许这些存储库直接使用彼此已经实现的模块。 因此用户可以在 MMDetection 中使用来自 MMPretrain 的骨干网络,而无需实现MMPretrain 中已经存在的网络。
### 使用在 MMPretrain 中实现的骨干网络
假设想将 `MobileNetV3-small` 作为 `RetinaNet` 的骨干网络,则配置文件如下。
```python
_base_ = [
'../_base_/models/retinanet_r50_fpn.py',
'../_base_/datasets/coco_detection.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
# please install mmpretrain
# import mmpretrain.models to trigger register_module in mmpretrain
custom_imports = dict(imports=['mmpretrain.models'], allow_failed_imports=False)
pretrained = 'https://download.openmmlab.com/mmclassification/v0/mobilenet_v3/convert/mobilenet_v3_small-8427ecf0.pth'
model = dict(
backbone=dict(
_delete_=True, # 将 _base_ 中关于 backbone 的字段删除
type='mmpretrain.MobileNetV3', # 使用 mmpretrain 中的 MobileNetV3
arch='small',
out_indices=(3, 8, 11), # 修改 out_indices
init_cfg=dict(
type='Pretrained',
checkpoint=pretrained,
prefix='backbone.')), # mmpretrain 中骨干网络的预训练权重含义 prefix='backbone.',为了正常加载权重,需要把这个 prefix 去掉。
# 修改 in_channels
neck=dict(in_channels=[24, 48, 96], start_level=0))
```
### 通过 MMPretrain 使用 TIMM 中实现的骨干网络
由于 MMPretrain 提供了 Py**T**orch **Im**age **M**odels (`timm`) 骨干网络的封装,用户也可以通过 MMPretrain 直接使用 `timm` 中的骨干网络。假设想将 [`EfficientNet-B1`](../../../configs/timm_example/retinanet_timm-efficientnet-b1_fpn_1x_coco.py) 作为 `RetinaNet` 的骨干网络,则配置文件如下。
```python
# https://github.com/open-mmlab/mmdetection/blob/main/configs/timm_example/retinanet_timm_efficientnet_b1_fpn_1x_coco.py
_base_ = [
'../_base_/models/retinanet_r50_fpn.py',
'../_base_/datasets/coco_detection.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
# please install mmpretrain
# import mmpretrain.models to trigger register_module in mmpretrain
custom_imports = dict(imports=['mmpretrain.models'], allow_failed_imports=False)
model = dict(
backbone=dict(
_delete_=True, # 将 _base_ 中关于 backbone 的字段删除
type='mmpretrain.TIMMBackbone', # 使用 mmpretrain 中 timm 骨干网络
model_name='efficientnet_b1',
features_only=True,
pretrained=True,
out_indices=(1, 2, 3, 4)), # 修改 out_indices
neck=dict(in_channels=[24, 40, 112, 320])) # 修改 in_channels
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
```
`type='mmpretrain.TIMMBackbone'` 表示在 MMDetection 中使用 MMPretrain 中的 `TIMMBackbone` 类,并且使用的模型为` EfficientNet-B1`,其中 `mmpretrain` 表示 MMPretrain 库,而 `TIMMBackbone ` 表示 MMPretrain 中实现的 TIMMBackbone 包装器。
关于层次注册器的具体原理可以参考 [MMEngine 文档](https://mmengine.readthedocs.io/zh_cn/latest/tutorials/config.md#跨项目继承配置文件),关于如何使用 MMPretrain 中的其他 backbone,可以参考 [MMPretrain 文档](https://mmpretrain.readthedocs.io/en/latest/user_guides/config.html)
## 使用马赛克数据增强
如果你想在训练中使用 `Mosaic`,那么请确保你同时使用 `MultiImageMixDataset`。以 `Faster R-CNN` 算法为例,你可以通过如下做法实现:
```python
# 直接打开 configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py ,增添如下字段
data_root = 'data/coco/'
dataset_type = 'CocoDataset'
img_scale=(1333, 800)
train_pipeline = [
dict(type='Mosaic', img_scale=img_scale, pad_val=114.0),
dict(
type='RandomAffine',
scaling_ratio_range=(0.1, 2),
border=(-img_scale[0] // 2, -img_scale[1] // 2)), # 图像经过马赛克处理后会放大4倍,所以我们使用仿射变换来恢复图像的大小。
dict(type='RandomFlip', prob=0.5),
dict(type='PackDetInputs'))
]
train_dataset = dict(
_delete_ = True, # 删除不必要的设置
type='MultiImageMixDataset',
dataset=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_train2017.json',
img_prefix=data_root + 'train2017/',
pipeline=[
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True)
],
filter_empty_gt=False,
),
pipeline=train_pipeline
)
data = dict(
train=train_dataset
)
```
## 在配置文件中冻结骨干网络后在训练中解冻骨干网络
如果你在配置文件中已经冻结了骨干网络并希望在几个训练周期后解冻它,你可以通过 hook 来实现这个功能。以用 ResNet 为骨干网络的 Faster R-CNN 为例,你可以冻结一个骨干网络的一个层并在配置文件中添加如下 `custom_hooks`:
```python
_base_ = [
'../_base_/models/faster-rcnn_r50_fpn.py',
'../_base_/datasets/coco_detection.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]
model = dict(
# freeze one stage of the backbone network.
backbone=dict(frozen_stages=1),
)
custom_hooks = [dict(type="UnfreezeBackboneEpochBasedHook", unfreeze_epoch=1)]
```
同时在 `mmdet/core/hook/unfreeze_backbone_epoch_based_hook.py` 当中书写 `UnfreezeBackboneEpochBasedHook`
```python
from mmengine.model import is_model_wrapper
from mmengine.hooks import Hook
from mmdet.registry import HOOKS
@HOOKS.register_module()
class UnfreezeBackboneEpochBasedHook(Hook):
"""Unfreeze backbone network Hook.
Args:
unfreeze_epoch (int): The epoch unfreezing the backbone network.
"""
def __init__(self, unfreeze_epoch=1):
self.unfreeze_epoch = unfreeze_epoch
def before_train_epoch(self, runner):
# Unfreeze the backbone network.
# Only valid for resnet.
if runner.epoch == self.unfreeze_epoch:
model = runner.model
if is_module_wrapper(model):
model = model.module
backbone = model.backbone
if backbone.frozen_stages >= 0:
if backbone.deep_stem:
backbone.stem.train()
for param in backbone.stem.parameters():
param.requires_grad = True
else:
backbone.norm1.train()
for m in [backbone.conv1, backbone.norm1]:
for param in m.parameters():
param.requires_grad = True
for i in range(1, backbone.frozen_stages + 1):
m = getattr(backbone, f'layer{i}')
m.train()
for param in m.parameters():
param.requires_grad = True
```
## 获得新的骨干网络的通道数
如果你想获得一个新骨干网络的通道数,你可以单独构建这个骨干网络并输入一个伪造的图片来获取每一个阶段的输出。
`ResNet` 为例:
```python
from mmdet.models import ResNet
import torch
self = ResNet(depth=18)
self.eval()
inputs = torch.rand(1, 3, 32, 32)
level_outputs = self.forward(inputs)
for level_out in level_outputs:
print(tuple(level_out.shape))
```
以上脚本的输出为:
```python
(1, 64, 8, 8)
(1, 128, 4, 4)
(1, 256, 2, 2)
(1, 512, 1, 1)
```
用户可以通过将脚本中的 `ResNet(depth=18)` 替换为自己的骨干网络配置来得到新的骨干网络的通道数。
# MMDetection 中训练 Detectron2 的模型
用户可以使用 `Detectron2Wrapper` 从而在 MMDetection 中使用 Detectron2 的模型。
我们提供了 [Faster R-CNN](../../../configs/misc/d2_faster-rcnn_r50-caffe_fpn_ms-90k_coco.py),
[Mask R-CNN](../../../configs/misc/d2_mask-rcnn_r50-caffe_fpn_ms-90k_coco.py)[RetinaNet](../../../configs/misc/d2_retinanet_r50-caffe_fpn_ms-90k_coco.py) 的示例来在 MMDetection 中训练/测试 Detectron2 的模型。
使用过程中需要注意配置文件中算法组件要和 Detectron2 中的相同。模型初始化时,我们首先初始化 [Detectron2](https://github.com/facebookresearch/detectron2/blob/main/detectron2/config/defaults.py) 的默认设置,然后配置文件中的设置将覆盖默认设置,模型将基于更新过的设置来建立。
输入数据首先转换成 Detectron2 的类型并输入进 Detectron2 的模型中。在推理阶段,Detectron2 的模型结果将会转换回 MMDetection 的类型。
## 使用 Detectron2 的预训练权重
`Detectron2Wrapper` 中的权重初始化将不使用 MMDetection 的逻辑。用户可以设置 `model.d2_detector.weights=xxx` 来加载预训练的权重。
例如,我们可以使用 `model.d2_detector.weights='detectron2://ImageNetPretrained/MSRA/R-50.pkl'` 来加载 ResNet-50 的预训练权重,或者使用
`model.d2_detector.weights='detectron2://COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x/137260431/model_final_a54504.pkl'` 来加载 Detectron2 中提出的预训练的Mask R-CNN权重。
**注意:** 不能直接使用 `load_from` 来加载 Detectron2 的预训练模型,但可以通过 `tools/model_converters/detectron2_to_mmdet.py` 先对该预训练模型进行转换。
在测试时,用户应该首先使用 `tools/model_converters/detectron2_to_mmdet.py` 将 Detectron2 的预训练权重转换为 MMDetection 可读取的结构。
```shell
python tools/model_converters/detectron2_to_mmdet.py ${Detectron2 ckpt path} ${MMDetectron ckpt path}
```
基础概念
***************
.. toctree::
:maxdepth: 1
data_flow.md
structures.md
models.md
datasets.md
transforms.md
evaluation.md
engine.md
conventions.md
组件定制
************************
.. toctree::
:maxdepth: 1
customize_models.md
customize_losses.md
customize_dataset.md
customize_transforms.md
customize_runtime.md
How to
************************
.. toctree::
:maxdepth: 1
how_to.md
# 数据结构(待更新)
# 数据变换(待更新)
按照惯例,我们使用 `Dataset``DataLoader` 进行多进程的数据加载。`Dataset` 返回字典类型的数据,数据内容为模型 `forward` 方法的各个参数。由于在目标检测中,输入的图像数据具有不同的大小,我们在 `MMCV` 里引入一个新的 `DataContainer` 类去收集和分发不同大小的输入数据。更多细节请参考[这里](https://github.com/open-mmlab/mmcv/blob/master/mmcv/parallel/data_container.py)
数据的准备流程和数据集是解耦的。通常一个数据集定义了如何处理标注数据(annotations)信息,而一个数据流程定义了准备一个数据字典的所有步骤。一个流程包括一系列的操作,每个操作都把一个字典作为输入,然后再输出一个新的字典给下一个变换操作。
我们在下图展示了一个经典的数据处理流程。蓝色块是数据处理操作,随着数据流程的处理,每个操作都可以在结果字典中加入新的键(标记为绿色)或更新现有的键(标记为橙色)。
![pipeline figure](../../../resources/data_pipeline.png)
这些操作可以分为数据加载(data loading)、预处理(pre-processing)、格式变化(formatting)和测试时数据增强(test-time augmentation)。
下面的例子是 `Faster R-CNN` 的一个流程:
```python
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
dict(type='RandomFlip', flip_ratio=0.5),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
]
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(1333, 800),
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
])
]
```
mmdet.apis
--------------
.. automodule:: mmdet.apis
:members:
mmdet.datasets
--------------
datasets
^^^^^^^^^^
.. automodule:: mmdet.datasets
:members:
api_wrappers
^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.datasets.api_wrappers
:members:
samplers
^^^^^^^^^^
.. automodule:: mmdet.datasets.samplers
:members:
transforms
^^^^^^^^^^^^
.. automodule:: mmdet.datasets.transforms
:members:
mmdet.engine
--------------
hooks
^^^^^^^^^^
.. automodule:: mmdet.engine.hooks
:members:
optimizers
^^^^^^^^^^^^^^^
.. automodule:: mmdet.engine.optimizers
:members:
runner
^^^^^^^^^^
.. automodule:: mmdet.engine.runner
:members:
schedulers
^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.engine.schedulers
:members:
mmdet.evaluation
--------------------
functional
^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.evaluation.functional
:members:
metrics
^^^^^^^^^^
.. automodule:: mmdet.evaluation.metrics
:members:
mmdet.models
--------------
backbones
^^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.models.backbones
:members:
data_preprocessors
^^^^^^^^^^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.models.data_preprocessors
:members:
dense_heads
^^^^^^^^^^^^^^^
.. automodule:: mmdet.models.dense_heads
:members:
detectors
^^^^^^^^^^
.. automodule:: mmdet.models.detectors
:members:
layers
^^^^^^^^^^
.. automodule:: mmdet.models.layers
:members:
losses
^^^^^^^^^^
.. automodule:: mmdet.models.losses
:members:
necks
^^^^^^^^^^^^
.. automodule:: mmdet.models.necks
:members:
roi_heads
^^^^^^^^^^^^^
.. automodule:: mmdet.models.roi_heads
:members:
seg_heads
^^^^^^^^^^^^^
.. automodule:: mmdet.models.seg_heads
:members:
task_modules
^^^^^^^^^^^^^
.. automodule:: mmdet.models.task_modules
:members:
test_time_augs
^^^^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.models.test_time_augs
:members:
utils
^^^^^^^^^^
.. automodule:: mmdet.models.utils
:members:
mmdet.structures
--------------------
structures
^^^^^^^^^^^^^^^^^
.. automodule:: mmdet.structures
:members:
bbox
^^^^^^^^^^
.. automodule:: mmdet.structures.bbox
:members:
mask
^^^^^^^^^^
.. automodule:: mmdet.structures.mask
:members:
mmdet.testing
----------------
.. automodule:: mmdet.testing
:members:
mmdet.visualization
--------------------
.. automodule:: mmdet.visualization
:members:
mmdet.utils
--------------
.. automodule:: mmdet.utils
:members:
## 中文解读文案汇总(待更新)
### 1 官方解读文案(v2.x)
#### 1.1 框架解读
- **[轻松掌握 MMDetection 整体构建流程(一)](https://zhuanlan.zhihu.com/p/337375549)**
- **[轻松掌握 MMDetection 整体构建流程(二)](https://zhuanlan.zhihu.com/p/341954021)**
- **[轻松掌握 MMDetection 中 Head 流程](https://zhuanlan.zhihu.com/p/343433169)**
#### 1.2 算法解读
- **[轻松掌握 MMDetection 中常用算法(一):RetinaNet 及配置详解](https://zhuanlan.zhihu.com/p/346198300)**
- **[轻松掌握 MMDetection 中常用算法(二):Faster R-CNN|Mask R-CNN](https://zhuanlan.zhihu.com/p/349807581)**
- [轻松掌握 MMDetection 中常用算法(三):FCOS](https://zhuanlan.zhihu.com/p/358056615)
- [轻松掌握 MMDetection 中常用算法(四):ATSS](https://zhuanlan.zhihu.com/p/358125611)
- [轻松掌握 MMDetection 中常用算法(五):Cascade R-CNN](https://zhuanlan.zhihu.com/p/360952172)
- [轻松掌握 MMDetection 中常用算法(六):YOLOF](https://zhuanlan.zhihu.com/p/370758213)
- [轻松掌握 MMDetection 中常用算法(七):CenterNet](https://zhuanlan.zhihu.com/p/374891478)
- [轻松掌握 MMDetection 中常用算法(八):YOLACT](https://zhuanlan.zhihu.com/p/376347955)
- [轻松掌握 MMDetection 中常用算法(九):AutoAssign](https://zhuanlan.zhihu.com/p/378581552)
- [YOLOX 在 MMDetection 中复现全流程解析](https://zhuanlan.zhihu.com/p/398545304)
- [喂喂喂!你可以减重了!小模型 - MMDetection 新增SSDLite 、 MobileNetV2YOLOV3 两大经典算法](https://zhuanlan.zhihu.com/p/402781143)
#### 1.3 工具解读
- [OpenMMLab 中混合精度训练 AMP 的正确打开方式](https://zhuanlan.zhihu.com/p/375224982)
- [小白都能看懂!手把手教你使用混淆矩阵分析目标检测](https://zhuanlan.zhihu.com/p/443499860)
- [MMDetection 图像缩放 Resize 详细说明 OpenMMLab](https://zhuanlan.zhihu.com/p/381117525)
- [拿什么拯救我的 4G 显卡](https://zhuanlan.zhihu.com/p/430123077)
- [MMDet居然能用MMCls的Backbone?论配置文件的打开方式](https://zhuanlan.zhihu.com/p/436865195)
#### 1.4 知乎问答
- [COCO数据集上1x模式下为什么不采用多尺度训练?](https://www.zhihu.com/question/462170786/answer/1915119662)
- [MMDetection中SOTA论文源码中将训练过程中BN层的eval打开?](https://www.zhihu.com/question/471189603/answer/2195540892)
- [基于PyTorch的MMDetection中训练的随机性来自何处?](https://www.zhihu.com/question/453511684/answer/1839683634)
- [单阶段、双阶段、anchor-based、anchor-free 这四者之间有什么联系吗?](https://www.zhihu.com/question/428972054/answer/1619925296)
- [目标检测的深度学习方法,有推荐的书籍或资料吗?](https://www.zhihu.com/question/391577080/answer/1612593817)
- [大佬们,刚入学研究生,想入门目标检测,有什么学习路线可以入门的?](https://www.zhihu.com/question/343768934/answer/1612580715)
- [目标检测领域还有什么可以做的?](https://www.zhihu.com/question/280703314/answer/1627885518)
- [如何看待Transformer在CV上的应用前景,未来有可能替代CNN吗?](https://www.zhihu.com/question/437495132/answer/1686380553)
- [MMDetection如何学习源码?](https://www.zhihu.com/question/451585041/answer/1832498963)
- [如何具体上手实现目标检测呢?](https://www.zhihu.com/question/341401981/answer/1848561187)
#### 1.5 其他
- **[不得不知的 MMDetection 学习路线(个人经验版)](https://zhuanlan.zhihu.com/p/369826931)**
- [OpenMMLab 社区专访之 YOLOX 复现篇](https://zhuanlan.zhihu.com/p/405913343)
### 2 社区解读文案(v2.x)
- [手把手带你实现经典检测网络 Mask R-CNN 的推理](https://zhuanlan.zhihu.com/p/414082071)
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import subprocess
import sys
import pytorch_sphinx_theme
sys.path.insert(0, os.path.abspath('../../'))
# -- Project information -----------------------------------------------------
project = 'MMDetection'
copyright = '2018-2021, OpenMMLab'
author = 'MMDetection Authors'
version_file = '../../mmdet/version.py'
def get_version():
with open(version_file, 'r') as f:
exec(compile(f.read(), version_file, 'exec'))
return locals()['__version__']
# The full version, including alpha/beta/rc tags
release = get_version()
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon',
'sphinx.ext.viewcode',
'myst_parser',
'sphinx_markdown_tables',
'sphinx_copybutton',
]
myst_enable_extensions = ['colon_fence']
myst_heading_anchors = 3
autodoc_mock_imports = [
'matplotlib', 'pycocotools', 'terminaltables', 'mmdet.version', 'mmcv.ops'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown',
}
# The main toctree document.
master_doc = 'index'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
# html_theme = 'sphinx_rtd_theme'
html_theme = 'pytorch_sphinx_theme'
html_theme_path = [pytorch_sphinx_theme.get_html_theme_path()]
html_theme_options = {
'menu': [
{
'name': 'GitHub',
'url': 'https://github.com/open-mmlab/mmdetection'
},
],
# Specify the language of shared menu
'menu_lang':
'cn',
}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_css_files = ['css/readthedocs.css']
language = 'zh_CN'
# -- Extension configuration -------------------------------------------------
# Ignore >>> when copying code
copybutton_prompt_text = r'>>> |\.\.\. '
copybutton_prompt_is_regexp = True
def builder_inited_handler(app):
subprocess.run(['./stat.py'])
def setup(app):
app.connect('builder-inited', builder_inited_handler)
# 开始你的第一步
## 依赖
本节中,我们将演示如何用 PyTorch 准备一个环境。
MMDetection 支持在 Linux,Windows 和 macOS 上运行。它需要 Python 3.7 以上,CUDA 9.2 以上和 PyTorch 1.8 及其以上。
```{note}
如果你对 PyTorch 有经验并且已经安装了它,你可以直接跳转到[下一小节](#安装流程)。否则,你可以按照下述步骤进行准备。
```
**步骤 0.**[官方网站](https://docs.conda.io/en/latest/miniconda.html)下载并安装 Miniconda。
**步骤 1.** 创建并激活一个 conda 环境。
```shell
conda create --name openmmlab python=3.8 -y
conda activate openmmlab
```
**步骤 2.** 基于 [PyTorch 官方说明](https://pytorch.org/get-started/locally/)安装 PyTorch。
在 GPU 平台上:
```shell
conda install pytorch torchvision -c pytorch
```
在 CPU 平台上:
```shell
conda install pytorch torchvision cpuonly -c pytorch
```
## 安装流程
我们推荐用户参照我们的最佳实践安装 MMDetection。不过,整个过程也是可定制化的,更多信息请参考[自定义安装](#自定义安装)章节。
### 最佳实践
**步骤 0.** 使用 [MIM](https://github.com/open-mmlab/mim) 安装 [MMEngine](https://github.com/open-mmlab/mmengine)[MMCV](https://github.com/open-mmlab/mmcv)
```shell
pip install -U openmim
mim install mmengine
mim install "mmcv>=2.0.0"
```
**注意:** 在 MMCV-v2.x 中,`mmcv-full` 改名为 `mmcv`,如果你想安装不包含 CUDA 算子精简版,可以通过 `mim install "mmcv-lite>=2.0.0rc1"` 来安装。
**步骤 1.** 安装 MMDetection。
方案 a:如果你开发并直接运行 mmdet,从源码安装它:
```shell
git clone https://github.com/open-mmlab/mmdetection.git
cd mmdetection
pip install -v -e .
# "-v" 指详细说明,或更多的输出
# "-e" 表示在可编辑模式下安装项目,因此对代码所做的任何本地修改都会生效,从而无需重新安装。
```
方案 b:如果你将 mmdet 作为依赖或第三方 Python 包,使用 MIM 安装:
```shell
mim install mmdet
```
## 验证安装
为了验证 MMDetection 是否安装正确,我们提供了一些示例代码来执行模型推理。
**步骤 1.** 我们需要下载配置文件和模型权重文件。
```shell
mim download mmdet --config rtmdet_tiny_8xb32-300e_coco --dest .
```
下载将需要几秒钟或更长时间,这取决于你的网络环境。完成后,你会在当前文件夹中发现两个文件 `rtmdet_tiny_8xb32-300e_coco.py``rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth`
**步骤 2.** 推理验证。
方案 a:如果你通过源码安装的 MMDetection,那么直接运行以下命令进行验证:
```shell
python demo/image_demo.py demo/demo.jpg rtmdet_tiny_8xb32-300e_coco.py --weights rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth --device cpu
```
你会在当前文件夹中的 `outputs/vis` 文件夹中看到一个新的图像 `demo.jpg`,图像中包含有网络预测的检测框。
方案 b:如果你通过 MIM 安装的 MMDetection,那么可以打开你的 Python 解析器,复制并粘贴以下代码:
```python
from mmdet.apis import init_detector, inference_detector
config_file = 'rtmdet_tiny_8xb32-300e_coco.py'
checkpoint_file = 'rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth'
model = init_detector(config_file, checkpoint_file, device='cpu') # or device='cuda:0'
inference_detector(model, 'demo/demo.jpg')
```
你将会看到一个包含 `DetDataSample` 的列表,预测结果在 `pred_instance` 里,包含有检测框,类别和得分。
### 自定义安装
#### CUDA 版本
在安装 PyTorch 时,你需要指定 CUDA 的版本。如果你不清楚应该选择哪一个,请遵循我们的建议:
- 对于 Ampere 架构的 NVIDIA GPU,例如 GeForce 30 系列以及 NVIDIA A100,CUDA 11 是必需的。
- 对于更早的 NVIDIA GPU,CUDA 11 是向后兼容 (backward compatible) 的,但 CUDA 10.2 能够提供更好的兼容性,也更加轻量。
请确保你的 GPU 驱动版本满足最低的版本需求,参阅 NVIDIA 官方的 [CUDA 工具箱和相应的驱动版本关系表](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions)
```{note}
如果按照我们的最佳实践,安装 CUDA 运行时库就足够了,这是因为不需要在本地编译 CUDA 代码。但如果你希望从源码编译 MMCV,或是开发其他 CUDA 算子,那么就必须安装完整的 CUDA 工具链,参见 [NVIDIA 官网](https://developer.nvidia.com/cuda-downloads),另外还需要确保该 CUDA 工具链的版本与 PyTorch 安装时的配置相匹配(如用 `conda install` 安装 PyTorch 时指定的 cudatoolkit 版本)。
```
#### 不使用 MIM 安装 MMEngine
要使用 pip 而不是 MIM 来安装 MMEngine,请遵照 [MMEngine 安装指南](https://mmengine.readthedocs.io/zh_CN/latest/get_started/installation.html)
例如,你可以通过以下命令安装 MMEngine。
```shell
pip install mmengine
```
#### 不使用 MIM 安装 MMCV
MMCV 包含 C++ 和 CUDA 扩展,因此其对 PyTorch 的依赖比较复杂。MIM 会自动解析这些依赖,选择合适的 MMCV 预编译包,使安装更简单,但它并不是必需的。
要使用 pip 而不是 MIM 来安装 MMCV,请遵照 [MMCV 安装指南](https://mmcv.readthedocs.io/zh_CN/2.x/get_started/installation.html)。它需要您用指定 url 的形式手动指定对应的 PyTorch 和 CUDA 版本。
例如,下述命令将会安装基于 PyTorch 1.12.x 和 CUDA 11.6 编译的 MMCV。
```shell
pip install "mmcv>=2.0.0" -f https://download.openmmlab.com/mmcv/dist/cu116/torch1.12.0/index.html
```
#### 在 CPU 环境中安装
MMDetection 可以在 CPU 环境中构建。在 CPU 模式下,可以进行模型训练(需要 MMCV 版本 >= 2.0.0rc1)、测试或者推理。
但是,以下功能在该模式下不能使用:
- Deformable Convolution
- Modulated Deformable Convolution
- ROI pooling
- Deformable ROI pooling
- CARAFE
- SyncBatchNorm
- CrissCrossAttention
- MaskedConv2d
- Temporal Interlace Shift
- nms_cuda
- sigmoid_focal_loss_cuda
- bbox_overlaps
因此,如果尝试训练/测试/推理包含上述算子的模型,将会报错。下表列出了将会受影响的相关算法。
| 操作 | 模型 |
| :-----------------------------------------------------: | :--------------------------------------------------------------------------------------: |
| Deformable Convolution/Modulated Deformable Convolution | DCN、Guided Anchoring、RepPoints、CentripetalNet、VFNet、CascadeRPN、NAS-FCOS、DetectoRS |
| MaskedConv2d | Guided Anchoring |
| CARAFE | CARAFE |
| SyncBatchNorm | ResNeSt |
#### 在 Google Colab 中安装
[Google Colab](https://colab.research.google.com/) 通常已经包含了 PyTorch 环境,因此我们只需要安装 MMEngine,MMCV 和 MMDetection 即可,命令如下:
**步骤 1.** 使用 [MIM](https://github.com/open-mmlab/mim) 安装 [MMEngine](https://github.com/open-mmlab/mmengine)[MMCV](https://github.com/open-mmlab/mmcv)
```shell
!pip3 install openmim
!mim install mmengine
!mim install "mmcv>=2.0.0,<2.1.0"
```
**步骤 2.** 使用源码安装 MMDetection。
```shell
!git clone https://github.com/open-mmlab/mmdetection.git
%cd mmdetection
!pip install -e .
```
**步骤 3.** 验证安装是否成功。
```python
import mmdet
print(mmdet.__version__)
# 预期输出:3.0.0 或其他版本号
```
```{note}
在 Jupyter Notebook 中,感叹号 `!` 用于执行外部命令,而 `%cd` 是一个[魔术命令](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-cd),用于切换 Python 的工作路径。
```
#### 通过 Docker 使用 MMDetection
我们提供了一个 [Dockerfile](../../docker/Dockerfile) 来构建一个镜像。请确保你的 [docker 版本](https://docs.docker.com/engine/install/) >=19.03。
```shell
# 基于 PyTorch 1.9,CUDA 11.1 构建镜像
# 如果你想要其他版本,只需要修改 Dockerfile
docker build -t mmdetection docker/
```
用以下命令运行 Docker 镜像:
```shell
docker run --gpus all --shm-size=8g -it -v {DATA_DIR}:/mmdetection/data mmdetection
```
### 排除故障
如果你在安装过程中遇到一些问题,请先查看 [FAQ](notes/faq.md) 页面。如果没有找到解决方案,你也可以在 GitHub 上[提出一个问题](https://github.com/open-mmlab/mmdetection/issues/new/choose)
### 使用多个 MMDetection 版本进行开发
训练和测试的脚本已经在 `PYTHONPATH` 中进行了修改,以确保脚本使用当前目录中的 MMDetection。
要使环境中安装默认版本的 MMDetection 而不是当前正在使用的,可以删除出现在相关脚本中的代码:
```shell
PYTHONPATH="$(dirname $0)/..":$PYTHONPATH
```
Welcome to MMDetection's documentation!
=======================================
.. toctree::
:maxdepth: 1
:caption: 开始你的第一步
overview.md
get_started.md
.. toctree::
:maxdepth: 2
:caption: 使用指南
user_guides/index.rst
.. toctree::
:maxdepth: 2
:caption: 进阶教程
advanced_guides/index.rst
.. toctree::
:maxdepth: 1
:caption: 迁移版本
migration/migration.md
.. toctree::
:maxdepth: 1
:caption: 接口文档(英文)
api.rst
.. toctree::
:maxdepth: 1
:caption: 模型仓库
model_zoo.md
.. toctree::
:maxdepth: 1
:caption: 说明
notes/contribution_guide.md
notes/projects.md
notes/faq.md
notes/compatibility.md
.. toctree::
:maxdepth: 1
:caption: 文章
article.md
.. toctree::
:caption: 语言切换
switch_language.md
Indices and tables
==================
* :ref:`genindex`
* :ref:`search`
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
# 将 API 和注册器从 MMDetection 2.x 迁移至 3.x
# 将配置文件从 MMDetection 2.x 迁移至 3.x
MMDetection 3.x 的配置文件与 2.x 相比有较大变化,这篇文档将介绍如何将 2.x 的配置文件迁移到 3.x。
在前面的[配置文件教程](../user_guides/config.md)中,我们以 Mask R-CNN 为例介绍了 MMDetection 3.x 的配置文件结构,这里我们将按同样的结构介绍如何将 2.x 的配置文件迁移至 3.x。
## 模型配置
模型的配置与 2.x 相比并没有太大变化,对于模型的 backbone,neck,head,以及 train_cfg 和 test_cfg,它们的参数与 2.x 版本的参数保持一致。
不同的是,我们在 3.x 版本的模型中新增了 `DataPreprocessor` 模块。
`DataPreprocessor` 模块的配置位于 `model.data_preprocessor` 中,它用于对输入数据进行预处理,例如对输入图像进行归一化,将不同大小的图片进行 padding 从而组成 batch,将图像从内存中读取到显存中等。这部分配置取代了原本存在于 train_pipeline 和 test_pipeline 中的 `Normalize``Pad`
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
# 图像归一化参数
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
to_rgb=True)
pipeline=[
...,
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32), # 图像 padding 到 32 的倍数
...
]
```
</td>
<tr>
<td>新配置</td>
<td>
```python
model = dict(
data_preprocessor=dict(
type='DetDataPreprocessor',
# 图像归一化参数
mean=[123.675, 116.28, 103.53],
std=[58.395, 57.12, 57.375],
bgr_to_rgb=True,
# 图像 padding 参数
pad_mask=True, # 在实例分割中,需要将 mask 也进行 padding
pad_size_divisor=32) # 图像 padding 到 32 的倍数
)
```
</td>
</tr>
</table>
## 数据集和评测器配置
数据集和评测部分的配置相比 2.x 版本有较大的变化。我们将从 Dataloader 和 Dataset,Data transform pipeline,以及评测器配置三个方面介绍如何将 2.x 版本的配置迁移到 3.x 版本。
### Dataloader 和 Dataset 配置
在新版本中,我们将数据加载的设置与 PyTorch 官方的 DataLoader 保持一致,这样可以使用户更容易理解和上手。
我们将训练、验证和测试的数据加载设置分别放在 `train_dataloader``val_dataloader``test_dataloader` 中,用户可以分别对这些 dataloader 设置不同的参数,其输入参数与 [PyTorch 的 Dataloader](https://pytorch.org/docs/stable/data.html?highlight=dataloader#torch.utils.data.DataLoader) 所需要的参数基本一致。
通过这种方式,我们将 2.x 版本中不可配置的 `sampler``batch_sampler``persistent_workers` 等参数都放到了配置文件中,使得用户可以更加灵活地设置数据加载的参数。
用户可以通过 `train_dataloader.dataset``val_dataloader.dataset``test_dataloader.dataset` 来设置数据集的配置,它们分别对应 2.x 版本中的 `data.train``data.val``data.test`
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
data = dict(
samples_per_gpu=2,
workers_per_gpu=2,
train=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_train2017.json',
img_prefix=data_root + 'train2017/',
pipeline=train_pipeline),
val=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_val2017.json',
img_prefix=data_root + 'val2017/',
pipeline=test_pipeline),
test=dict(
type=dataset_type,
ann_file=data_root + 'annotations/instances_val2017.json',
img_prefix=data_root + 'val2017/',
pipeline=test_pipeline))
```
</td>
<tr>
<td>新配置</td>
<td>
```python
train_dataloader = dict(
batch_size=2,
num_workers=2,
persistent_workers=True, # 避免每次迭代后 dataloader 重新创建子进程
sampler=dict(type='DefaultSampler', shuffle=True), # 默认的 sampler,同时支持分布式训练和非分布式训练
batch_sampler=dict(type='AspectRatioBatchSampler'), # 默认的 batch_sampler,用于保证 batch 中的图片具有相似的长宽比,从而可以更好地利用显存
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_train2017.json',
data_prefix=dict(img='train2017/'),
filter_cfg=dict(filter_empty_gt=True, min_size=32),
pipeline=train_pipeline))
# 在 3.x 版本中可以独立配置验证和测试的 dataloader
val_dataloader = dict(
batch_size=1,
num_workers=2,
persistent_workers=True,
drop_last=False,
sampler=dict(type='DefaultSampler', shuffle=False),
dataset=dict(
type=dataset_type,
data_root=data_root,
ann_file='annotations/instances_val2017.json',
data_prefix=dict(img='val2017/'),
test_mode=True,
pipeline=test_pipeline))
test_dataloader = val_dataloader # 测试 dataloader 的配置与验证 dataloader 的配置相同,这里省略
```
</td>
</tr>
</table>
### Data transform pipeline 配置
上文中提到,我们将图像 normalize 和 padding 的配置从 `train_pipeline``test_pipeline` 中独立出来,放到了 `model.data_preprocessor` 中,因此在 3.x 版本的 pipeline 中,我们不再需要 `Normalize``Pad` 这两个 transform。
同时,我们也对负责数据格式打包的 transform 进行了重构,将 `Collect``DefaultFormatBundle` 这两个 transform 合并为了 `PackDetInputs`,它负责将 data pipeline 中的数据打包成模型的输入格式,关于输入格式的转换,详见[数据流文档](../advanced_guides/data_flow.md)
下面以 Mask R-CNN 1x 的 train_pipeline 为例,介绍如何将 2.x 版本的配置迁移到 3.x 版本:
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
img_norm_cfg = dict(
mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),
dict(type='RandomFlip', flip_ratio=0.5),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='DefaultFormatBundle'),
dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
]
```
</td>
<tr>
<td>新配置</td>
<td>
```python
train_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='LoadAnnotations', with_bbox=True),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
dict(type='RandomFlip', prob=0.5),
dict(type='PackDetInputs')
]
```
</td>
</tr>
</table>
对于 test_pipeline,除了将 `Normalize``Pad` 这两个 transform 去掉之外,我们也将测试时的数据增强(TTA)与普通的测试流程分开,移除了 `MultiScaleFlipAug`。关于新版的 TTA 如何使用,详见[TTA 文档](../advanced_guides/tta.md)
下面同样以 Mask R-CNN 1x 的 test_pipeline 为例,介绍如何将 2.x 版本的配置迁移到 3.x 版本:
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(
type='MultiScaleFlipAug',
img_scale=(1333, 800),
flip=False,
transforms=[
dict(type='Resize', keep_ratio=True),
dict(type='RandomFlip'),
dict(type='Normalize', **img_norm_cfg),
dict(type='Pad', size_divisor=32),
dict(type='ImageToTensor', keys=['img']),
dict(type='Collect', keys=['img']),
])
]
```
</td>
<tr>
<td>新配置</td>
<td>
```python
test_pipeline = [
dict(type='LoadImageFromFile'),
dict(type='Resize', scale=(1333, 800), keep_ratio=True),
dict(
type='PackDetInputs',
meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',
'scale_factor'))
]
```
</td>
</tr>
</table>
除此之外,我们还对一些数据增强进行了重构,下表列出了 2.x 版本中的 transform 与 3.x 版本中的 transform 的对应关系:
<table class="docutils">
<thead>
<tr>
<th>名称</th>
<th>原配置</th>
<th>新配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>Resize</td>
<td>
```python
dict(type='Resize',
img_scale=(1333, 800),
keep_ratio=True)
```
</td>
<td>
```python
dict(type='Resize',
scale=(1333, 800),
keep_ratio=True)
```
</td>
</tr>
<tr>
<td>RandomResize</td>
<td>
```python
dict(
type='Resize',
img_scale=[
(1333, 640), (1333, 800)],
multiscale_mode='range',
keep_ratio=True)
```
</td>
<td>
```python
dict(
type='RandomResize',
scale=[
(1333, 640), (1333, 800)],
keep_ratio=True)
```
</td>
</tr>
<tr>
<td>RandomChoiceResize</td>
<td>
```python
dict(
type='Resize',
img_scale=[
(1333, 640), (1333, 672),
(1333, 704), (1333, 736),
(1333, 768), (1333, 800)],
multiscale_mode='value',
keep_ratio=True)
```
</td>
<td>
```python
dict(
type='RandomChoiceResize',
scales=[
(1333, 640), (1333, 672),
(1333, 704), (1333, 736),
(1333, 768), (1333, 800)],
keep_ratio=True)
```
</td>
</tr>
<tr>
<td>RandomFlip</td>
<td>
```python
dict(type='RandomFlip',
flip_ratio=0.5)
```
</td>
<td>
```python
dict(type='RandomFlip',
prob=0.5)
```
</td>
</tr>
</tbody>
</table>
### 评测器配置
在 3.x 版本中,模型精度评测不再与数据集绑定,而是通过评测器(Evaluator)来完成。
评测器配置分为 val_evaluator 和 test_evaluator 两部分,其中 val_evaluator 用于验证集评测,test_evaluator 用于测试集评测,对应 2.x 版本中的 evaluation 字段。
下表列出了 2.x 版本与 3.x 版本中的评测器的对应关系:
<table class="docutils">
<thead>
<tr>
<th>评测指标名称</th>
<th>原配置</th>
<th>新配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>COCO</td>
<td>
```python
data = dict(
val=dict(
type='CocoDataset',
ann_file=data_root + 'annotations/instances_val2017.json'))
evaluation = dict(metric=['bbox', 'segm'])
```
</td>
<td>
```python
val_evaluator = dict(
type='CocoMetric',
ann_file=data_root + 'annotations/instances_val2017.json',
metric=['bbox', 'segm'],
format_only=False)
```
</td>
</tr>
<tr>
<td>Pascal VOC</td>
<td>
```python
data = dict(
val=dict(
type=dataset_type,
ann_file=data_root + 'VOC2007/ImageSets/Main/test.txt'))
evaluation = dict(metric='mAP')
```
</td>
<td>
```python
val_evaluator = dict(
type='VOCMetric',
metric='mAP',
eval_mode='11points')
```
</td>
</tr>
<tr>
<td>OpenImages</td>
<td>
```python
data = dict(
val=dict(
type='OpenImagesDataset',
ann_file=data_root + 'annotations/validation-annotations-bbox.csv',
img_prefix=data_root + 'OpenImages/validation/',
label_file=data_root + 'annotations/class-descriptions-boxable.csv',
hierarchy_file=data_root +
'annotations/bbox_labels_600_hierarchy.json',
meta_file=data_root + 'annotations/validation-image-metas.pkl',
image_level_ann_file=data_root +
'annotations/validation-annotations-human-imagelabels-boxable.csv'))
evaluation = dict(interval=1, metric='mAP')
```
</td>
<td>
```python
val_evaluator = dict(
type='OpenImagesMetric',
iou_thrs=0.5,
ioa_thrs=0.5,
use_group_of=True,
get_supercategory=True)
```
</td>
</tr>
<tr>
<td>CityScapes</td>
<td>
```python
data = dict(
val=dict(
type='CityScapesDataset',
ann_file=data_root +
'annotations/instancesonly_filtered_gtFine_val.json',
img_prefix=data_root + 'leftImg8bit/val/',
pipeline=test_pipeline))
evaluation = dict(metric=['bbox', 'segm'])
```
</td>
<td>
```python
val_evaluator = [
dict(
type='CocoMetric',
ann_file=data_root +
'annotations/instancesonly_filtered_gtFine_val.json',
metric=['bbox', 'segm']),
dict(
type='CityScapesMetric',
ann_file=data_root +
'annotations/instancesonly_filtered_gtFine_val.json',
seg_prefix=data_root + '/gtFine/val',
outfile_prefix='./work_dirs/cityscapes_metric/instance')
]
```
</td>
</tr>
</tbody>
</table>
## 训练和测试的配置
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
runner = dict(
type='EpochBasedRunner', # 训练循环的类型
max_epochs=12) # 最大训练轮次
evaluation = dict(interval=2) # 验证间隔。每 2 个 epoch 验证一次
```
</td>
<tr>
<td>新配置</td>
<td>
```python
train_cfg = dict(
type='EpochBasedTrainLoop', # 训练循环的类型,请参考 https://github.com/open-mmlab/mmengine/blob/main/mmengine/runner/loops.py
max_epochs=12, # 最大训练轮次
val_interval=2) # 验证间隔。每 2 个 epoch 验证一次
val_cfg = dict(type='ValLoop') # 验证循环的类型
test_cfg = dict(type='TestLoop') # 测试循环的类型
```
</td>
</tr>
</table>
## 优化相关配置
优化器以及梯度裁剪的配置都移至 optim_wrapper 字段中。下表列出了 2.x 版本与 3.x 版本中的优化器配置的对应关系:
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
optimizer = dict(
type='SGD', # 随机梯度下降优化器
lr=0.02, # 基础学习率
momentum=0.9, # 带动量的随机梯度下降
weight_decay=0.0001) # 权重衰减
optimizer_config = dict(grad_clip=None) # 梯度裁剪的配置,设置为 None 关闭梯度裁剪
```
</td>
<tr>
<td>新配置</td>
<td>
```python
optim_wrapper = dict( # 优化器封装的配置
type='OptimWrapper', # 优化器封装的类型。可以切换至 AmpOptimWrapper 来启用混合精度训练
optimizer=dict( # 优化器配置。支持 PyTorch 的各种优化器。请参考 https://pytorch.org/docs/stable/optim.html#algorithms
type='SGD', # 随机梯度下降优化器
lr=0.02, # 基础学习率
momentum=0.9, # 带动量的随机梯度下降
weight_decay=0.0001), # 权重衰减
clip_grad=None, # 梯度裁剪的配置,设置为 None 关闭梯度裁剪。使用方法请见 https://mmengine.readthedocs.io/en/latest/tutorials/optimizer.html
)
```
</td>
</tr>
</table>
学习率的配置也从 lr_config 字段中移至 param_scheduler 字段中。param_scheduler 的配置更贴近 PyTorch 的学习率调整策略,更加灵活。下表列出了 2.x 版本与 3.x 版本中的学习率配置的对应关系:
<table class="docutils">
<tr>
<td>原配置</td>
<td>
```python
lr_config = dict(
policy='step', # 在训练过程中使用 multi step 学习率策略
warmup='linear', # 使用线性学习率预热
warmup_iters=500, # 到第 500 个 iteration 结束预热
warmup_ratio=0.001, # 学习率预热的系数
step=[8, 11], # 在哪几个 epoch 进行学习率衰减
gamma=0.1) # 学习率衰减系数
```
</td>
<tr>
<td>新配置</td>
<td>
```python
param_scheduler = [
dict(
type='LinearLR', # 使用线性学习率预热
start_factor=0.001, # 学习率预热的系数
by_epoch=False, # 按 iteration 更新预热学习率
begin=0, # 从第一个 iteration 开始
end=500), # 到第 500 个 iteration 结束
dict(
type='MultiStepLR', # 在训练过程中使用 multi step 学习率策略
by_epoch=True, # 按 epoch 更新学习率
begin=0, # 从第一个 epoch 开始
end=12, # 到第 12 个 epoch 结束
milestones=[8, 11], # 在哪几个 epoch 进行学习率衰减
gamma=0.1) # 学习率衰减系数
]
```
</td>
</tr>
</table>
关于其他的学习率调整策略的迁移,请参考 MMEngine 的[学习率迁移文档](https://mmengine.readthedocs.io/zh_CN/latest/migration/param_scheduler.html)
## 其他配置的迁移
### 保存 checkpoint 的配置
<table class="docutils">
<thead>
<tr>
<th>功能</th>
<th>原配置</th>
<th>新配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>设置保存间隔</td>
<td>
```python
checkpoint_config = dict(
interval=1)
```
</td>
<td>
```python
default_hooks = dict(
checkpoint=dict(
type='CheckpointHook',
interval=1))
```
</td>
</tr>
<tr>
<td>保存最佳模型</td>
<td>
```python
evaluation = dict(
save_best='auto')
```
</td>
<td>
```python
default_hooks = dict(
checkpoint=dict(
type='CheckpointHook',
save_best='auto'))
```
</td>
</tr>
<tr>
<td>只保留最新的几个模型</td>
<td>
```python
checkpoint_config = dict(
max_keep_ckpts=3)
```
</td>
<td>
```python
default_hooks = dict(
checkpoint=dict(
type='CheckpointHook',
max_keep_ckpts=3))
```
</td>
</tr>
</tbody>
</table>
### 日志的配置
3.x 版本中,日志的打印和可视化由 MMEngine 中的 logger 和 visualizer 分别完成。下表列出了 2.x 版本与 3.x 版本中的日志配置的对应关系:
<table class="docutils">
<thead>
<tr>
<th>功能</th>
<th>原配置</th>
<th>新配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>设置日志打印间隔</td>
<td>
```python
log_config = dict(
interval=50)
```
</td>
<td>
```python
default_hooks = dict(
logger=dict(
type='LoggerHook',
interval=50))
# 可选: 配置日志打印数值的平滑窗口大小
log_processor = dict(
type='LogProcessor',
window_size=50)
```
</td>
</tr>
<tr>
<td>使用 TensorBoard 或 WandB 可视化日志</td>
<td>
```python
log_config = dict(
interval=50,
hooks=[
dict(type='TextLoggerHook'),
dict(type='TensorboardLoggerHook'),
dict(type='MMDetWandbHook',
init_kwargs={
'project': 'mmdetection',
'group': 'maskrcnn-r50-fpn-1x-coco'
},
interval=50,
log_checkpoint=True,
log_checkpoint_metadata=True,
num_eval_images=100)
])
```
</td>
<td>
```python
vis_backends = [
dict(type='LocalVisBackend'),
dict(type='TensorboardVisBackend'),
dict(type='WandbVisBackend',
init_kwargs={
'project': 'mmdetection',
'group': 'maskrcnn-r50-fpn-1x-coco'
})
]
visualizer = dict(
type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')
```
</td>
</tr>
</tbody>
</table>
关于可视化相关的教程,请参考 MMDetection 的[可视化教程](../user_guides/visualization.md)
### Runtime 的配置
3.x 版本中 runtime 的配置字段有所调整,具体的对应关系如下:
<table class="docutils">
<thead>
<tr>
<th>原配置</th>
<th>新配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>
```python
cudnn_benchmark = False
opencv_num_threads = 0
mp_start_method = 'fork'
dist_params = dict(backend='nccl')
log_level = 'INFO'
load_from = None
resume_from = None
```
</td>
<td>
```python
env_cfg = dict(
cudnn_benchmark=False,
mp_cfg=dict(mp_start_method='fork',
opencv_num_threads=0),
dist_cfg=dict(backend='nccl'))
log_level = 'INFO'
load_from = None
resume = False
```
</td>
</tr>
</tbody>
</table>
# 将数据集从 MMDetection 2.x 迁移至 3.x
# 从 MMDetection 2.x 迁移至 3.x
MMDetection 3.x 版本是一个重大更新,包含了许多 API 和配置文件的变化。本文档旨在帮助用户从 MMDetection 2.x 版本迁移到 3.x 版本。
我们将迁移指南分为以下几个部分:
- [配置文件迁移](./config_migration.md)
- [API 和 Registry 迁移](./api_and_registry_migration.md)
- [数据集迁移](./dataset_migration.md)
- [模型迁移](./model_migration.md)
- [常见问题](./migration_faq.md)
如果您在迁移过程中遇到任何问题,欢迎在 issue 中提出。我们也欢迎您为本文档做出贡献。
# 将模型从 MMDetection 2.x 迁移至 3.x
# 模型库
## 镜像地址
从 MMDetection V2.0 起,我们只通过阿里云维护模型库。V1.x 版本的模型已经弃用。
## 共同设置
- 所有模型都是在 `coco_2017_train` 上训练,在 `coco_2017_val` 上测试。
- 我们使用分布式训练。
- 所有 pytorch-style 的 ImageNet 预训练主干网络来自 PyTorch 的模型库,caffe-style 的预训练主干网络来自 detectron2 最新开源的模型。
- 为了与其他代码库公平比较,文档中所写的 GPU 内存是8个 GPU 的 `torch.cuda.max_memory_allocated()` 的最大值,此值通常小于 nvidia-smi 显示的值。
- 我们以网络 forward 和后处理的时间加和作为推理时间,不包含数据加载时间。所有结果通过 [benchmark.py](https://github.com/open-mmlab/mmdetection/blob/main/tools/analysis_tools/benchmark.py) 脚本计算所得。该脚本会计算推理 2000 张图像的平均时间。
## ImageNet 预训练模型
通过 ImageNet 分类任务预训练的主干网络进行初始化是很常见的操作。所有预训练模型的链接都可以在 [open_mmlab](https://github.com/open-mmlab/mmcv/blob/master/mmcv/model_zoo/open_mmlab.json) 中找到。根据 `img_norm_cfg` 和原始权重,我们可以将所有 ImageNet 预训练模型分为以下几种情况:
- TorchVision:torchvision 模型权重,包含 ResNet50, ResNet101。`img_norm_cfg``dict(mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)`
- Pycls:[pycls](https://github.com/facebookresearch/pycls) 模型权重,包含 RegNetX。`img_norm_cfg``dict( mean=[103.530, 116.280, 123.675], std=[57.375, 57.12, 58.395], to_rgb=False)`
- MSRA styles:[MSRA](https://github.com/KaimingHe/deep-residual-networks) 模型权重,包含 ResNet50_Caffe,ResNet101_Caffe。`img_norm_cfg``dict( mean=[103.530, 116.280, 123.675], std=[1.0, 1.0, 1.0], to_rgb=False)`
- Caffe2 styles:现阶段只包含 ResNext101_32x8d。`img_norm_cfg``dict(mean=[103.530, 116.280, 123.675], std=[57.375, 57.120, 58.395], to_rgb=False)`
- Other styles: SSD 的 `img_norm_cfg``dict(mean=[123.675, 116.28, 103.53], std=[1, 1, 1], to_rgb=True)`,YOLOv3 的 `img_norm_cfg``dict(mean=[0, 0, 0], std=[255., 255., 255.], to_rgb=True)`
MMdetection 常用到的主干网络细节如下表所示:
| 模型 | 来源 | 链接 | 描述 |
| ---------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ResNet50 | TorchVision | [torchvision 中的 ResNet-50](https://download.pytorch.org/models/resnet50-19c8e357.pth) | 来自 [torchvision 中的 ResNet-50](https://download.pytorch.org/models/resnet50-19c8e357.pth)。 |
| ResNet101 | TorchVision | [torchvision 中的 ResNet-101](https://download.pytorch.org/models/resnet101-5d3b4d8f.pth) | 来自 [torchvision 中的 ResNet-101](https://download.pytorch.org/models/resnet101-5d3b4d8f.pth)。 |
| RegNetX | Pycls | [RegNetX_3.2gf](https://download.openmmlab.com/pretrain/third_party/regnetx_3.2gf-c2599b0f.pth)[RegNetX_800mf](https://download.openmmlab.com/pretrain/third_party/regnetx_800mf-1f4be4c7.pth) 等 | 来自 [pycls](https://github.com/facebookresearch/pycls)。 |
| ResNet50_Caffe | MSRA | [MSRA 中的 ResNet-50](https://download.openmmlab.com/pretrain/third_party/resnet50_caffe-788b5fa3.pth) | 由 [Detectron2 中的 R-50.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/MSRA/R-50.pkl) 转化的副本。原始权重文件来自 [MSRA 中的原始 ResNet-50](https://github.com/KaimingHe/deep-residual-networks)。 |
| ResNet101_Caffe | MSRA | [MSRA 中的 ResNet-101](https://download.openmmlab.com/pretrain/third_party/resnet101_caffe-3ad79236.pth) | 由 [Detectron2 中的 R-101.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/MSRA/R-101.pkl) 转化的副本。原始权重文件来自 [MSRA 中的原始 ResNet-101](https://github.com/KaimingHe/deep-residual-networks)。 |
| ResNext101_32x8d | Caffe2 | [Caffe2 ResNext101_32x8d](https://download.openmmlab.com/pretrain/third_party/resnext101_32x8d-1516f1aa.pth) | 由 [Detectron2 中的 X-101-32x8d.pkl](https://dl.fbaipublicfiles.com/detectron2/ImageNetPretrained/FAIR/X-101-32x8d.pkl) 转化的副本。原始 ResNeXt-101-32x8d 由 FB 使用 Caffe2 训练。 |
## Baselines
### RPN
请参考 [RPN](https://github.com/open-mmlab/mmdetection/blob/main/configs/rpn)
### Faster R-CNN
请参考 [Faster R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/faster_rcnn)
### Mask R-CNN
请参考 [Mask R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/mask_rcnn)
### Fast R-CNN (使用提前计算的 proposals)
请参考 [Fast R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/fast_rcnn)
### RetinaNet
请参考 [RetinaNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/retinanet)
### Cascade R-CNN and Cascade Mask R-CNN
请参考 [Cascade R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/cascade_rcnn)
### Hybrid Task Cascade (HTC)
请参考 [HTC](https://github.com/open-mmlab/mmdetection/blob/main/configs/htc)
### SSD
请参考 [SSD](https://github.com/open-mmlab/mmdetection/blob/main/configs/ssd)
### Group Normalization (GN)
请参考 [Group Normalization](https://github.com/open-mmlab/mmdetection/blob/main/configs/gn)
### Weight Standardization
请参考 [Weight Standardization](https://github.com/open-mmlab/mmdetection/blob/main/configs/gn+ws)
### Deformable Convolution v2
请参考 [Deformable Convolutional Networks](https://github.com/open-mmlab/mmdetection/blob/main/configs/dcn)
### CARAFE: Content-Aware ReAssembly of FEatures
请参考 [CARAFE](https://github.com/open-mmlab/mmdetection/blob/main/configs/carafe)
### Instaboost
请参考 [Instaboost](https://github.com/open-mmlab/mmdetection/blob/main/configs/instaboost)
### Libra R-CNN
请参考 [Libra R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/libra_rcnn)
### Guided Anchoring
请参考 [Guided Anchoring](https://github.com/open-mmlab/mmdetection/blob/main/configs/guided_anchoring)
### FCOS
请参考 [FCOS](https://github.com/open-mmlab/mmdetection/blob/main/configs/fcos)
### FoveaBox
请参考 [FoveaBox](https://github.com/open-mmlab/mmdetection/blob/main/configs/foveabox)
### RepPoints
请参考 [RepPoints](https://github.com/open-mmlab/mmdetection/blob/main/configs/reppoints)
### FreeAnchor
请参考 [FreeAnchor](https://github.com/open-mmlab/mmdetection/blob/main/configs/free_anchor)
### Grid R-CNN (plus)
请参考 [Grid R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/grid_rcnn)
### GHM
请参考 [GHM](https://github.com/open-mmlab/mmdetection/blob/main/configs/ghm)
### GCNet
请参考 [GCNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/gcnet)
### HRNet
请参考 [HRNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/hrnet)
### Mask Scoring R-CNN
请参考 [Mask Scoring R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/ms_rcnn)
### Train from Scratch
请参考 [Rethinking ImageNet Pre-training](https://github.com/open-mmlab/mmdetection/blob/main/configs/scratch)
### NAS-FPN
请参考 [NAS-FPN](https://github.com/open-mmlab/mmdetection/blob/main/configs/nas_fpn)
### ATSS
请参考 [ATSS](https://github.com/open-mmlab/mmdetection/blob/main/configs/atss)
### FSAF
请参考 [FSAF](https://github.com/open-mmlab/mmdetection/blob/main/configs/fsaf)
### RegNetX
请参考 [RegNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/regnet)
### Res2Net
请参考 [Res2Net](https://github.com/open-mmlab/mmdetection/blob/main/configs/res2net)
### GRoIE
请参考 [GRoIE](https://github.com/open-mmlab/mmdetection/blob/main/configs/groie)
### Dynamic R-CNN
请参考 [Dynamic R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/dynamic_rcnn)
### PointRend
请参考 [PointRend](https://github.com/open-mmlab/mmdetection/blob/main/configs/point_rend)
### DetectoRS
请参考 [DetectoRS](https://github.com/open-mmlab/mmdetection/blob/main/configs/detectors)
### Generalized Focal Loss
请参考 [Generalized Focal Loss](https://github.com/open-mmlab/mmdetection/blob/main/configs/gfl)
### CornerNet
请参考 [CornerNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/cornernet)
### YOLOv3
请参考 [YOLOv3](https://github.com/open-mmlab/mmdetection/blob/main/configs/yolo)
### PAA
请参考 [PAA](https://github.com/open-mmlab/mmdetection/blob/main/configs/paa)
### SABL
请参考 [SABL](https://github.com/open-mmlab/mmdetection/blob/main/configs/sabl)
### CentripetalNet
请参考 [CentripetalNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/centripetalnet)
### ResNeSt
请参考 [ResNeSt](https://github.com/open-mmlab/mmdetection/blob/main/configs/resnest)
### DETR
请参考 [DETR](https://github.com/open-mmlab/mmdetection/blob/main/configs/detr)
### Deformable DETR
请参考 [Deformable DETR](https://github.com/open-mmlab/mmdetection/blob/main/configs/deformable_detr)
### AutoAssign
请参考 [AutoAssign](https://github.com/open-mmlab/mmdetection/blob/main/configs/autoassign)
### YOLOF
请参考 [YOLOF](https://github.com/open-mmlab/mmdetection/blob/main/configs/yolof)
### Seesaw Loss
请参考 [Seesaw Loss](https://github.com/open-mmlab/mmdetection/blob/main/configs/seesaw_loss)
### CenterNet
请参考 [CenterNet](https://github.com/open-mmlab/mmdetection/blob/main/configs/centernet)
### YOLOX
请参考 [YOLOX](https://github.com/open-mmlab/mmdetection/blob/main/configs/yolox)
### PVT
请参考 [PVT](https://github.com/open-mmlab/mmdetection/blob/main/configs/pvt)
### SOLO
请参考 [SOLO](https://github.com/open-mmlab/mmdetection/blob/main/configs/solo)
### QueryInst
请参考 [QueryInst](https://github.com/open-mmlab/mmdetection/blob/main/configs/queryinst)
### Other datasets
我们还在 [PASCAL VOC](https://github.com/open-mmlab/mmdetection/blob/main/configs/pascal_voc)[Cityscapes](https://github.com/open-mmlab/mmdetection/blob/main/configs/cityscapes)[WIDER FACE](https://github.com/open-mmlab/mmdetection/blob/main/configs/wider_face) 上对一些方法进行了基准测试。
### Pre-trained Models
我们还通过多尺度训练和更长的训练策略来训练用 ResNet-50 和 [RegNetX-3.2G](https://github.com/open-mmlab/mmdetection/blob/main/configs/regnet) 作为主干网络的 [Faster R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/faster_rcnn)[Mask R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/mask_rcnn)。这些模型可以作为下游任务的预训练模型。
## 速度基准
### 训练速度基准
我们提供 [analyze_logs.py](https://github.com/open-mmlab/mmdetection/blob/main/tools/analysis_tools/analyze_logs.py) 来得到训练中每一次迭代的平均时间。示例请参考 [Log Analysis](https://mmdetection.readthedocs.io/en/latest/useful_tools.html#log-analysis)
我们与其他流行框架的 Mask R-CNN 训练速度进行比较(数据是从 [detectron2](https://github.com/facebookresearch/detectron2/blob/main/docs/notes/benchmarks.md/) 复制而来)。在 mmdetection 中,我们使用 [mask-rcnn_r50-caffe_fpn_poly-1x_coco_v1.py](https://github.com/open-mmlab/mmdetection/blob/main/configs/mask_rcnn/mask-rcnn_r50-caffe_fpn_poly-1x_coco_v1.py) 进行基准测试。它与 detectron2 的 [mask_rcnn_R_50_FPN_noaug_1x.yaml](https://github.com/facebookresearch/detectron2/blob/main/configs/Detectron1-Comparisons/mask_rcnn_R_50_FPN_noaug_1x.yaml) 设置完全一样。同时,我们还提供了[模型权重](https://download.openmmlab.com/mmdetection/v2.0/benchmark/mask_rcnn_r50_caffe_fpn_poly_1x_coco_no_aug/mask_rcnn_r50_caffe_fpn_poly_1x_coco_no_aug_compare_20200518-10127928.pth)[训练 log](https://download.openmmlab.com/mmdetection/v2.0/benchmark/mask_rcnn_r50_caffe_fpn_poly_1x_coco_no_aug/mask_rcnn_r50_caffe_fpn_poly_1x_coco_no_aug_20200518_105755.log.json) 作为参考。为了跳过 GPU 预热时间,吞吐量按照100-500次迭代之间的平均吞吐量来计算。
| 框架 | 吞吐量 (img/s) |
| -------------------------------------------------------------------------------------- | -------------- |
| [Detectron2](https://github.com/facebookresearch/detectron2) | 62 |
| [MMDetection](https://github.com/open-mmlab/mmdetection) | 61 |
| [maskrcnn-benchmark](https://github.com/facebookresearch/maskrcnn-benchmark/) | 53 |
| [tensorpack](https://github.com/tensorpack/tensorpack/tree/master/examples/FasterRCNN) | 50 |
| [simpledet](https://github.com/TuSimple/simpledet/) | 39 |
| [Detectron](https://github.com/facebookresearch/Detectron) | 19 |
| [matterport/Mask_RCNN](https://github.com/matterport/Mask_RCNN/) | 14 |
### 推理时间基准
我们提供 [benchmark.py](https://github.com/open-mmlab/mmdetection/blob/main/tools/analysis_tools/benchmark.py) 对推理时间进行基准测试。此脚本将推理 2000 张图片并计算忽略前 5 次推理的平均推理时间。可以通过设置 `LOG-INTERVAL` 来改变 log 输出间隔(默认为 50)。
```shell
python tools/benchmark.py ${CONFIG} ${CHECKPOINT} [--log-interval $[LOG-INTERVAL]] [--fuse-conv-bn]
```
模型库中,所有模型在基准测量推理时间时都没设置 `fuse-conv-bn`, 此设置可以使推理时间更短。
## 与 Detectron2 对比
我们在速度和精度方面对 mmdetection 和 [Detectron2](https://github.com/facebookresearch/detectron2.git) 进行对比。对比所使用的 detectron2 的 commit id 为 [185c27e](https://github.com/facebookresearch/detectron2/tree/185c27e4b4d2d4c68b5627b3765420c6d7f5a659)(30/4/2020)
为了公平对比,我们所有的实验都在同一机器下进行。
### 硬件
- 8 NVIDIA Tesla V100 (32G) GPUs
- Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz
### 软件环境
- Python 3.7
- PyTorch 1.4
- CUDA 10.1
- CUDNN 7.6.03
- NCCL 2.4.08
### 精度
| 模型 | 训练策略 | Detectron2 | mmdetection | 下载 |
| ------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Faster R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/faster_rcnn/faster-rcnn_r50-caffe_fpn_ms-1x_coco.py) | 1x | [37.9](https://github.com/facebookresearch/detectron2/blob/main/configs/COCO-Detection/faster_rcnn_R_50_FPN_1x.yaml) | 38.0 | [model](https://download.openmmlab.com/mmdetection/v2.0/benchmark/faster_rcnn_r50_caffe_fpn_mstrain_1x_coco/faster_rcnn_r50_caffe_fpn_mstrain_1x_coco-5324cff8.pth) \| [log](https://download.openmmlab.com/mmdetection/v2.0/benchmark/faster_rcnn_r50_caffe_fpn_mstrain_1x_coco/faster_rcnn_r50_caffe_fpn_mstrain_1x_coco_20200429_234554.log.json) |
| [Mask R-CNN](https://github.com/open-mmlab/mmdetection/blob/main/configs/mask_rcnn/mask-rcnn_r50-caffe_fpn_ms-poly-1x_coco.py) | 1x | [38.6 & 35.2](https://github.com/facebookresearch/detectron2/blob/master/configs/COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_1x.yaml) | 38.8 & 35.4 | [model](https://download.openmmlab.com/mmdetection/v2.0/benchmark/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco-dbecf295.pth) \| [log](https://download.openmmlab.com/mmdetection/v2.0/benchmark/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco_20200430_054239.log.json) |
| [Retinanet](https://github.com/open-mmlab/mmdetection/blob/main/configs/retinanet/retinanet_r50-caffe_fpn_ms-1x_coco.py) | 1x | [36.5](https://github.com/facebookresearch/detectron2/blob/master/configs/COCO-Detection/retinanet_R_50_FPN_1x.yaml) | 37.0 | [model](https://download.openmmlab.com/mmdetection/v2.0/benchmark/retinanet_r50_caffe_fpn_mstrain_1x_coco/retinanet_r50_caffe_fpn_mstrain_1x_coco-586977a0.pth) \| [log](https://download.openmmlab.com/mmdetection/v2.0/benchmark/retinanet_r50_caffe_fpn_mstrain_1x_coco/retinanet_r50_caffe_fpn_mstrain_1x_coco_20200430_014748.log.json) |
### 训练速度
训练速度使用 s/iter 来度量。结果越低越好。
| 模型 | Detectron2 | mmdetection |
| ------------ | ---------- | ----------- |
| Faster R-CNN | 0.210 | 0.216 |
| Mask R-CNN | 0.261 | 0.265 |
| Retinanet | 0.200 | 0.205 |
### 推理速度
推理速度通过单张 GPU 下的 fps(img/s) 来度量,越高越好。
为了与 Detectron2 保持一致,我们所写的推理时间除去了数据加载时间。
对于 Mask RCNN,我们去除了后处理中 RLE 编码的时间。
我们在括号中给出了官方给出的速度。由于硬件差异,官方给出的速度会比我们所测试得到的速度快一些。
| 模型 | Detectron2 | mmdetection |
| ------------ | ----------- | ----------- |
| Faster R-CNN | 25.6 (26.3) | 22.2 |
| Mask R-CNN | 22.5 (23.3) | 19.6 |
| Retinanet | 17.8 (18.2) | 20.6 |
### 训练内存
| 模型 | Detectron2 | mmdetection |
| ------------ | ---------- | ----------- |
| Faster R-CNN | 3.0 | 3.8 |
| Mask R-CNN | 3.4 | 3.9 |
| Retinanet | 3.9 | 3.4 |
# MMDetection v2.x 兼容性说明
## MMDetection 2.25.0
为了加入 Mask2Former 实例分割模型,对 Mask2Former 的配置文件进行了重命名 [PR #7571](https://github.com/open-mmlab/mmdetection/pull/7571)
<table align="center">
<thead>
<tr align='center'>
<td>在 v2.25.0 之前</td>
<td>v2.25.0 及之后</td>
</tr>
</thead>
<tbody><tr valign='top'>
<th>
```
'mask2former_xxx_coco.py' 代表全景分割的配置文件
```
</th>
<th>
```
'mask2former_xxx_coco.py' 代表实例分割的配置文件
'mask2former_xxx_coco-panoptic.py' 代表全景分割的配置文件
```
</th></tr>
</tbody></table>
## MMDetection 2.21.0
为了支持 CPU 训练,MMCV 中进行批处理的 scatter 的代码逻辑已经被修改。我们推荐使用 MMCV v1.4.4 或更高版本,
更多信息请参考 [MMCV PR #1621](https://github.com/open-mmlab/mmcv/pull/1621).
## MMDetection 2.18.1
### MMCV compatibility
为了修复 BaseTransformerLayer 中的权重引用问题, MultiheadAttention 中 batch first 的逻辑有所改变。
我们推荐使用 MMCV v1.3.17 或更高版本。 更多信息请参考 [MMCV PR #1418](https://github.com/open-mmlab/mmcv/pull/1418)
## MMDetection 2.18.0
### DIIHead 兼容性
为了支持 QueryInst,在 DIIHead 的返回元组中加入了 attn_feats。
## MMDetection v2.14.0
### MMCV 版本
为了修复 EvalHook 优先级过低的问题,MMCV v1.3.8 中所有 hook 的优先级都重新进行了调整,因此 MMDetection v2.14.0 需要依赖最新的 MMCV v1.3.8 版本。 相关信息请参考[PR #1120](https://github.com/open-mmlab/mmcv/pull/1120) ,相关问题请参考[#5343](https://github.com/open-mmlab/mmdetection/issues/5343)
### SSD 兼容性
在 v2.14.0 中,为了使 SSD 能够被更灵活地使用,[PR #5291](https://github.com/open-mmlab/mmdetection/pull/5291) 重构了 SSD 的 backbone、neck 和 head。用户可以使用 tools/model_converters/upgrade_ssd_version.py 转换旧版本训练的模型。
```shell
python tools/model_converters/upgrade_ssd_version.py ${OLD_MODEL_PATH} ${NEW_MODEL_PATH}
```
- OLD_MODEL_PATH:旧版 SSD 模型的路径。
- NEW_MODEL_PATH:保存转换后模型权重的路径。
## MMDetection v2.12.0
在 v2.12.0 到 v2.18.0(或以上)版本的这段时间,为了提升通用性和便捷性,MMDetection 正在进行大规模重构。在升级到 v2.12.0 后 MMDetection 不可避免地带来了一些 BC Breaking,包括 MMCV 的版本依赖、模型初始化方式、模型 registry 和 mask AP 的评估。
### MMCV 版本
MMDetection v2.12.0 依赖 MMCV v1.3.3 中新增加的功能,包括:使用 `BaseModule` 统一参数初始化,模型 registry,以及[Deformable DETR](https://arxiv.org/abs/2010.04159) 中的 `MultiScaleDeformableAttn` CUDA 算子。
注意,尽管 MMCV v1.3.2 已经包含了 MMDet 所需的功能,但是存在一些已知的问题。我们建议用户跳过 MMCV v1.3.2 使用 v1.3.3 版本。
### 统一模型初始化
为了统一 OpenMMLab 项目中的参数初始化方式,MMCV 新增加了 `BaseModule` 类,使用 `init_cfg` 参数对模块进行统一且灵活的初始化配置管理。
现在用户需要在训练脚本中显式调用 `model.init_weights()` 来初始化模型(例如 [这行代码](https://github.com/open-mmlab/mmdetection/blob/master/tools/train.py#L162) ,在这之前则是在 detector 中进行处理的。
**下游项目必须相应地更新模型初始化方式才能使用 MMDetection v2.12.0**。请参阅 [PR #4750](https://github.com/open-mmlab/mmdetection/pull/4750) 了解详情。
### 统一模型 registry
为了能够使用在其他 OpenMMLab 项目中实现的 backbone,MMDetection v2.12.0 继承了在 MMCV (#760) 中创建的模型 registry。
这样,只要 OpenMMLab 项目实现了某个 backbone,并且该项目也使用 MMCV 中的 registry,那么用户只需修改配置即可在 MMDetection 中使用该 backbone,不再需要将代码复制到 MMDetection 中。 更多详细信息,请参阅 [PR #5059](https://github.com/open-mmlab/mmdetection/pull/5059)
### Mask AP 评估
[PR #4898](https://github.com/open-mmlab/mmdetection/pull/4898) 和 v2.12.0 之前,对小、中、大目标的 mask AP 的评估是基于其边界框区域而不是真正的 mask 区域。
这导致 `APs``APm` 变得更高但 `APl` 变得更低,但是不会影响整体的 mask AP。 [PR #4898](https://github.com/open-mmlab/mmdetection/pull/4898) 删除了 mask AP 计算中的 `bbox` ,改为使用 mask 区域。
新的计算方式不会影响整体的 mask AP 评估,与 [Detectron2](https://github.com/facebookresearch/detectron2/)一致。
## 与 MMDetection v1.x 的兼容性
MMDetection v2.0 经过了大规模重构并解决了许多遗留问题。 MMDetection v2.0 不兼容 v1.x 版本,在这两个版本中使用相同的模型权重运行推理会产生不同的结果。 因此,MMDetection v2.0 重新对所有模型进行了 benchmark,并在 model zoo 中提供了新模型的权重和训练记录。
新旧版本的主要的区别有四方面:坐标系、代码库约定、训练超参和模块设计。
### 坐标系
新坐标系与 [Detectron2](https://github.com/facebookresearch/detectron2/) 一致,
将最左上角的像素的中心视为坐标原点 (0, 0) 而不是最左上角像素的左上角。 因此 COCO 边界框和分割标注中的坐标被解析为范围 `[0,width]``[0,height]` 中的坐标。 这个修改影响了所有与 bbox 及像素选择相关的计算,变得更加自然且更加准确。
- 在新坐标系中,左上角和右下角为 (x1, y1) (x2, y2) 的框的宽度及高度计算公式为 `width = x2 - x1``height = y2 - y1`
在 MMDetection v1.x 和之前的版本中,高度和宽度都多了 `+ 1` 的操作。
本次修改包括三部分:
1. box 回归中的检测框变换以及编码/解码。
2. IoU 计算。这会影响 ground truth 和检测框之间的匹配以及 NMS 。但对兼容性的影响可以忽略不计。
3. Box 的角点坐标为浮点型,不再取整。这能使得检测结果更为准确,也使得检测框和 RoI 的最小尺寸不再为 1,但影响很小。
- Anchor 的中心与特征图的网格点对齐,类型变为 float。
在 MMDetection v1.x 和之前的版本中,anchors 是 `int` 类型且没有居中对齐。
这会影响 RPN 中的 Anchor 生成和所有基于 Anchor 的方法。
- ROIAlign 更好地与图像坐标系对齐。新的实现来自 [Detectron2](https://github.com/facebookresearch/detectron2/tree/master/detectron2/layers/csrc/ROIAlign)
当 RoI 用于提取 RoI 特征时,与 MMDetection v1.x 相比默认情况下相差半个像素。
能够通过设置 `aligned=False` 而不是 `aligned=True` 来维持旧版本的设置。
- Mask 的裁剪和粘贴更准确。
1. 我们使用新的 RoIAlign 来提取 mask 目标。 在 MMDetection v1.x 中,bounding box 在提取 mask 目标之前被取整,裁剪过程是 numpy 实现的。 而在新版本中,裁剪的边界框不经过取整直接输入 RoIAlign。 此实现大大加快了训练速度(每次迭代约加速 0.1 秒,1x schedule 训练 Mask R50 时加速约 2 小时)并且理论上会更准确。
2. 在 MMDetection v2.0 中,修改后的 `paste_mask()` 函数应该比之前版本更准确。 此更改参考了 [Detectron2](https://github.com/facebookresearch/detectron2/blob/master/detectron2/structures/masks.py) 中的修改,可以将 COCO 上的 mask AP 提高约 0.5%。
### 代码库约定
- MMDetection v2.0 更改了类别标签的顺序,减少了回归和 mask 分支里的无用参数并使得顺序更加自然(没有 +1 和 -1)。
这会影响模型的所有分类层,使其输出的类别标签顺序发生改变。回归分支和 mask head 的最后一层不再为 K 个类别保留 K+1 个通道,类别顺序与分类分支一致。
- 在 MMDetection v2.0 中,标签 “K” 表示背景,标签 \[0, K-1\] 对应于 K = num_categories 个对象类别。
- 在 MMDetection v1.x 及之前的版本中,标签 “0” 表示背景,标签 \[1, K\] 对应 K 个类别。
- **注意**:softmax RPN 的类顺序在 version\<=2.4.0 中仍然和 1.x 中的一样,而 sigmoid RPN 不受影响。从 MMDetection v2.5.0 开始,所有 head 中的类顺序是统一的。
- 不使用 R-CNN 中的低质量匹配。在 MMDetection v1.x 和之前的版本中,`max_iou_assigner` 会在 RPN 和 R-CNN 训练时给每个 ground truth 匹配低质量框。我们发现这会导致最佳的 GT 框不会被分配给某些边界框,
因此,在MMDetection v2.0 的 R-CNN 训练中默认不允许低质量匹配。这有时可能会稍微改善 box AP(约为 0.1%)。
- 单独的宽高比例系数。在 MMDetection v1.x 和以前的版本中,`keep_ratio=True` 时比例系数是单个浮点数,这并不准确,因为宽度和高度的比例系数会有一定的差异。 MMDetection v2.0 对宽度和高度使用单独的比例系数,对 AP 的提升约为 0.1%。
- 修改了 config 文件名称的规范。 由于 model zoo 中模型不断增多, MMDetection v2.0 采用新的命名规则:
```shell
[model]_(model setting)_[backbone]_[neck]_(norm setting)_(misc)_(gpu x batch)_[schedule]_[dataset].py
```
其中 (`misc`) 包括 DCN 和 GCBlock 等。更多详细信息在 [配置文件说明文档](config.md) 中说明
- MMDetection v2.0 使用新的 ResNet Caffe backbone 来减少加载预训练模型时的警告。新 backbone 中的大部分权重与以前的相同,但没有 `conv.bias`,且它们使用不同的 `img_norm_cfg`。因此,新的 backbone 不会报 `unexpected keys` 的警告。
### 训练超参
训练超参的调整不会影响模型的兼容性,但会略微提高性能。主要有:
- 通过设置 `nms_post=1000``max_num=1000`,将 nms 之后的 proposal 数量从 2000 更改为 1000。使 mask AP 和 bbox AP 提高了约 0.2%。
- Mask R-CNN、Faster R-CNN 和 RetinaNet 的默认回归损失从 smooth L1 损失更改为 L1 损失,使得 box AP 整体上都有所提升(约 0.6%)。但是,将 L1-loss 用在 Cascade R-CNN 和 HTC 等其他方法上并不能提高性能,因此我们保留这些方法的原始设置。
- 为简单起见,RoIAlign 层的 `sampling_ratio` 设置为 0。略微提升了 AP(约 0.2% 绝对值)。
- 为了提升训练速度,默认设置在训练过程中不再使用梯度裁剪。大多数模型的性能不会受到影响。对于某些模型(例如 RepPoints),我们依旧使用梯度裁剪来稳定训练过程从而获得更好的性能。
- 因为不再默认使用梯度裁剪,默认 warmup 比率从 1/3 更改为 0.001,以使模型训练预热更加平缓。不过我们重新进行基准测试时发现这种影响可以忽略不计。
### 将模型从 v1.x 升级至 v2.0
用户可以使用脚本 `tools/model_converters/upgrade_model_version.py` 来将 MMDetection 1.x 训练的模型转换为 MMDetection v2.0。转换后的模型可以在 MMDetection v2.0 中运行,但性能略有下降(小于 1% AP)。
详细信息可以在 `configs/legacy` 中找到。
## pycocotools 兼容性
`mmpycocotools` 是 OpenMMLab 维护的 `pycocotools` 的复刻版,适用于 MMDetection 和 Detectron2。
[PR #4939](https://github.com/open-mmlab/mmdetection/pull/4939) 之前,由于 `pycocotools``mmpycocotool` 具有相同的包名,如果用户已经安装了 `pyccocotools`(在相同环境下先安装了 Detectron2 ),那么 MMDetection 的安装过程会跳过安装 `mmpycocotool`。 导致 MMDetection 缺少 `mmpycocotools` 而报错。
但如果在 Detectron2 之前安装 MMDetection,则可以在相同的环境下工作。
[PR #4939](https://github.com/open-mmlab/mmdetection/pull/4939) 弃用 mmpycocotools,使用官方 pycocotools。
[PR #4939](https://github.com/open-mmlab/mmdetection/pull/4939) 之后,用户能够在相同环境下安装 MMDetection 和 Detectron2,不再需要关注安装顺序。
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment