MMDetection是一款优秀的基于PyTorch的深度学习目标检测工具箱,由香港中文大学(CUHK)多媒体实验室(mmlab)开发。基本上支持所有当前SOTA二阶段的目标检测算法,比如faster rcnn,mask rcnn,r-fcn,Cascade-RCNN等。读者可在 PyTorch 环境下测试不同的预训练模型及训练新的检测分割模型。
根据 GitHub 项目所述,MMDetection的主要特征可以总结为以下几个方面:
模块化设计:将检测或者分割任务分解成几个模块,通过模块的组合即可完成相应的任务。
支持多个框架,开箱即用:该工具包直接支持多种流行的检测框架,如 Faster RCNN、Mask RCNN、RetinaNet 等。
高效:所有基础边界框和掩码运算都在 GPU 上运行。不同模型的训练速度大约比 FAIR 的 Detectron 快 5% ~ 20%。
技术发展水平:达到了目前最先进的水平。
了解如何在计算机上安装MMDetection
Linux(不正式支持Windows)
Python 3.5+
PyTorch 1.1或更高版本
CUDA 9.0或更高
NCCL 2
GCC 4.9或更高
mmcv(https://github.com/open-mmlab/mmcv)
我们已经测试了以下版本的操作系统和软件:
OS: Ubuntu 16.04/18.04 and CentOS 7.2
CUDA: 9.0/9.2/10.0/10.1
NCCL: 2.1.15/2.2.13/2.3.7/2.4.2
GCC(G++): 4.9/5.3/5.4/7.3
a. 创建一个conda虚拟环境并激活它
conda create -n open-mmlab python=3.7-y
conda activate open-mmlab
b. 按照官方说明安装PyTorch和Torchvision(https://pytorch.org/) ,例如,
conda install pytorch torchvision -c pytorch
If you have CUDA 10.1 installed under /usr/local/cuda and would like to install PyTorch 1.5, you need to install the prebuilt PyTorch with CUDA 10.1.
conda install pytorch cudatoolkit=10.1 torchvision -c pytorch
If you have CUDA 9.2 installed under /usr/local/cuda and would like to install PyTorch 1.3.1., you need to install the prebuilt PyTorch with CUDA 9.2.
conda install pytorch=1.3.1 cudatoolkit=9.2 torchvision=0.4.2 -c pytorch
c. 克隆mmdetection存储库
git clone https://github.com/open-mmlab/mmdetection.git
cd mmdetection
d. 安装构建要求,然后安装mmdetection。(我们通过github repo安装pycocotools而不是pypi,因为pypi版本较旧并且与最新的numpy不兼容。)
pip install -r requirements/build.txt -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
pip install "git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI"
pip install -v -e .## or "python setup.py develop"
安装完成
Using /home/lhy/anaconda3/envs/mmdetection/lib/python3.7/site-packages
Finished processing dependencies for mmdet==2.24.1
注意:
1.git commit的id将在步骤d中写入版本号,例如0.6.0 + 2e7045c。该版本还将保存在经过训练的模型中。建议你每次从github获取一些更新时都运行步骤d。如果修改了C++/CUDA代码,则此步骤为强制性的。
2.按照上述说明,mmdetection将安装在dev模式下,对代码进行的任何本地修改都将生效,而无需重新安装它(除非你提交了一些提交并希望更新版本号)。
3.如果要使用 opencv-python-headless 来代替 opencv-python,可以在安装MMCV之前先安装它。
4.一些依赖关系是可选的。只需运行 pip install -v -e .,将只会安装最低运行时间要求。要使用可选的依赖项如albumentations和imagecorruptions,并使用pip install -r requirements/optional.txt 手动安装它们,或者在调用pip时指定所需的附加项(例如pip install -v -e .[optional])。对于额外字段的有效键为:all,tests,build,和 optional。
或者可以
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/{cu_version}/{torch_version}/index.html
Please replace {cu_version} and {torch_version} in the url to your desired one. For example, to install the latest mmcv-full with CUDA 11.0 and PyTorch 1.7.0, use the following command:
pip install mmcv-full -f https://download.openmmlab.com/mmcv/dist/cu110/torch1.7.0/index.html
我们提供了一个Dockerfile(https://github.com/open-mmlab/mmdetection/blob/master/docker/Dockerfile)来构建映像。
使用PyTorch 1.1、CUDA 10.0和CUDNN 7.5构建图像
docker build -t mmdetection docker/
这是一个完整的脚本,用于使用conda设置mmdetection并链接数据集路径(假设你的COCO数据集路径为$ COCO_ROOT)。
conda create -n open-mmlab python=3.7-y
conda activate open-mmlab
conda install -c pytorch pytorch torchvision -y
git clone https://github.com/open-mmlab/mmdetection.git
cd mmdetection
pip install -r requirements/build.txt
pip install "git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI"
如果网不好,可以按照下面的步骤安装
git clone https://github.com/cocodataset/cocoapi.git
cd cocoapi/PythonAPI
python setup.py build_ext --inplace
python setup.py build_ext install
pip install -v -e .
mkdir data
ln -s $COCO_ROOT data
如果你的机器上有多个mmdetection,并且你想交替使用它们,则建议的方法是创建多个conda环境并对不同版本使用不同的环境。
另一种方法是插入下面的代码到主脚本(train.py,test.py或任何其他脚本运行)
import os.path as osp
import sys
sys.path.insert(0,osp.join(osp.dirname(osp.abspath(__file__)),'../'))
或者在相应文件夹的终端中运行以下命令以临时使用当前文件夹。
export PYTHONPATH=`pwd`:$PYTHONPATH
测试数据集
[x]单个GPU测试
[x]多个GPU测试
[x]可视化检测结果
你可以使用以下命令测试数据集。
RESULT_FILE: Filename of the output results in pickle format. If not specified, the results will not be saved to a file.(输出结果的文件名为pickle格式。如果未指定,结果将不会保存到文件中。)
EVAL_METRICS: Items to be evaluated on the results. Allowed values depend on the dataset, e.g., proposal_fast, proposal, bbox, segm are available for COCO, mAP, recall for PASCAL VOC. Cityscapes could be evaluated by cityscapes as well as all COCO metrics.(根据结果进行评估的项目。允许的值取决于数据集,例如,proposal_fast, proposal, box, segm可用于COCO, mAP, PASCAL VOC的recall。城市景观可以通过城市景观以及所有COCO指标进行评估)
–show: If specified, detection results will be plotted on the images and shown in a new window. It is only applicable to single GPU testing and used for debugging and visualization. Please make sure that GUI is available in your environment. Otherwise, you may encounter an error like cannot connect to X server.
–show-dir: If specified, detection results will be plotted on the images and saved to the specified directory. It is only applicable to single GPU testing and used for debugging and visualization. You do NOT need a GUI available in your environment for using this option.(如果指定,检测结果将绘制在图像上并保存到指定目录。仅适用于单个GPU测试,用于调试和可视化。您的环境中不需要可用的GUI来使用此选项)
–show-score-thr: If specified, detections with scores below this threshold will be removed.
–cfg-options: if specified, the key-value pair optional cfg will be merged into config file(如果指定,键值对可选CFG将被合并到配置文件中)
–eval-options: if specified, the key-value pair optional eval cfg will be kwargs for dataset.evaluate() function, it’s only for evaluation
#单GPU测试
python tools / test.py $ {CONFIG_FILE} $ {CHECKPOINT_FILE} [--out $ {RESULT_FILE}] [--eval $ {EVAL_METRICS}] [--show]
#多GPU测试和评估
./tools/dist_test.sh $ {CONFIG_FILE} $ {CHECKPOINT_FILE} $ {GPU_NUM} [--out $ {RESULT_FILE}] [--eval $ {EVAL_METRICS}]
可选参数:
RESULT_FILE:输出结果的文件名是pickle格式。如果未指定,结果将不会保存到文件中。
EVAL_METRICS:要根据结果评估的项目。允许的值取决于数据集,例如proposal_fast,proposal,bbox,segm可用于COCO和mAP,recall为PASCAL VOC。
–show:如果指定,检测结果将绘制在图像上并显示在新窗口中。它仅适用于单个GPU测试,并用于调试和可视化。请确保GUI在你的环境中可用,否则你可能会遇到类似cannot connect to X server的错误。
如果要评估数据集,请不要同时指定–show。
假设你已经将检查点下载到目录checkpoints/。
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
python tools/test.py configs/pascal_voc/faster_rcnn_r50_fpn_1x_voc.py \
checkpoints/SOME_CHECKPOINT.pth \
--eval mAP
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
./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
tools/dist_test.sh也支持多节点测试,但依赖于PyTorch的启动工具。
./tools/dist_test.sh configs/mask_rcnn_r50_fpn_1x.py \
checkpoints/mask_rcnn_r50_fpn_1x_20181010-069fa190.pth \
8 --format-only --options "jsonfile_prefix=./mask_rcnn_test-dev_results"
/media/lhy/Swin-Transformer-Object-Detection# python ./tools/test.py4_window7_mstrain_480-800_adamw_3x_coco.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/latest.pth --format_only --options "jsonfile_prefix=./result/maskrcnn_result"
你将获得两个json文件mask_rcnn_test-dev_results.bbox.json和mask_rcnn_test-dev_results.segm.json。
./tools/dist_test.sh \
configs/cityscapes/mask_rcnn_r50_fpn_1x_cityscapes.py \
checkpoints/mask_rcnn_r50_fpn_1x_cityscapes_20200227-afe51d5a.pth \
8 \
--format-only \
--options "txtfile_prefix=./mask_rcnn_cityscapes_test_results"
或者
python tools/test.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/latest.pth --out inference_dirs/mask_rcnn_swin_tiny_coco_result.pkl --format-only --show-dir ./inference_dirs/ --options "txtfile_prefix=./inference_dirs/mask_rcnn_swin_tiny_coco_test_results"
生成的png和txt文件将在./mask_rcnn_cityscapes_test_results目录下。
我们提供了一个网络摄像头演示来说明结果。
python demo / webcam_demo.py $ {CONFIG_FILE} $ {CHECKPOINT_FILE} [-设备$ {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
python demo/webcam_demo.py configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py weights/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth
python demo/video_demo.py
${VIDEO_FILE}
${CONFIG_FILE}
${CHECKPOINT_FILE}
[–device ${GPU_ID}]
[–score-thr ${SCORE_THR}]
[–out ${OUT_FILE}]
[–show]
[–wait-time ${WAIT_TIME}]
python demo/video_demo.py demo/demo.mp4 \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
--out result.mp4
python demo/video_demo.py demo/demo.mp4 \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
--show
同步接口
MMDetection提供了用于图像推断的高级Python apl。下面是一个在给定的图像或视频上构建模型和推理的例子。
from mmdet.apis import init_detector, inference_detector
import mmcv
# Specify the path to model config and checkpoint file
config_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py'
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.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
model.show_result(img, result)
# or save the visualization results to image files
model.show_result(img, result, 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)
model.show_result(frame, result, wait_time=1)
异步接口
对于Python 3.7+, MMDetection也支持异步接口。通过使用CUDA流,它允许在GPU绑定推断代码上不阻塞CPU,并使单线程应用程序能够更好地利用CPU/GPU。推理可以在不同的输入数据样本之间,也可以在某些推理管道的不同模型之间并行进行。
请参阅tests/async_benchmark.py比较同步和异步接口的速度。
import asyncio
import torch
from mmdet.apis import init_detector, async_inference_detector
from mmdet.utils.contextmanagers import concurrent
async def main():
config_file = 'configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py'
checkpoint_file = 'checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.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
model.show_result(img, result)
# or save the visualization results to image files
model.show_result(img, result, out_file='result.jpg')
asyncio.run(main())
这里是引用配置文件中默认的学习速率为8gpu和每张gpu 2张img (batch size = 8*2 = 16)。根据线性缩放规则,如果你使用不同的GPU或每个GPU的图像,则需要按批大小设置成比例的学习率
例如,对于4个GPU,lr = 0.01 * 2 img / gpu;对于16个GPU,lr = 0.08 * 4 img / gpu。
例如:lr =0.01,4个GPU ,每张gpu 2张img
当有 16个GPU ,每张gpu4 张imgs ,Ir=0.08。
MMDetection实施分布式训练和非分布式训练, 它分别使用MMDistributedDataParallel和MMDataParallel。
所有输出(日志文件和检查点)将保存到工作目录中, 在配置文件中由work_dir指定。
默认情况下,模型每隔一段时间就会在验证集上评估,评估间隔可以在配置文件中指定,如下所示。
Evaluation = dict(interval = 12)#每12个时间段评估一次模型。
为了评估模型的准确性,人们通常在一些标准数据集上测试模型。MMDetection支持多种公共数据集,包括cocO, Pascal VOC, CityScapes等。本节将展示如何在受支持的数据集上测试现有模型。
Pascal VOC或mirror和COCO等公共数据集可以在官方网站或mirror上获得。注意:在检测任务中,Pascal VOC 2012是Pascal VOC 2007的扩展,没有重叠,我们通常一起使用。建议下载并提取项目目录外的数据集,并将数据集根符号链接到SMMDETECTION/data,如下所示。如果您的文件夹结构不同,可能需要在配置文件中更改相应的路径。更多使用请参考dataset-download
mmdetection
├── mmdet
├── tools
├── configs
├── data
│ ├── coco
│ │ ├── annotations
│ │ ├── train2017
│ │ ├── val2017
│ │ ├── test2017
│ ├── cityscapes
│ │ ├── annotations
│ │ ├── leftImg8bit
│ │ │ ├── train
│ │ │ ├── val
│ │ ├── gtFine
│ │ │ ├── train
│ │ │ ├── val
│ ├── VOCdevkit
│ │ ├── VOC2007
│ │ ├── VOC2012
有些型号需要额外的coco数据集,如HTC, detector和SCNet,你可以下载解压,然后移动到coco文件夹。目录应该是这样的。
mmdetection
├── data
│ ├── coco
│ │ ├── annotations
│ │ ├── train2017
│ │ ├── val2017
│ │ ├── test2017
│ │ ├── stuffthingmaps
PanopticFPN等Panoptic分割模型需要额外的COCO Panoptic数据集,您可以下载并解压,然后移动到COCO注释文件夹。目录应该是这样的。
mmdetection
├── data
│ ├── coco
│ │ ├── annotations
│ │ │ ├── panoptic_train2017.json
│ │ │ ├── panoptic_train2017
│ │ │ ├── panoptic_val2017.json
│ │ │ ├── panoptic_val2017
│ │ ├── train2017
│ │ ├── val2017
│ │ ├── test2017
tools/misc/download_dataset.py supports downloading datasets such as COCO, VOC, and LVIS.
python tools/misc/download_dataset.py --dataset-name coco2017
python tools/misc/download_dataset.py --dataset-name voc2007
python tools/misc/download_dataset.py --dataset-name lvis
tools/data_converters/ contains tools to convert the Cityscapes dataset and Pascal VOC dataset to the COCO format.
tools/data_converters/包含将Cityscapes数据集和Pascal VOC数据集转换为COCO格式的工具。
python tools/dataset_converters/cityscapes.py ${CITYSCAPES_PATH} [-h] [--img-dir ${IMG_DIR}] [--gt-dir ${GT_DIR}] [-o ${OUT_DIR}] [--nproc ${NPROC}]
python tools/dataset_converters/pascal_voc.py ${DEVKIT_PATH} [-h] [-o ${OUT_DIR}]
假设我们想实现一个名为AugFPN的新颈部,用现有检测器Cascade Mask R-CNN R50下的默认FPN替换。下面实现了AugFPN underMMDetection。
首先创建一个新文件mmdet/models/necks/augfpn.py。
from ..builder import NECKS
@NECKS.register_module()
class AugFPN(nn.Module):
def __init__(self,
in_channels,
out_channels,
num_outs,
start_level=0,
end_level=-1,
add_extra_convs=False):
pass
def forward(self, inputs):
# implementation is ignored
pass
您可以将以下行添加到
from .augfpn import AugFPN
或者添加
custom_imports = dict(
imports=['mmdet.models.necks.augfpn.py'],
allow_failed_imports=False)
配置文件,避免修改原始代码。
neck=dict(
type='AugFPN',
in_channels=[256, 512, 1024, 2048],
out_channels=256,
num_outs=5)
关于定制您自己的模型(例如,实现一个新的骨干,头部,损失等)和运行时训练设置(例如,定义一个新的优化器,使用梯度剪辑,定制训练时间表和钩子等),请分别参考指南定制模型和定制运行时设置。
第三步是为您自己的培训设置准备配置。假设我们想要添加AugFPN并对现有的级联掩码R-CNN R50进行旋转或Translate增强以训练cityscapes数据集,并假设配置文件在configs/cityscapes/目录下,命名为cascade_mask_rcnn_r50_augfpn_autoaug_10e_cityscapes.py,配置文件如下所示。
# The new config inherits the base configs to highlight the necessary modification
#新配置继承了基本配置,以突出显示必要的修改。模型的具体设置继承了cascade_mask_rcnn_r50_fpn.py,数据的基本设置继承了cityscapes_instance.py,运行的一些设置继承了default_runtime.py
_base_ = [
'../_base_/models/cascade_mask_rcnn_r50_fpn.py',
'../_base_/datasets/cityscapes_instance.py', '../_base_/default_runtime.py'
]
model = dict(
# set None to avoid loading ImageNet pretrained backbone,
#设置None以避免加载ImageNet预训练骨干
# instead here we set `load_from` to load from COCO pretrained detectors.
#这里我们将' load_from '设置为从COCO预训练的检测器加载。
backbone=dict(init_cfg=None),
# replace neck from defaultly `FPN` to our new implemented module `AugFPN`
neck=dict(
type='AugFPN',#这里修改为我们的neck
in_channels=[256, 512, 1024, 2048],
out_channels=256,
num_outs=5),
# We also need to change the num_classes in head from 80 to 8, to match the
# cityscapes dataset's annotation. This modification involves `bbox_head` and `mask_head`.
#我们还需要将head中的num_classes从80更改为8,以匹配cityscape数据集的注释。这个修改涉及到' bbox_head '和' mask_head '
roi_head=dict(
bbox_head=[
dict(
type='Shared2FCBBoxHead',
in_channels=256,
fc_out_channels=1024,
roi_feat_size=7,
# change the number of classes from defaultly COCO to cityscapes
num_classes=8,
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[0., 0., 0., 0.],
target_stds=[0.1, 0.1, 0.2, 0.2]),
reg_class_agnostic=True,
loss_cls=dict(
type='CrossEntropyLoss',
use_sigmoid=False,
loss_weight=1.0),
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
loss_weight=1.0)),
dict(
type='Shared2FCBBoxHead',
in_channels=256,
fc_out_channels=1024,
roi_feat_size=7,
# change the number of classes from defaultly COCO to cityscapes
num_classes=8,
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[0., 0., 0., 0.],
target_stds=[0.05, 0.05, 0.1, 0.1]),
reg_class_agnostic=True,
loss_cls=dict(
type='CrossEntropyLoss',
use_sigmoid=False,
loss_weight=1.0),
loss_bbox=dict(type='SmoothL1Loss', beta=1.0,
loss_weight=1.0)),
dict(
type='Shared2FCBBoxHead',
in_channels=256,
fc_out_channels=1024,
roi_feat_size=7,
# change the number of classes from defaultly COCO to cityscapes
num_classes=8,
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[0., 0., 0., 0.],
target_stds=[0.033, 0.033, 0.067, 0.067]),
reg_class_agnostic=True,
loss_cls=dict(
type='CrossEntropyLoss',
use_sigmoid=False,
loss_weight=1.0),
loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))
],
mask_head=dict(
type='FCNMaskHead',
num_convs=4,
in_channels=256,
conv_out_channels=256,
# change the number of classes from defaultly COCO to cityscapes
num_classes=8,
loss_mask=dict(
type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))))
# over-write `train_pipeline` for new added `AutoAugment` training setting
# 覆盖' train_pipeline '为新添加的' AutoAugment '培训设置
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, with_mask=True),
dict(
type='AutoAugment',
policies=[
[dict(
type='Rotate',#新增加了旋转的增强操作
level=5,
img_fill_val=(124, 116, 104),
prob=0.5,
scale=1)
],
[dict(type='Rotate', level=7, img_fill_val=(124, 116, 104)),
dict(
type='Translate',#新增加了变换的增强操作
level=5,
prob=0.5,
img_fill_val=(124, 116, 104))
],
]),
dict(
type='Resize', img_scale=[(2048, 800), (2048, 1024)], 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', 'gt_masks']),
]
# set batch_size per gpu, and set new training pipeline
#设置每个gpu的batch_size,并设置新的训练管道
data = dict(
samples_per_gpu=1,
workers_per_gpu=3,
# over-write `pipeline` with new training pipeline setting
train=dict(dataset=dict(pipeline=train_pipeline)))
# Set optimizer,设置优化器
optimizer = dict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)
optimizer_config = dict(grad_clip=None)
# Set customized learning policy,设置自定义学习策略
lr_config = dict(
policy='step',
warmup='linear',
warmup_iters=500,
warmup_ratio=0.001,
step=[8])
runner = dict(type='EpochBasedRunner', max_epochs=10)
# We can use the COCO pretrained Cascade Mask R-CNN R50 model for more stable performance initialization,我们可以使用COCO预训练的级联掩模R-CNN R50模型来实现更稳定的性能初始化(迁移学习)
load_from = 'https://download.openmmlab.com/mmdetection/v2.0/cascade_rcnn/cascade_mask_rcnn_r50_fpn_1x_coco/cascade_mask_rcnn_r50_fpn_1x_coco_20200203-9d4dcb24.pth'
要用新的配置训练模型,您可以简单地运行
python tools/train.py configs/cityscapes/cascade_mask_rcnn_r50_augfpn_autoaug_10e_cityscapes.py
python tools/test.py configs/cityscapes/cascade_mask_rcnn_r50_augfpn_autoaug_10e_cityscapes.py work_dirs/cascade_mask_rcnn_r50_augfpn_autoaug_10e_cityscapes.py/latest.pth --eval bbox segm
python tools/train.py \
${CONFIG_FILE} \
[optional arguments]
python tools/train.py configs/swin/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py
在培训过程中,日志文件和检查点将被保存到工作目录中,工作目录由配置文件中的work_dir指定或通过CLI参数——work-dir指定。在命令中指定工作目录,则可以添加参数–work_dir $ {YOUR_WORK_DIR}
默认情况下,模型每隔一段时间就会在验证集上评估,评估间隔可以在配置文件中指定,如下所示。
# evaluate the model every 12 epoch.
evaluation = dict(interval=12)
该工具接受几个可选参数,包括:
--no-validate (not suggested): Disable evaluation during training.在培训期间禁用评估
--work-dir ${WORK_DIR}: Override the working directory.设置工作目录
--resume-from ${CHECKPOINT_FILE}: Resume from a previous checkpoint file.从上一个检查点文件恢复
--options 'Key=value': Overrides other settings in the used config.覆盖所使用配置中的其他设置
CPU上的训练过程与单GPU训练过程一致。我们只需要在训练前禁用图形处理器。
export CUDA_VISIBLE_DEVICES=-1
bash ./tools/dist_train.sh \
${CONFIG_FILE} \
${GPU_NUM} \
[optional arguments]
./tools/dist_train.sh $ {CONFIG_FILE} $ {GPU_NUM} [可选参数]
案例:多gpu断点恢复模型训练
./tools/dist_train.sh configs/swin/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py 3 --resume-from work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/latest.pth
在单台计算机上启动多个作业
如果你使用dist_train.sh启动训练作业,则可以在命令中设置端口。
如果你想在一台机器上启动多个任务,例如,在一台有8个gpu的机器上启动2个4-GPU训练的任务,你需要为每个任务指定不同的端口(默认29500),以避免通信冲突。如果使用dist_train.sh启动培训作业,可以在命令中设置端口。
CUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 ./tools/dist_train.sh ${CONFIG_FILE} 4
CUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 ./tools/dist_train.sh ${CONFIG_FILE} 4
如果在由slurm(https://slurm.schedmd.com/) 管理的群集上运行MMDetection,则可以使用脚本"slurm_train.sh"。(此脚本还支持单机训练。)
[GPUS=${GPUS}] ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR}
./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [${GPUS}]
下面是一个使用16个gpu在一个名为dev的Slurm分区上训练Mask R-CNN的示例,并将工作目录设置为一些共享文件系统。
GPUS=16 ./tools/slurm_train.sh dev mask_r50_1x configs/mask_rcnn_r50_fpn_1x_coco.py /nfs/xxxx/mask_rcnn_r50_fpn_1x
你可以检查slurm_train.sh(https://github.com/open-mmlab/mmdetection/blob/master/tools/slurm_train.sh) 中的完整参数和环境变量。
使用Slurm时,port选项可以通过以下方式设置:
CUDA_VISIBLE_DEVICES=0,1,2,3 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config1.py ${WORK_DIR} --options 'dist_params.port=29500'
CUDA_VISIBLE_DEVICES=4,5,6,7 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config2.py ${WORK_DIR} --options 'dist_params.port=29501'
如果只有多台计算机与以太网连接,则可以参考 pytorch 启动实用程序(https://pytorch.org/docs/stable/distributed_deprecated.html#launch-utility)。如果没有像infiniband这样的高速网络,通常速度很慢。
如果你将启动训练作业与slurm一起使用,则需要修改配置文件(通常是配置文件底部的第6行)以设置不同的通信端口。
在config1.py中,
dist_params = dict(backend='nccl', port=29500)
In config2.py, set
dist_params = dict(backend='nccl',port= 29501)
然后,你可以使用config1.py和config2.py启动两个作业。
CUDA_VISIBLE_DEVICES=0,1,2,3 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config1.py ${WORK_DIR}
CUDA_VISIBLE_DEVICES=4,5,6,7 GPUS=4 ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} config2.py ${WORK_DIR}
#demo 的单张图片测试
python demo/image_demo.py demo/demo.jpg configs/swin/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py mask_rcnn_swin_tiny_patch4_window7.pth
成功的话 能看到实例图片,当 mask_rcnn_swin_tiny_patch4_window7.pth 不在项目根目录下的时候,需要在前面指定具体位置。
demo/image_demo.py 做如下修改:
# test a single image
result = inference_detector(model, args.img)
new_result = result[0]
# show the results
show_result_pyplot(model, args.img, new_result, score_thr=args.score_thr)
python demo/image_detection_demo.py demo/demo.jpg configs/swin/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco.py mask_rcnn_swin_tiny_patch4_window7.pth
**
TypeError: SwinTransformer: init() got an unexpected keyword argument ‘embed_dim‘
**
在不同目录下它寻找的mmdet包不同
在swin_master/(你的项目)目录下它会寻找该项目内本来包含的mmdet文件夹
但是在swin_master/tools文件夹下,它会寻找openmmlab环境中的mmdet
设置环境变量,指定它去该目录下寻找mmdet包
进入配置信息 sudo vi /etc/profile
export PYTHONPATH= export PYTHONPATH=/media/lhy/Swin-Transformer-Object-Detection
(包含mmdet文件夹的你的项目路径)
基本步骤如下:
1、准备定制的dataset
2、准备一个config
3、在定制的数据集上训练、测试和推断模型。
1、 将数据集重组为coCO格式。
2、将数据集重新组织为中间格式。
3、实现一个新的数据集。
通常我们推荐使用前两种方法,它们通常比第三种更容易。
注意:MMDetection目前只支持评估coco格式数据集的掩码AP。例如实例分割任务用户应该将数据转换成coco格式。
数据集的下载、格式、格式转换参考3.3的内容
第二步是准备一个配置,这样数据集就可以成功加载。假设我们想要使用带有FPN的Mask R-CNN,在气球数据集上训练检测器的配置如下所示。
假设配置位于configs/balloon/目录下,命名为mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py,配置如下所示。
# The new config inherits a base config to highlight the necessary modification
#1、新配置继承了一个基本配置,以突出显示必要的修改
_base_ = 'mask_rcnn/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_coco.py'
# We also need to change the num_classes in head to match the dataset's annotation
#2、我们还需要更改head中的num_classes,以匹配数据集的注释
model = dict(
roi_head=dict(
bbox_head=dict(num_classes=1),
mask_head=dict(num_classes=1)))
# Modify dataset related settings
#3、修改数据集相关设置
dataset_type = 'COCODataset'
classes = ('balloon',) #修改为自己数据集的名称
data = dict(
train=dict(
img_prefix='balloon/train/',
classes=classes,
ann_file='balloon/train/annotation_coco.json'),
val=dict(
img_prefix='balloon/val/',
classes=classes,
ann_file='balloon/val/annotation_coco.json'),
test=dict(
img_prefix='balloon/val/',
classes=classes,
ann_file='balloon/val/annotation_coco.json'))
# We can use the pre-trained Mask RCNN model to obtain higher performance
#4、我们可以使用预训练的Mask RCNN模型来获得更高的性能
load_from = 'checkpoints/mask_rcnn_r50_caffe_fpn_mstrain-poly_3x_coco_bbox_mAP-0.408__segm_mAP-0.37_20200504_163245-42aa3d00.pth'
要用新的配置训练模型,您可以简单地运行
python tools/train.py configs/balloon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py
tensorboard --logdir work_dirs/mask_rcnn_swin_tiny_patch4_window7_mstrain_480-800_adamw_3x_coco/tf_logs --host 10.1.42.60
python tools/test.py configs/balloon/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon.py work_dirs/mask_rcnn_r50_caffe_fpn_mstrain-poly_1x_balloon/latest.pth --eval bbox segm
除了培训/测试脚本,我们在tools/目录下提供了许多有用的工具。
tools/analysis_tools/analyze_logs.py 给出一个训练日志文件,绘制损失/mAP曲线。
Run pip install seaborn first to install the dependency.
python tools/analysis_tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]
python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_cls --legend loss_cls
python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_bbox --out losses.pdf
python tools/analysis_tools/analyze_logs.py plot_curve log1.json log2.json --keys bbox_mAP --legend run1 run2
python tools/analysis_tools/analyze_logs.py cal_train_time log.json [--include-outliers]
The output is expected to be like the following.
-----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
tools/analysis_tools/analyze_results.py计算单个图像mAP,并根据预测结果保存或显示得分最高和最低的topk图像。
python tools/analysis_tools/analyze_results.py \
${CONFIG} \
${PREDICTION_PATH} \
${SHOW_DIR} \
[--show] \
[--wait-time ${WAIT_TIME}] \
[--topk ${TOPK}] \
[--show-score-thr ${SHOW_SCORE_THR}] \
[--cfg-options ${CFG_OPTIONS}]
config : The path of a model config file.模型配置文件的路径。
prediction_path: Output result file in pickle format from tools/test.py,从tools/test.py输出pickle格式的结果文件
show_dir: Directory where painted GT and detection images will be saved,绘制的GT和检测图像保存的目录
–show:Determines whether to show painted images, If not specified, it will be set to False
–wait-time: The interval of show (s), 0 is block
–topk: The number of saved images that have the highest and lowest topk scores after sorting. If not specified, it will be set to 20.
–show-score-thr: Show score threshold. If not specified, it will be set to 0.
–cfg-options: If specified, the key-value pair optional cfg will be merged into config file
Assume that you have got result file in pickle format from tools/test.py in the path ‘./result.pkl’.
"假设你在’./result.pkl’路径下从tools/test.py获得了pickle格式的结果文件。
Test Faster R-CNN and visualize the results, save images to the directory results/
测试更快的R-CNN并可视化结果,将图像保存到目录results/
python tools/analysis_tools/analyze_results.py \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
result.pkl \
results \
--show
Test Faster R-CNN and specified topk to 50, save images to the directory results/
测试更快的R-CNN和指定topk为50,保存图像到目录results/
python tools/analysis_tools/analyze_results.py \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
result.pkl \
results \
--topk 50
If you want to filter the low score prediction results, you can specify the show-score-thr parameter
如果你想过滤低分数预测结果,你可以指定参数show-score-thr参数
python tools/analysis_tools/analyze_results.py \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
result.pkl \
results \
--show-score-thr 0.3
tools/analysis_tools/coco_error_analysis.py根据不同的标准分析每个类别的COCO结果。它还可以制作一个情节,提供有用的信息。
python tools/analysis_tools/coco_error_analysis.py ${RESULT} ${OUT_DIR} [-h] [--ann ${ANN}] [--types ${TYPES[TYPES...]}]
Assume that you have got Mask R-CNN checkpoint file in the path ‘checkpoint’. For other checkpoints, please refer to our model zoo. You can use the following command to get the results bbox and segmentation json file.
假设你有掩码R-CNN检查点文件在路径’checkpoint’。其他检查站请参考我们的模型动物园。您可以使用以下命令获取结果框和分段json文件。 out: results.bbox.json and results.segm.json
python tools/test.py \
configs/mask_rcnn/mask_rcnn_r50_fpn_1x_coco.py \
checkpoint/mask_rcnn_r50_fpn_1x_coco_20200205-d4b0c5d6.pth \
--format-only \
--options "jsonfile_prefix=./results"
获取每个类别的COCO box错误结果,将分析结果图像保存到目录results/
Get COCO bbox error results per category , save analyze result images to the directory results/
python tools/analysis_tools/coco_error_analysis.py \
results.bbox.json \
results \
--ann=data/coco/annotations/instances_val2017.json \
获取COCO每个类别的分割错误结果,将分析结果图像保存到目录results/
Get COCO segmentation error results per category , save analyze result images to the directory results/
python tools/analysis_tools/coco_error_analysis.py \
results.segm.json \
results \
--ann=data/coco/annotations/instances_val2017.json \
--types='segm'
Tools /misc/browse_data .py帮助用户可视化地浏览检测数据集(包括图像和边界框注释),或者将图像保存到指定目录
python tools/misc/browse_dataset.py ${CONFIG} [-h] [--skip-type ${SKIP_TYPE[SKIP_TYPE...]}] [--output-dir ${OUTPUT_DIR}] [--not-show] [--show-interval ${SHOW_INTERVAL}]
首先,按照这里的描述将模型转换为ONNX
请注意,目前只支持RetinaNet,对其他型号的支持将在以后的版本中出现。转换后的模型可以通过netron等工具进行可视化。
如果您需要一个轻量级的GUI来可视化检测结果,您可以参考 DetVisGUI project.
为了使用TorchServe添加链接描述服务一个MMDetection模型,你可以按照以下步骤:
python tools/deployment/mmdet2torchserve.py ${CONFIG_FILE} ${CHECKPOINT_FILE} \
--output-folder ${MODEL_STORE} \
--model-name ${MODEL_NAME}
注意:$(MODEL_STORE)需要是一个文件夹的绝对路径。
docker build -t mmdet-serve:latest docker/serve/
Check the official docs for running TorchServe with docker.
In order to run in GPU, you need to install nvidia-docker. You can omit the --gpus argument in order to run in CPU.
Example:
docker run --rm \
--cpus 8 \
--gpus device=0 \
-p8080:8080 -p8081:8081 -p8082:8082 \
--mount type=bind,source=$MODEL_STORE,target=/home/model-server/model-store \
mmdet-serve:latest
curl -O curl -O https://raw.githubusercontent.com/pytorch/serve/master/docs/images/3dogs.jpg
curl http://127.0.0.1:8080/predictions/${MODEL_NAME} -T 3dogs.jpg
你应该得到类似于下面的结果
[
{
"class_name": "dog",
"bbox": [
294.63409423828125,
203.99111938476562,
417.048583984375,
281.62744140625
],
"score": 0.9987992644309998
},
{
"class_name": "dog",
"bbox": [
404.26019287109375,
126.0080795288086,
574.5091552734375,
293.6662292480469
],
"score": 0.9979367256164551
},
{
"class_name": "dog",
"bbox": [
197.2144775390625,
93.3067855834961,
307.8505554199219,
276.7560119628906
],
"score": 0.993338406085968
}
]
你可以使用test_torchserver.py来比较torchserver和pytorch的结果,并将它们可视化。
python tools/deployment/test_torchserver.py ${IMAGE_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} ${MODEL_NAME}
[--inference-addr ${INFERENCE_ADDR}] [--device ${DEVICE}] [--score-thr ${SCORE_THR}]
Example:
python tools/deployment/test_torchserver.py \
demo/demo.jpg \
configs/yolo/yolov3_d53_320_273e_coco.py \
checkpoint/yolov3_d53_320_273e_coco-421362b6.pth \
yolov3
我们提供了一个脚本来将模型转换为ONNX格式。我们还支持对比Pytorch和ONNX模型的输出结果进行验证。
python tools/deployment/pytorch2onnx.py ${CONFIG_FILE} ${CHECKPOINT_FILE} --output-file ${ONNX_FILE} [--shape ${INPUT_SHAPE} --verify]
tools/model_converters/upgrade_model_version.py将以前的MMDetection检查点升级到新版本。注意,这个脚本不能保证工作,因为在新版本中引入了一些破坏性的更改。建议直接使用新的检查点。
python tools/model_converters/upgrade_model_version.py ${IN_FILE} ${OUT_FILE} [-h] [--num-classes NUM_CLASSES]
tools/model_converters/ regnet2mmdett .py将在pycls预训练的RegNet模型中的键转换为MMDetection风格。
python tools/model_converters/regnet2mmdet.py ${SRC} ${DST} [-h]
tools/model_converters/detectron2pytorch.py将原始的detectron预训练ResNet模型中的键转换为PyTorch样式。
python tools/model_converters/detectron2pytorch.py ${SRC} ${DST} ${DEPTH} [-h]
tools /model_converters/publish_model.py帮助用户准备发布模型。
在您将模型上传到AWS之前,您可能需要
在将模型上传到AWS之前,你可能需要
(1)将模型权重转换为CPU张量,
(2)删除优化器状态并
(3)计算检查点文件的哈希并将哈希ID附加到文件名中。
python tools/model_converters/publish_model.py ${INPUT_FILENAME} ${OUTPUT_FILENAME}
python tools/model_converters/publish_model.py work_dirs/faster_rcnn/latest.pth faster_rcnn_r50_fpn_1x_20190801.pth
最终的输出文件名将是faster_rcnn_r50_fpn_1x_20190801-[哈希id).pth。
tools/analysis_tools/get_flops.py是一个改编自失败计数器的 flops-counter.pytorch脚本。pytorch来计算给定模型的FLOPs和参数。
python tools/analysis_tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}]
你会得到这样的结果。
Input shape: (3, 1280, 800)
Flops: 239.32 GFLOPs
Params: 37.74 M
注意:此工具仍处于试验阶段,我们不能保证数字是绝对正确的。你可以将结果用于简单的比较,但是在你在技术报告或论文中采用它之前要再三检查它。
Tools /analysis_tools/test_robust .py和Tools /analysis_tools/robustness_eval.py帮助用户评估模型的健壮性。其核心思想来自于对象检测中的基准鲁棒性:冬季来临时的自动驾驶。有关如何在损坏的图像和一组标准模型的结果上评估模型的更多信息,请参考robustness_benchmarking.md。
tools/analysis_tools/benchmark.py帮助用户计算FPS。FPS值包括模型转发和后期处理。为了得到更准确的数值,目前仅支持单GPU分布式启动方式。
python -m torch.distributed.launch --nproc_per_node=1 --master_port=${PORT} tools/analysis_tools/benchmark.py \
${CONFIG} \
${CHECKPOINT} \
[--repeat-num ${REPEAT_NUM}] \
[--max-iter ${MAX_ITER}] \
[--log-interval ${LOG_INTERVAL}] \
--launcher pytorch
Tools /analysis_tools/eval_metric.py 根据配置文件评估PKL结果文件的某些度量。
python tools/analysis_tools/eval_metric.py ${CONFIG} ${PKL_RESULTS} [-h] [--format-only] [--eval ${EVAL[EVAL ...]}]
[--cfg-options ${CFG_OPTIONS [CFG_OPTIONS ...]}]
[--eval-options ${EVAL_OPTIONS [EVAL_OPTIONS ...]}]
混淆矩
阵混淆矩阵是预测结果的总结
tools/analysis_tools/confusion_matrix.py can analyze the prediction results and plot a confusion matrix table.
First, run tools/test.py to save the .pkl detection results.
首先,运行tools/test.py来保存.pkl检测结果。
python tools/analysis_tools/confusion_matrix.py ${CONFIG} ${DETECTION_RESULTS} ${SAVE_DIR} --show
Tools /misc/print_config.py逐字打印整个配置,展开所有导入。
python tools/misc/print_config.py ${CONFIG} [-h] [--options ${OPTIONS [OPTIONS...]}]
YOLO Anchor Optimization
tools/analysis_tools/optimize_anchors.py提供了两种优化YOLO锚的方法
一种是k-means锚簇,指的是博库
python tools/analysis_tools/optimize_anchors.py ${CONFIG} --algorithm k-means --input-shape ${INPUT_SHAPE [WIDTH HEIGHT]} --output-dir ${OUTPUT_DIR}
另一种方法是使用差异进化来优化锚
python tools/analysis_tools/optimize_anchors.py ${CONFIG} --algorithm differential_evolution --input-shape ${INPUT_SHAPE [WIDTH HEIGHT]} --output-dir ${OUTPUT_DIR}
python tools/analysis_tools/optimize_anchors.py configs/yolo/yolov3_d53_320_273e_coco.py --algorithm differential_evolution --input-shape 608 608 --device cuda --output-dir work_dirs