快捷键

除了训练/测试脚本,我们还在 tools/ 目录下提供了许多有用的工具。

日志分析

tools/analysis_tools/analyze_logs.py 根据训练日志文件绘制损失/mAP 曲线。请先运行 pip install seaborn 来安装依赖项。

python tools/analysis_tools/analyze_logs.py plot_curve [--keys ${KEYS}] [--eval-interval ${EVALUATION_INTERVAL}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]

loss curve image

示例

  • 绘制某个运行的分类损失。

    python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_cls --legend loss_cls
    
  • 绘制某个运行的分类和回归损失,并将图形保存为 pdf。

    python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_cls loss_bbox --out losses.pdf
    
  • 在同一张图中比较两个运行的 bbox mAP。

    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]
    

    预计输出类似于以下内容。

    -----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 : 模型配置文件的路径。

  • prediction_path: 来自 tools/test.py 的 pickle 格式的输出结果文件

  • show_dir: 将绘制的 GT 和检测图像保存到的目录

  • --show: 确定是否显示绘制的图像,如果未指定,则将其设置为 False

  • --wait-time: 显示的间隔 (s),0 为阻塞

  • --topk: 排序后保存得分最高和最低 topk 得分的图像数量。如果未指定,则将其设置为 20

  • --show-score-thr: 显示分数阈值。如果未指定,则将其设置为 0

  • --cfg-options: 如果指定,则键值对可选 cfg 将合并到配置文件中

示例:

假设您已从 tools/test.py 中在路径 ‘./result.pkl’ 中获得了 pickle 格式的结果文件。

  1. 测试 Faster R-CNN 并可视化结果,将图像保存到目录 results/

python tools/analysis_tools/analyze_results.py \
       configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \
       result.pkl \
       results \
       --show
  1. 测试 Faster 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
  1. 如果您想过滤低得分预测结果,可以指定 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/fusion_results.py 可以使用来自不同目标检测模型的加权框融合 (WBF) 来融合预测。(目前仅支持 coco 格式)

用法

python tools/analysis_tools/fuse_results.py \
       ${PRED_RESULTS} \
       [--annotation ${ANNOTATION}] \
       [--weights ${WEIGHTS}] \
       [--fusion-iou-thr ${FUSION_IOU_THR}] \
       [--skip-box-thr ${SKIP_BOX_THR}] \
       [--conf-type ${CONF_TYPE}] \
       [--eval-single ${EVAL_SINGLE}] \
       [--save-fusion-results ${SAVE_FUSION_RESULTS}] \
       [--out-dir ${OUT_DIR}]

所有参数的描述

  • pred-results: 来自不同模型的检测结果的路径。(目前仅支持 coco 格式)

  • --annotation: 真值路径。

  • --weights: 每个模型的权重列表。默认值:None,这意味着每个模型的权重 == 1。

  • --fusion-iou-thr: 框匹配所需的 IoU 值。默认值:0.55

  • --skip-box-thr: WBF 算法中需要排除的置信度阈值。置信度低于此值的边界框将被排除。默认值:0

  • --conf-type: 如何计算加权框中的置信度。

    • avg: 平均值,默认值。

    • max: 最大值。

    • box_and_model_avg: 盒子级和模型级的混合加权平均值。

    • absent_model_aware_avg: 考虑了缺失模型的加权平均值。

  • --eval-single: 是否评估每个单个模型。默认值:False

  • --save-fusion-results: 是否保存融合结果。默认值:False

  • --out-dir: 融合结果的路径。

示例: 假设您已通过 tools/test.py 从相应的模型中获得了 3 个结果文件,其路径分别为 ‘./faster-rcnn_r50-caffe_fpn_1x_coco.json’,‘./retinanet_r50-caffe_fpn_1x_coco.json’,‘./cascade-rcnn_r50-caffe_fpn_1x_coco.json’。真值文件路径为 ‘./annotation.json’。

  1. 合并来自三个模型的预测并评估其有效性

