mmdetection 使用

1. 准备工作目录

我们的工作目录,也就是 mmdetection 目录,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
|-- configs
| |-- _base_
| |--- .......
|-- data
| |--- coco
| | |--- annotations
| | |--- train2017
| | |--- val2017
| | |--- visualization
|-- mmdet
| |--- core
| |--- datasets
| |--- .......
|-- tools
  • configs就是我们的配置文件,里边包含所有的文件。
  • data就是我们的数据集文件,文件目录如上。
  • mmdet是我们所需要修改的目录。
  • tools是我们的mmdetection提供的工具箱,里边包含我们要用的训练和测试文件。

2. 修改mmdetection模型的配置

查找配置文件

选择你要训练的模型对应的配置文件修改,假如我要训练的模型是mask_rcnn_r101_fpn_2x_coco.py,打开configs/mask_rcnn/mask_rcnn_r101_fpn_2x_coco.py,然后跟着 _base_ 一直往下找,最后找到,这就是它所有的配置文件:

这个文件不修改,主要查看哪些文件需要修改及其位置

1
2
3
4
5
_base_ = [
'../_base_/models/mask_rcnn_r50_fpn.py',
'../_base_/datasets/coco_instance.py',
'../_base_/schedules/schedule_1x.py', '../_base_/default_runtime.py'
]

图片尺寸

修改下面文件里的img_scale=(1333, 800),改成小一点的数值。三个文件都要改(这句话存疑,我试的时候只用改第一个)

1
2
3
configs/_base_/datasets/coco_detection.py
configs/_base_/datasets/coco_instance.py
configs/_base_/datasets/coco_instance_semantic.py

batch_size

batch_size 没有单独的地方进行配置,不过mmdetection 有自己的计算规则,如下

1
2
3
4
imgs_per_gpu=2, # 每个gpu计算的图像数量
workers_per_gpu=2, # 每个gpu分配的线程数
batch_size = num_gpus * imgs_per_gpu
num_workers = num_gpus * workers_per_gpu

上述参数在文件中:

1
configs/_base_/datasets/coco_detection.py

“imgs_per_gpu” is deprecated in MMDet V2.0. Please use “samples_per_gpu” instead

修改学习率lr,训练次数max_epochs

修改学习率lr,以及训练次数 max_epochs(依照自己电脑配置)

1
mmdetection\configs\_base_\schedules\schedule_1x.py

配置文件中的默认学习率0.2是8个gpu和2个img/gpu(batch size=16)。根据线性缩放规则,如果您使用不同的GPU数目或img/gpu,您需要设置与batch size成比例的学习率。例如,如果4GPUs * 2 img/gpu的lr=0.01,那么16GPUs * 4 img/gpu的lr=0.08。比如你一块GPU,就应该设置为原来的1/8。

batch_size = gpu_num(训练使用gpu数量) * imgs_per_gpu

lr = 0.00125*batch_siz

类别数量

(1)修改文件里的 num_classes=80 ,修改成自己的类别数目。

1
mmdetection/configs/_base_/models/mask_rcnn_r50_fpn.py

(2)修改我们的类别名,两个文件需要修改,第一个文件是:

1
mmdet/core/evaluation/class_names.py

修改里边的def coco_classes(): ,将return内容修改成自己的类别。

第二个文件:

1
mmdet/datasets/coco.py

修改里边的class CocoDataset(CustomDataset): ,将 CLASSES = () 修改成自己的类别。

修改完类别后一定要重新编译,否则可能会出现错误

至此,修改结束,我们还需要重新编译一遍,这样才能生效,在我们的mmdetection目录下运行:

1
python setup.py install

否则会遇到bug:你指定的类别(3种)与CocoDataset的类别(80种)不匹配

1
# AssertionError: The `num_classes` (3) in Shared2FCBBoxHead of MMDataParallel does not matches the length of `CLASSES` 80) in CocoDataset

如果编译后还是失败,可以先删掉mmdetection,重新下载修改再编译。我之前也遇到编译后出错,重新下载一次就解决了。

还有一种方法,未测试

1
2
3
4
5
6
7
8
9
第三种方法,也是我使用的方法,其实跟重新编译一样,重新编译的原因就是因为环境里的源文件没有修改,所以你才会报错。mmdetection-master目录下只是一些python文件,真正运行程序时,运行的还是环境里的源文件,因为我们直接去环境里修改源文件。

假设我的conda环境名为conda_env_name,因此去下面的目录下,分别修改两个文件:

