1. 计算各个类别的map

1.1 方法1: 直接计算, 仅支持voc 数据集与 custom 数据集

使用如下命令直接计算各个分类的map , 使用的图片为 config 配置中test中的数据集评估

python tools/test.py work_dirs/faster_rcnn_r50_fpn_1x_coco.py work_dirs/latest.pth --eval mAP

# 参数说明
- work_dir/faster_rcnn_r50_fpn_1x_coco.py: 模型配置文件
- work_dir/latest.pth: 训练好的模型
- --eval mAP: 使用map评估

但该方式只支持 voc 数据集与 custom 数据集

1.2 方法2: coco 数据集使用中间文件生成计算
1.2.1 先使用 test.py生成 results.pkl 文件
python tools/test.py work_dir/faster_rcnn_r50_fpn_1x_coco.py  work_dir/latest.pth  --out results.pkl

- work_dir/faster_rcnn_r50_fpn_1x_coco.py: 模型配置文件
- work_dir/latest.pth: 训练好的模型
- --out results.pkl: 代表输出到根目录的results.pkl文件中, 也可以输出到指定目录
1.2.2 使用VOC标准计算各个类别 map

这里要用到旧版本 1.0.0 下的 tools/voc_eval.py 文件, 由于该文件已经在2.11.0版本中移除, 所以需要去官网下载, 链接: voc.eval.py文件 , 后文也会复制一份放在本文中

下载后将 voc_eval.py 放到 tools 目录下, 然后执行如下命令,采用voc标准计算mAP:

python tools/voc_eval.py results.pkl  work_dirs/faster_rcnn_r50_fpn_1x_coco.py 

便可以得到如下结果:

这些类别是我自己训练的数据集中的各个类别, 可以看到已经计算出了各个类别的 map值

1.2.3 使用coco 评估标准计算所有类别 bbox_mAP50, 75, 95, bbox_mAP_s/m/l的值

同样需要使用 1.1 中得到的 results.pkl 文件, 使用命令:

python tools/analysis_tools/eval_metric.py  work_dirs/faster_rcnn_r50_fpn_1x_coco.py  results.pkl  --eval=bbox

得到结果示例如下图:

参考: mmdetection实战,训练扑克牌数据集(VOC格式)并测试计算mAP MMDetection 快速开始,训练自定义数据集

2. 绘制每个类别bbox 的结果曲线图并保存

2.1 先使用 test.py 生成输出 results.bbox.json 文件
python tools/test.py  work_dir/faster_rcnn_r50_fpn_1x_coco.py  work_dir/latest.pth  --format-only  --options "jsonfile_prefix=./results"
2.2 获得COCO bbox错误结果每个类别,保存分析结果图像到目录results/
python tools/analysis_tools/coco_error_analysis.py results.bbox.json results  --ann=D:/annotations.json

- results.bbox.json:上一步生成的文件
- results: 结果曲线图的生成目录, 此处将生成到results/ 目录下
- --ann=D:/annotations.json: 指定数据集的标注文件, 需要修改成你自己的, 默认为 data/coco/annotations/instances_val2017.json, 用的是官方的

生成的文件概览大体如下:

注意点:

  • coco格式的json 标注文件中, 需要有 supercategory 键值, 参考coco数据集格式

参考: mmdetection 官方教程

3. 关于分析日志的工具

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

- keys: 要展示的关键字
- title: 图的标题
- legend: 指定图例

例子:

  • 绘制一些运行的分类损失。
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_reg --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/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

参考: mmdetection官方教程 MMDetection中文文档—2.入门 【通用视觉框架 OpenMMLab 字幕版】第四讲 目标检测 & MMDetection(下)—陈恺博士

4. 附录

voc_eval.py 具体代码如下:

from argparse import ArgumentParser

import mmcv

from mmdet import datasets
from mmdet.core import eval_map


def voc_eval(result_file, dataset, iou_thr=0.5, nproc=4):
    det_results = mmcv.load(result_file)
    annotations = [dataset.get_ann_info(i) for i in range(len(dataset))]
    if hasattr(dataset, 'year') and dataset.year == 2007:
        dataset_name = 'voc07'
    else:
        dataset_name = dataset.CLASSES
    eval_map(
        det_results,
        annotations,
        scale_ranges=None,
        iou_thr=iou_thr,
        dataset=dataset_name,
        logger='print',
        nproc=nproc)


def main():
    parser = ArgumentParser(description='VOC Evaluation')
    parser.add_argument('result', help='result file path')
    parser.add_argument('config', help='config file path')
    parser.add_argument(
        '--iou-thr',
        type=float,
        default=0.5,
        help='IoU threshold for evaluation')
    parser.add_argument(
        '--nproc',
        type=int,
        default=4,
        help='Processes to be used for computing mAP')
    args = parser.parse_args()
    cfg = mmcv.Config.fromfile(args.config)
    test_dataset = mmcv.runner.obj_from_dict(cfg.data.test, datasets)
    voc_eval(args.result, test_dataset, args.iou_thr, args.nproc)


if __name__ == '__main__':
    main()
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