python tools/analysis_tools/fuse_results.py \
       ./faster-rcnn_r50-caffe_fpn_1x_coco.json \
       ./retinanet_r50-caffe_fpn_1x_coco.json \
       ./cascade-rcnn_r50-caffe_fpn_1x_coco.json \
       --annotation ./annotation.json \
       --weights 1 2 3 \
  1. 同时评估每个单个模型和融合结果

python tools/analysis_tools/fuse_results.py \
       ./faster-rcnn_r50-caffe_fpn_1x_coco.json \
       ./retinanet_r50-caffe_fpn_1x_coco.json \
       ./cascade-rcnn_r50-caffe_fpn_1x_coco.json \
       --annotation ./annotation.json \
       --weights 1 2 3 \
       --eval-single
  1. 合并来自三个模型的预测结果并保存

python tools/analysis_tools/fuse_results.py \
       ./faster-rcnn_r50-caffe_fpn_1x_coco.json \
       ./retinanet_r50-caffe_fpn_1x_coco.json \
       ./cascade-rcnn_r50-caffe_fpn_1x_coco.json \
       --annotation ./annotation.json \
       --weights 1 2 3 \
       --save-fusion-results \
       --out-dir outputs/fusion

可视化

可视化数据集

tools/analysis_tools/browse_dataset.py 帮助用户直观地浏览检测数据集(图像和边界框注释),或将图像保存到指定目录。

python tools/analysis_tools/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 项目

错误分析

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...]}]

示例

假设您已在路径 ‘checkpoint’ 中获得了 Mask R-CNN 检查点文件。对于其他检查点,请参考我们的 模型库

您可以修改 test_evaluator 以通过以下方式保存结果 bbox

  1. 找到当前配置对应的“configs/base/datasets”中的数据集。

  2. 将数据集配置注释中的原始 test_evaluator 和 test_dataloader 替换为 test_evaluator 和 test_dataloader。

  3. 使用以下命令获取结果 bbox 和分割 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 \
  1. 获取每个类别的 COCO bbox 错误结果,并将分析结果图像保存到目录(在 config 中,默认目录为“./work_dirs/coco_instance/test”)。

python tools/analysis_tools/coco_error_analysis.py \
       results.bbox.json \
       results \
       --ann=data/coco/annotations/instances_val2017.json \
  1. 获取每个类别的 COCO 分割错误结果,并将分析结果图像保存到目录。

python tools/analysis_tools/coco_error_analysis.py \
       results.segm.json \
       results \
       --ann=data/coco/annotations/instances_val2017.json \
       --types='segm'

模型服务

为了使用 TorchServe 提供 MMDetection 模型,您可以按照以下步骤操作

1. 安装 TorchServe

假设您有一个已成功安装 PyTorchMMDetectionPython 环境,那么您可以运行以下命令安装 TorchServe 及其依赖项。有关其他安装选项,请参阅 快速入门

python -m pip install torchserve torch-model-archiver torch-workflow-archiver nvgpu

注意:如果您想在 docker 中使用 TorchServe,请参阅 torchserve docker

2. 将模型从 MMDetection 转换为 TorchServe

python tools/deployment/mmdet2torchserve.py ${CONFIG_FILE} ${CHECKPOINT_FILE} \
--output-folder ${MODEL_STORE} \
--model-name ${MODEL_NAME}

3. 启动 TorchServe

torchserve --start --ncs \
  --model-store ${MODEL_STORE} \
  --models  ${MODEL_NAME}.mar

4. 测试部署

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_label": 16,
    "class_name": "dog",
    "bbox": [
      294.63409423828125,
      203.99111938476562,
      417.048583984375,
      281.62744140625
    ],
    "score": 0.9987992644309998
  },
  {
    "class_label": 16,
    "class_name": "dog",
    "bbox": [
      404.26019287109375,
      126.0080795288086,
      574.5091552734375,
      293.6662292480469
    ],
    "score": 0.9979367256164551
  },
  {
    "class_label": 16,
    "class_name": "dog",
    "bbox": [
      197.2144775390625,
      93.3067855834961,
      307.8505554199219,
      276.7560119628906
    ],
    "score": 0.993338406085968
  }
]