\anaconda3\envs\conda_env_name\lib\python3.7\site-packages\mmdet\core\evaluation\class_names.py

\anaconda3\envs\conda_env_name\lib\python3.7\site-packages\mmdet\datasets\coco.py

在conda环境里把这两个文件里的类别修改了,就可以了。

3. 训练

训练参数

1
python tools/train.py configs/mask_rcnn/mask_rcnn_r101_fpn_2x_coco.py
  • –work-dir:指定训练保存模型和日志的路径
  • –resume-from:从预训练模型chenkpoint中恢复训练
  • –no-validate:训练期间不评估checkpoint
  • –gpus:指定训练使用GPU的数量(仅适用非分布式训练)
  • –gpu-ids: 指定使用哪一块GPU(仅适用非分布式训练)
  • –seed:随机种子
  • –deterministic:是否为CUDNN后端设置确定性选项
  • –options: arguments in dict
  • –launcher: {none,pytorch,slurm,mpi} job launcher
  • –local_rank: LOCAL_RANK
  • –autoscale-lr: automatically scale lr with the number of gpus

示例:

1
2
3
4
5
# 单GPU训练
python tools/train.py configs/mask_rcnn/mask_rcnn_r101_fpn_2x_coco.py

# 多GPU训练
bash ./tools/dist_train.sh configs/mask_rcnn/mask_rcnn_r101_fpn_2x_coco.py 2
  • configs/mask_rcnn/mask_rcnn_r101_fpn_2x_coco.py 就是我们要训练的模型
  • 2 是我们的GPU数目

模型训练过程中修改

0 直接修改 config 中对应的配置,然后重新运行

直接修改 config 中对应的配置,然后重新运行

1 修改临时生成的配置文件,然后运行时指定该配置文件

  1. 刚开始训练时,会在你的mmdetection目录下自动生成一个work_dirs文件夹,里边包含你模型的配置文件:
1
mmdetection/work_dirs/mask_rcnn_r101_fpn_2x_coco/mask_rcnn_r101_fpn_2x_coco.py

官方给的配置文件中所有参数的解释说明:mmdetection-readthedocs-io-zh_CN-latest.pdf

一般我们进行修改的就是下面这些:

1
2
3
4
5
6
7
8
# 最大的epochs,根据自己的情况来调整。
runner = dict(type='EpochBasedRunner', max_epochs=24)

# 模型权重的保存的间隔,建议调大一点,否则会保存大量模型权重,占用存储空间,例如interval=8。模型会默认保存最后一次训练的权重
checkpoint_config = dict(interval=1)

# 日志的输出间隔,建议调小一点,例如interval=4
log_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])
  1. 修改完配置文件,再训练时训练语句指定的配置文件就是刚刚修改的,也就是work_dirs目录下面的
1
2
3
4
5
# 单 GPU训练
python tools/train.py work_dirs/mask_rcnn_r101_fpn_2x_coco/mask_rcnn_r101_fpn_2x_coco.py

# 多GPU训练
bash ./tools/dist_train.sh work_dirs/mask_rcnn_r101_fpn_2x_coco/mask_rcnn_r101_fpn_2x_coco.py 2

中断之后加载之前的模型接着训练

0 使用运行命令直接加载 (可用)

训练时带上参数 --resume-from, 训练时会自动从 checkpoint 开始训练,也就是接着模型保存的位置开始训练。

1
python tools/train.py configs/cascade_rcnn/cascade_rcnn_x101_32x4d_fpn_20e_coco.py --resume-from work_dirs/cascade_rcnn_x101_32x4d_fpn_20e_coco/epoch_3.pth

1 使用上述模型训练过程中修改 修改 resume_from 参数,然后重新训练

修改参数可以在两个地方修改:

  1. 修改临时生产的配置文件,在 work_dir 文件找到本次运行的配置文件,修改 resume_from 参数,然后重新训练
  2. 直接修改配置文件。修改 ../_base_/default_runtime.pyresume_from 参数,然后重新训练

4. 模型测试

生成测试结果

1
2
3
4
# 单 GPU 测试
python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}] [--show]
# 多 GPU 测试
bash tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}]

