论文下载地址:点击这里
本页提供有关MMDetection用法的基本教程。有关安装说明,请参阅INSTALL.md。
目录
- 预训练模型的推论
- 训练模型
- 有用的工具
- 如何
预训练模型的推论
我们提供测试脚本以评估整个数据集(COCO,PASCAL VOC等),还提供一些高级api,以便更轻松地集成到其他项目。
名词解析
- ${CONFIG_FILE}:代表着 config/里面文件的位置,比如configs/mask_rcnn_r50_fpn_1x.py。
- ${CHECKPOINT_FILE}:代表着模型权重所在的位置。比如checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth。
- [--out ${RESULT_FILE}]:代表着测试生成的文件的位置。
- [--eval ${EVAL_METRICS}]:所选用的测试方式,EVAL_METRICS 下面有解析。
- ${GPU_NUM}:GPU数量,比如 --gpu 2代表用两个GPU进行训练或者测试。
测试数据集
- 单GPU测试
- 多个GPU测试
- 可视化检测结果
您可以使用以下命令测试数据集。
# single-gpu testing 单GPU测试
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}] [--show]
# multi-gpu testing 多GPU测试
./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}]
可选参数:
RESULT_FILE
:输出结果的文件名采用pickle格式。如果未指定,结果将不会保存到文件中。EVAL_METRICS
(--eval):要根据结果评估的项目。允许的值是:proposal_fast
,proposal
,bbox
,segm
,keypoints
。--show
:如果指定,检测结果将绘制在图像上并显示在新窗口中。它仅适用于单个GPU测试。请确保您的环境中可以使用GUI,否则您可能会遇到类似的错误。cannot
connect
to
X
server
例子:
假设您已经将模型权重下载到checkpoints/
。
- 测试Faster R-CNN并显示结果。
python tools/test.py configs/faster_rcnn_r50_fpn_1x.py \
checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth \
--show
# 生成测试结果,.json和.pkl文件,加--eval bbox生成框的信息,用于目标检测。
python tools/test.py configs/faster_rcnn_r50_fpn_1x.py \
checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth \
--eval bbox --show
- 测试Mask R-CNN并评估bbox和mask AP。
python tools/test.py configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
--out results.pkl --eval bbox segm
- 使用8个GPU测试Mask R-CNN,并评估bbox和mask AP。
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
8 --out results.pkl --eval bbox segm
网络摄像头演示
我们提供了一个网络摄像头演示来说明结果。
python demo/webcam_demo.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--device ${GPU_ID}] [--camera-id ${CAMERA-ID}] [--score-thr ${SCORE_THR}]
例子:
python demo/webcam_demo.py configs/faster_rcnn_r50_fpn_1x.py \
checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth
用于测试图像的高级
同步接口
这是构建模型并测试给定图像的示例。
from mmdet.apis import init_detector, inference_detector, show_result
import mmcv
config_file = 'configs/faster_rcnn_r50_fpn_1x.py'
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth'
# build the model from a config file and a checkpoint file
model = init_detector(config_file, checkpoint_file, device='cuda:0')
# test a single image and show the results
img = 'test.jpg' # or img = mmcv.imread(img), which will only load it once
result = inference_detector(model, img)
# visualize the results in a new window
show_result(img, result, model.CLASSES)
# or save the visualization results to image files
show_result(img, result, model.CLASSES, out_file='result.jpg')
# test a video and show the results
video = mmcv.VideoReader('video.mp4')
for frame in video:
result = inference_detector(model, frame)
show_result(frame, result, model.CLASSES, wait_time=1)
笔记本演示可以在demo / inference_demo.ipynb中找到。
异步接口-受Python 3.7+支持
异步接口允许不阻塞GPU绑定推理代码上的CPU,并为单线程应用程序提供更好的CPU / GPU利用率。可以在不同的输入数据样本之间或某个推理管道的不同模型之间同时进行推理。
请参阅tests/async_benchmark.py
比较同步和异步接口的速度。
import asyncio
import torch
from mmdet.apis import init_detector, async_inference_detector, show_result
from mmdet.utils.contextmanagers import concurrent
async def main():
config_file = 'configs/faster_rcnn_r50_fpn_1x.py'
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_20181010-3d1b3351.pth'
device = 'cuda:0'
model = init_detector(config_file, checkpoint=checkpoint_file, device=device)
# queue is used for concurrent inference of multiple images
streamqueue = asyncio.Queue()
# queue size defines concurrency level
streamqueue_size = 3
for _ in range(streamqueue_size):
streamqueue.put_nowait(torch.cuda.Stream(device=device))
# test a single image and show the results
img = 'test.jpg' # or img = mmcv.imread(img), which will only load it once
async with concurrent(streamqueue):
result = await async_inference_detector(model, img)
# visualize the results in a new window
show_result(img, result, model.CLASSES)
# or save the visualization results to image files
show_result(img, result, model.CLASSES, out_file='result.jpg')
asyncio.run(main())
训练模型
MMDetection 分别使用,1.实施分布式并行运算MMDistributedDataParallel
,2.非分布式运算MMDataParallel
。
所有输出(日志文件和检查点)将保存到工作目录,该目录work_dir
在config文件中指定。
重要:配置文件中的默认学习率(lr=0.02)是8个GPU和2 img / gpu(批大小= 8 * 2 = 16)。根据线性缩放规则,如果您使用不同的GPU或每个GPU的有多少张图像,则需要按批大小设置学习率,例如,对于4GPU* 2 img / gpu=8,lr =8/16 * 0.02 = 0.01 ;对于16GPU* 4 img / gpu=64,lr =64/16 *0.02 = 0.08 。
总结学习率简单计算为:比如我一个轮次是12张图片,就是12/16*0.02
使用单个GPU进行训练
python tools/train.py ${CONFIG_FILE}
例子:
python tools/train.py chongqing_tainchi/cascade_rcnn_r50_fpn_1x.py
如果要在命令中指定工作目录,则可以添加参数。--work_dir${YOUR_WORK_DIR}
使用多个GPU进行训练
./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [optional arguments]
例子:
./tools/dist_train.sh ./chongqing_tainchi/cascade_rcnn_r50_fpn_1x.py 2
可选参数为:
--validate
(强烈建议):在训练过程中,每隔k个代执行一次评估(默认值为1,可以像这样修改)。--work_dir
${WORK_DIR}
:覆盖配置文件中指定的工作目录。--resume_from
${CHECKPOINT_FILE}
:从先前的检查点文件恢复。
resume_from
和之间的差异load_from
: resume_from
加载模型权重和优化器状态,并且纪元也从指定的检查点继承。它通常用于恢复意外中断的训练过程。 load_from
仅加载模型权重,并且训练时期从0开始。通常用于微调。
用多台机器训练
如果在使用slurm管理的群集上运行MMDetection,则可以使用该脚本slurm_train.sh
。
./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [${GPUS}]
这是使用16个GPU在dev分区上训练Mask R-CNN的示例。
./tools/slurm_train.sh dev mask_r50_1x configs/mask_rcnn_r50_fpn_1x.py /nfs/xxxx/mask_rcnn_r50_fpn_1x 16
您可以检查slurm_train.sh中的完整参数和环境变量。
如果只有多台计算机连接了以太网,则可以参考pytorch 启动实用程序。如果没有像infiniband这样的高速网络,通常速度很慢。
有用的工具
分析日志
您可以绘制给定训练日志文件的损耗/ mAP曲线。首先运行以安装依赖项。
pip install seaborn
损耗曲线图
python tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]
例子:
- 绘制一些运行的分类损失。
python tools/analyze_logs.py plot_curve log.json --keys loss_cls --legend loss_cls
- 绘制一些运行的分类和回归损失,并将该图保存为pdf。
python tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_reg --out losses.pdf
- 比较同一图中两次运行的bbox mAP。
python tools/analyze_logs.py plot_curve log1.json log2.json --keys bbox_mAP --legend run1 run2
您还可以计算平均训练速度。
python tools/analyze_logs.py cal_train_time ${CONFIG_FILE} [--include-outliers]
预期输出将如下所示。
-----Analyze train time of work_dirs/some_exp/20190611_192040.log.json-----
slowest epoch 11, average time is 1.2024
fastest epoch 1, average time is 1.1909
time std over epochs is 0.0028
average iter time: 1.1959 s/iter
分析类性能
您可以分析基于类的mAP,以更全面地了解该模型。
python coco_eval.py ${RESULT} --ann ${ANNOTATION_PATH} --types bbox --classwise
现在,我们仅支持所有评估类型的按类mAP,将来我们将支持按类mAR。
获取FLOP和参数(实验)
我们提供了一个适用于flops-counter.pytorch的脚本,用于计算给定模型的FLOP和参数。
python tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}]
您将得到这样的结果。
==============================
Input shape: (3, 1280, 800)
Flops: 239.32 GMac
Params: 37.74 M
==============================
注意:此工具仍处于试验阶段,我们不保证该数字正确。您可以将结果用于简单比较,但在将其用于技术报告或论文之前,请仔细检查。
(1)FLOP与输入形状有关,而参数与输入形状无关。默认输入形状为(1、3、1280、800)。(2)某些运算符不像GN和自定义运算符那样计入FLOP中。您可以通过修改添加对新运算符的支持mmdet/utils/flops_counter.py
。(3)两级检测器的FLOP取决于提议的数量。
压缩一个模型—publish_model.py压缩模型
在将模型上载到AWS之前,您可能需要(1)将模型权重转换为CPU张量,(2)删除优化器状态,(3)计算检查点文件的哈希并将哈希ID附加到文件名中。
python tools/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
例如,
python tools/publish_model.py work_dirs/faster_rcnn/latest.pth faster_rcnn_r50_fpn_1x_20190801.pth
最终的输出文件名将为。faster_rcnn_r50_fpn_1x_20190801-{hash
id}.pth
测试检测器的健壮性
请参考ROBUSTNESS_BENCHMARKING.md。
操作方法
使用我自己的数据集
最简单的方法是将数据集转换为现有的数据集格式(COCO或PASCAL VOC)。
在这里,我们展示了一个添加5类自定义数据集的示例,假设它也是COCO格式。
在mmdet/datasets/my_dataset.py
:
from .coco import CocoDataset
from .registry import DATASETS
@DATASETS.register_module
class MyDataset(CocoDataset):
CLASSES = ('a', 'b', 'c', 'd', 'e')
在mmdet/datasets/__init__.py
:
from .my_dataset import MyDataset
然后,您可以MyDataset
在配置文件中使用与CocoDataset相同的API。
如果您不想将注释格式转换为COCO或PASCAL格式,也可以。实际上,我们定义了一种简单的注释格式,并且对所有现有数据集进行了处理以使其兼容(联机或脱机)。
数据集的注释是字典列表,每个字典对应一个图像。有3个字段filename
(相对路径), width
,height
进行检测,并附加字段ann
进行训练。ann
也是一个至少包含2个字段的字典:bboxes
和labels
,这两个字段 都是numpy数组。一些数据集可能会提供注释,例如人群/困难/被忽略的bbox,我们使用bboxes_ignore
并labels_ignore
覆盖了它们。
这是一个例子。
[
{
'filename': 'a.jpg',
'width': 1280,
'height': 720,
'ann': {
'bboxes': <np.ndarray, float32> (n, 4),
'labels': <np.ndarray, int64> (n, ),
'bboxes_ignore': <np.ndarray, float32> (k, 4),
'labels_ignore': <np.ndarray, int64> (k, ) (optional field)
}
},
...
]
有两种使用自定义数据集的方法。
- 在线转换
您可以编写一个继承自的新Dataset类CustomDataset
,并覆盖两个方法 和,例如CocoDataset和VOCDataset。load_annotations(self,
ann_file)get_ann_info(self,
idx)
- 离线转换
您可以将注释格式转换为上面的预期格式,并将其保存到pickle或json文件中,例如pascal_voc.py。然后,您可以简单地使用CustomDataset
。
开发新的组件
我们基本上将模型组件分为4种类型。
- 骨干网:通常是FCN网络,用于提取特征图,例如ResNet,MobileNet。
- 脖子:骨干和头部之间的组件,例如FPN,PAFPN。
- head:用于特定任务的组件,例如bbox预测和掩码预测。
- roi提取器:用于从要素图(例如RoI Align)中提取RoI要素的部分。
在这里,我们以MobileNet为例说明如何开发新组件。
- 创建一个新文件
mmdet/models/backbones/mobilenet.py
。
import torch.nn as nn
from ..registry import BACKBONES
@BACKBONES.register_module
class MobileNet(nn.Module):
def __init__(self, arg1, arg2):
pass
def forward(x): # should return a tuple
pass
def init_weights(self, pretrained=None):
pass
- 在中导入模块
mmdet/models/backbones/__init__.py
。
from .mobilenet import MobileNet
- 在您的配置文件中使用它。
model = dict(
...
backbone=dict(
type='MobileNet',
arg1=xxx,
arg2=xxx),
...
有关其工作原理的更多信息,可以参考TECHNICAL_DETAILS.md(TODO)。