比较结果

您可以使用 test_torchserver.py 比较 TorchServePyTorch 的结果,并进行可视化。

python tools/deployment/test_torchserver.py ${IMAGE_FILE} ${CONFIG_FILE} ${CHECKPOINT_FILE} ${MODEL_NAME}
[--inference-addr ${INFERENCE_ADDR}] [--device ${DEVICE}] [--score-thr ${SCORE_THR}] [--work-dir ${WORK_DIR}]

示例

python tools/deployment/test_torchserver.py \
demo/demo.jpg \
configs/yolo/yolov3_d53_8xb8-320-273e_coco.py \
checkpoint/yolov3_d53_320_273e_coco-421362b6.pth \
yolov3 \
--work-dir ./work-dir

5. 停止 TorchServe

torchserve --stop

模型复杂度

tools/analysis_tools/get_flops.py 是一个从 flops-counter.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
==============================

注意:此工具仍处于实验阶段,我们不保证数字完全正确。您可以将结果用于简单的比较,但在技术报告或论文中采用之前请仔细检查。

  1. FLOPs 与输入形状相关,而参数则无关。默认输入形状为 (1, 3, 1280, 800)。

  2. 一些运算符不会计入 FLOPs,例如 GN 和自定义运算符。有关详细信息,请参阅 mmcv.cnn.get_model_complexity_info()

  3. 两阶段检测器的 FLOPs 取决于提案的数量。

模型转换

MMDetection 模型到 ONNX

我们提供一个脚本将模型转换为 ONNX 格式。我们还支持比较 Pytorch 和 ONNX 模型的输出结果以进行验证。更多详细信息请参阅 mmdeploy

MMDetection 1.x 模型到 MMDetection 2.x

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]

RegNet 模型到 MMDetection

tools/model_converters/regnet2mmdet.py 将 pycls 预训练的 RegNet 模型中的键转换为 MMDetection 风格。

python tools/model_converters/regnet2mmdet.py ${SRC} ${DST} [-h]

Detectron ResNet 到 Pytorch

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 之前,您可能需要

  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-{hash id}.pth

数据集转换

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}]

数据集下载

tools/misc/download_dataset.py 支持下载 COCO、VOC 和 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

对于中国用户,这些数据集也可以从 OpenDataLab 高速下载

基准测试

鲁棒检测基准测试

tools/analysis_tools/test_robustness.pytools/analysis_tools/robustness_eval.py 帮助用户评估模型的鲁棒性。核心思想来自 Benchmarking Robustness in Object Detection: Autonomous Driving when Winter is Coming。有关如何在损坏的图像上评估模型以及一组标准模型的结果,请参阅 robustness_benchmarking.md

FPS 基准测试

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 ${CHECKPOINT}] \
    [--repeat-num ${REPEAT_NUM}] \
    [--max-iter ${MAX_ITER}] \
    [--log-interval ${LOG_INTERVAL}] \
    --launcher pytorch

示例:假设您已将 Faster R-CNN 模型检查点下载到 checkpoints/ 目录。

python -m torch.distributed.launch --nproc_per_node=1 --master_port=29500 tools/analysis_tools/benchmark.py \
       configs/faster_rcnn/faster-rcnn_r50_fpn_1x_coco.py \
       checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
       --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 ...]}]

超参数优化

YOLO 锚点优化

tools/analysis_tools/optimize_anchors.py 提供两种优化 YOLO 锚点的方法。

一种是 k 均值锚点聚类,它来自 darknet

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_8xb8-320-273e_coco.py --algorithm differential_evolution --input-shape 608 608 --device cuda --output-dir work_dirs