命令参数:

  • config_file:模型配置文件的路径
  • checkpoint_file:模型检查点文件的路径
  • gpu_num:使用的 GPU 数量
  • --out:设置输出 pkl 测试结果文件的路径
  • --work-dir:设置存放 json 日志文件的路径
  • --eval:设置度量指标(vocmAP, recall | cocobbox, segm, proposal
  • --show:设置显示有预测框的测试集图像
  • --show-dir:设置存放有预测框的测试集图像的路径
  • --show-score-thr:设置显示预测框的阈值,默认值为 0.3
  • --fuse-conv-bn: 设置融合卷积层和批归一化层,能够稍微提升推理速度

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 单 GPU 测试 
# 可视化某个图片
python tools/test.py \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
work_dirs/faster_rcnn_r50_fpn_1x_coco/latest.pth \
--show

# 多 GPU 测试
# 计算 map ,并保存测试结果
bash tools/dist_test.sh \
configs/faster_rcnn/faster_rcnn_r50_fpn_1x_mydataset.py \
work_dirs/faster_rcnn_r50_fpn_1x_coco/latest.pth 4 \
--out work_dirs/faster_rcnn_r50_fpn_1x_mydataset/result.pkl \
--eval mAP
  • configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py:是模型文件
  • ./work_dirs/faster_rcnn_r50_fpn_1x_coco/latest.pth:是我们自己训练保存的模型
  • ./result.pkl:生成一个result.pkl文件,大小1.2M,该文件中会保存各个类别对应的信息,用于计算APwenj

测试结果文件评估 eval_metric.py

1
2
3
python tools/analysis_tools/eval_metric.py \
${CONFIG_FILE} ${PKL_RESULTS} \
[--eval ${EVAL_METRICS}]

命令参数:

  • config_file:模型配置文件的路径
  • pkl_resultspkl 测试结果文件的路径
  • --eval:设置度量指标(vocmAP, recall | cocobbox, segm, proposal

示例

1
2
3
4
5
6
7
8
9
python tools/analysis_tools/eval_metric.py \
configs/config/faster_rcnn_r50_fpn_1x_mydataset.py \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/result.pkl \
--eval mAP

# or
python tools/analysis_tools/eval_metric.py \
configs/cascade_rcnn/cascade_rcnn_x101_32x4d_fpn_20e_coco.py \
./result.pkl --eval bbox

测试结果文件评估 robustness_eval.py

命令格式:

1
2
python tools/analysis_tools/robustness_eval.py ${PKL_RESULTS} \
[--dataset ${DATASET}] [--task ${TASK}] [--metric ${EVAL_METRICS}]

命令参数:

  • pkl_resultspkl 测试结果文件的路径
  • --dataset:设置数据集类型(voc, coco, cityscape),默认值为 coco
  • --task: 设置任务类型(vocbbox | cocobbox, segm),默认值为 bbox
  • --metric:设置度量指标(vocAP50 | cocoAP, AP50, AP75, APs, APm, APl, AR1, AR10, AR100, ARs, ARm, ARl

测试 AP(有点问题):

1
python tools/analysis_tools/robustness_eval.py ./result.pkl --dataset voc --metric AP

测试鲁棒性test_robustness.py

1
2
3
python tools/analysis_tools/test_robustness.py \
${CONFIG_FILE} ${CHECKPOINT_FILE} \
[--out ${RESULT_FILE}] [--eval ${EVAL_METRICS}]

命令参数:

  • config_file:模型配置文件的路径
  • checkpoint_file:模型检查点文件的路径
  • --out:设置输出 pkl 测试结果文件的路径
  • --eval:设置度量类型(vocbbox | cocoproposal, proposal_fast, bbox, segm, keypoints
  • --corruptions:设置图像损坏类型(all, benchmark, noise, blur, weather, digital, holdout, None),默认值为 benchmark
  • --severities:设置图像损坏程度(0, 1, 2, 3, 4, 5),默认值为 0 1 2 3 4 5
  • --iou-thr:设置 voc 评估的 IoU 阈值,默认值为 0.5
  • --show:设置显示有预测框的测试集图像
  • --show-dir:设置存放有预测框的测试集图像的路径
  • --show-score-thr:设置显示预测结果的阈值,默认值为 0.3
  • --seed:设置随机种子,便于复现结果

示例:

1
2
3
4
5
python tools/analysis_tools/test_robustness.py \
configs/myconfig/faster_rcnn_r50_fpn_1x_mydataset.py \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/latest.pth \
--out work_dirs/faster_rcnn_r50_fpn_1x_mydataset/robustness.pkl \
--eval bbox --corruptions noise weather --severities 1 2 --seed 0

4 工具箱

4.1 日志分析

绘制学习曲线

命令格式:

1
2
3
python tools/analysis_tools/analyze_logs.py plot_curve log.json \
[--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] \
[--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]

命令参数:

  • plot_curve:绘制曲线,该参数后跟的是训练保存的json文件
  • json_logsjson 日志文件的路径
  • --keys:设置度量指标(acc, loss, loss_cls, loss_bbox, mAP, etc.)
  • --title:设置曲线标题
  • --legend:设置曲线图例
  • --backend:设置后端
  • --style:设置风格
  • --out:设置输出 jpg 绘制曲线文件的路径,可以保存成png图片,也可以保存成pdf

示例:

1
2
3
python tools/analysis_tools/analyze_logs.py plot_curve \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/20201030_162432.log.json \
--keys loss --out work_dirs/faster_rcnn_r50_fpn_1x_mydataset/plot_result.jpg

计算训练时间

命令格式:

1
python tools/analysis_tools/analyze_logs.py cal_train_time log.json

命令参数:

  • cal_train_time:计算训练时间
  • json_logsjson 日志文件的路径

示例:

1
2
python tools/analysis_tools/analyze_logs.py cal_train_time \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/20201030_162432.log.json

计算模型复杂度

命令格式:

1
2
python tools/analysis_tools/get_flops.py \
${CONFIG_FILE} [--shape ${INPUT_SHAPE}]

命令参数:

  • config_file:模型配置文件的路径
  • --shape:输入图像尺寸,默认值为 1280 800

示例:

1
2
3
python tools/analysis_tools/get_flops.py \
configs/myconfig/faster_rcnn_r50_fpn_1x_mydataset.py \
--shape 1333 800

4.2 结果分析

命令格式:

1
2
3
4
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}]

命令参数:

  • config:模型配置文件的路径
  • prediction_pathpkl 预测结果文件的路径
  • show_dir:设置存放有预测框的图像文件的路径
  • --show:设置显示有预测框的图像
  • --wait-time:设置图像显示间隔时间,默认值为 0 (s)
  • --topk:设置需要保存预测图像的数量,默认值为 20
  • --show-score-thr:设置显示预测结果的阈值,默认值为 0

示例:

1
2
3
4
5
python tools/analysis_tools/analyze_results.py \
configs/myconfig/faster_rcnn_r50_fpn_1x_mydataset.py \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/result.pkl \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/results \
--show --topk 10 --show-score-thr 0.3

4.3 误差分析

命令格式:

1
2
3
python tools/analysis_tools/coco_error_analysis.py \
${RESULT} ${OUT_DIR} \
[--ann ${ANN}] [--types ${TYPES[TYPES...]}]

命令参数:

  • resultjson 预测结果文件的路径
  • out_dir:设置输出分析结果文件的路径
  • --annjson 标注文件的路径,默认值为 data/coco/annotations/instances_val2017.json
  • --types:设置预测结果类型,默认值为 bbox

示例:

1
2
3
4
5
python tools/analysis_tools/coco_error_analysis.py \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/results.bbox.json \
work_dirs/faster_rcnn_r50_fpn_1x_mydataset/results \
--ann=data/coco/annotations/instances_val2017.json
--types='bbox'

4.4 其他

浏览训练集图像

命令格式:

1
2
python tools/misc/browse_dataset.py ${CONFIG_FILE} \
[--output-dir ${OUTPUT_DIR}] [--show-interval ${SHOW_INTERVAL}]

命令参数:

  • config_file:模型配置文件的路径
  • --output-dir:设置输出有标注框的训练集图像的路径
  • --show-interval:设置图像显示间隔时间,默认值为 2 (s)

示例:

1
python tools/misc/browse_dataset.py configs/myconfig/faster_rcnn_r50_fpn_1x_mydataset.py

Tips:
如果需要使用 GUI,来浏览有预测框的图像文件,可下载 DetVisGUI

打印完整配置

命令格式:

1
python tools/misc/print_config.py ${CONFIG_FILE}

命令参数:

  • config_file:模型配置文件的路径

示例:

1
python tools/misc/print_config.py configs/myconfig/faster_rcnn_r50_fpn_1x_mydataset.py

训练过程各种损失值和准确率可视化效果

tensorboard

开启tensorboard,记得在config配置文件里将dict(type=’TensorboardLoggerHook’)注释取消掉

在新的终端中执行如下命令:

1
tensorboard --logdir=path --port=8090#port=8090可以自己指定的端口,默认不需要--port其端口是6006

本地跑mmdetection的话直接在PC的浏览器上输入如下链接 http://127.0.0.1:16006


mmdetection 使用
https://flepeng.github.io/ml-目标检测开源神器-mmdetection-使用/
作者
Lepeng
发布于
2021年4月19日
许可协议