您将获得

loading annotations into memory...
Done (t=9.70s)
creating index...
index created!
2021-07-19 19:37:20,951 - mmdet - INFO - Collecting bboxes from annotation...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 117266/117266, 15874.5 task/s, elapsed: 7s, ETA:     0s

2021-07-19 19:37:28,753 - mmdet - INFO - Collected 849902 bboxes.
differential_evolution step 1: f(x)= 0.506055
differential_evolution step 2: f(x)= 0.506055
......

differential_evolution step 489: f(x)= 0.386625
2021-07-19 19:46:40,775 - mmdet - INFO Anchor evolution finish. Average IOU: 0.6133754253387451
2021-07-19 19:46:40,776 - mmdet - INFO Anchor differential evolution result:[[10, 12], [15, 30], [32, 22], [29, 59], [61, 46], [57, 116], [112, 89], [154, 198], [349, 336]]
2021-07-19 19:46:40,798 - mmdet - INFO Result saved in work_dirs/anchor_optimize_result.json

混淆矩阵

混淆矩阵是预测结果的摘要。

tools/analysis_tools/confusion_matrix.py 可以分析预测结果并绘制混淆矩阵表。

首先,运行 tools/test.py 保存 .pkl 检测结果。

然后,运行

python tools/analysis_tools/confusion_matrix.py ${CONFIG}  ${DETECTION_RESULTS}  ${SAVE_DIR} --show

您将获得一个混淆矩阵,如下所示

confusion_matrix_example

COCO 分离和遮挡掩码指标

检测遮挡物体对于最先进的目标检测器来说仍然是一个挑战。我们实现了论文 A Tri-Layer Plugin to Improve Occluded Detection 中提出的指标来计算分离和遮挡掩码的召回率。

使用此指标有两种方法

离线评估

我们提供一个脚本,使用转储的预测文件来计算指标。

首先,使用 tools/test.py 脚本转储检测结果

python tools/test.py ${CONFIG} ${MODEL_PATH} --out results.pkl

然后,运行 tools/analysis_tools/coco_occluded_separated_recall.py 脚本获取分离和遮挡掩码的召回率

python tools/analysis_tools/coco_occluded_separated_recall.py results.pkl --out occluded_separated_recall.json

输出应如下所示

loading annotations into memory...
Done (t=0.51s)
creating index...
index created!
processing detection results...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 5000/5000, 109.3 task/s, elapsed: 46s, ETA:     0s
computing occluded mask recall...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 5550/5550, 780.5 task/s, elapsed: 7s, ETA:     0s
COCO occluded mask recall: 58.79%
COCO occluded mask success num: 3263
computing separated mask recall...
[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] 3522/3522, 778.3 task/s, elapsed: 5s, ETA:     0s
COCO separated mask recall: 31.94%
COCO separated mask success num: 1125

+-----------+--------+-------------+
| mask type | recall | num correct |
+-----------+--------+-------------+
| occluded  | 58.79% | 3263        |
| separated | 31.94% | 1125        |
+-----------+--------+-------------+
Evaluation results have been saved to occluded_separated_recall.json.

在线评估

我们实现了 CocoOccludedSeparatedMetric,它继承自 CocoMetic。要在训练期间评估分离和遮挡掩码的召回率,只需在您的配置中将评估器指标类型替换为 'CocoOccludedSeparatedMetric'

val_evaluator = dict(
    type='CocoOccludedSeparatedMetric',  # modify this
    ann_file=data_root + 'annotations/instances_val2017.json',
    metric=['bbox', 'segm'],
    format_only=False)
test_evaluator = val_evaluator

如果您使用此指标,请引用该论文

@article{zhan2022triocc,
    title={A Tri-Layer Plugin to Improve Occluded Detection},
    author={Zhan, Guanqi and Xie, Weidi and Zisserman, Andrew},
    journal={British Machine Vision Conference},
    year={2022}
}