mmdetection输出precision指标(VOC数据集)

使用VOC格式数据集训练mmdetection模型时,测试只输出recall和AP。想要输出precision指标,其实很简单,实际上mmdet/core/evaluation/mean_ap.py的eval_map()函数中已经得到了precision的值并写入了字典,通过修改print_map_summary()函数打印出来即可。

在mmdet/core/evaluation/mean_ap.py中,找到print_map_summary()函数,添加几行代码:

 
def print_map_summary(mean_ap,
                      results,
                      dataset=None,
                      scale_ranges=None,
                      logger=None):
    """Print mAP and results of each class.
    A table will be printed to show the gts/dets/recall/AP of each class and
    the mAP.
    Args:
        mean_ap (float): Calculated from `eval_map()`.
        results (list[dict]): Calculated from `eval_map()`.
        dataset (list[str] | str | None): Dataset name or dataset classes.
        scale_ranges (list[tuple] | None): Range of scales to be evaluated.
        logger (logging.Logger | str | None): The way to print the mAP
            summary. See `mmcv.utils.print_log()` for details. Default: None.
    """
 
    if logger == 'silent':
        return
 
    if isinstance(results[0]['ap'], np.ndarray):
        num_scales = len(results[0]['ap'])
    else:
        num_scales = 1
 
    if scale_ranges is not None:
        assert len(scale_ranges) == num_scales
 
    num_classes = len(results)
 
    recalls = np.zeros((num_scales, num_classes), dtype=np.float32)
    precisions = np.zeros((num_scales, num_classes), dtype=np.float32)  #定义
    aps = np.zeros((num_scales, num_classes), dtype=np.float32)
    num_gts = np.zeros((num_scales, num_classes), dtype=int)
    for i, cls_result in enumerate(results):
        if cls_result['recall'].size > 0:
            recalls[:, i] = np.array(cls_result['recall'], ndmin=2)[:, -1]
        if cls_result['precision'].size > 0:
            precisions[:, i] = np.array(cls_result['precision'], ndmin=2)[:, -1]  #添加值
        aps[:, i] = cls_result['ap']
        num_gts[:, i] = cls_result['num_gts']
 
    if dataset is None:
        label_names = [str(i) for i in range(num_classes)]
    elif mmcv.is_str(dataset):
        label_names = get_classes(dataset)
    else:
        label_names = dataset
 
    if not isinstance(mean_ap, list):
        mean_ap = [mean_ap]
 
    header = ['class', 'gts', 'dets', 'recall', 'precision', 'ap']  #打印precision标题
    for i in range(num_scales):
        if scale_ranges is not None:
            print_log(f'Scale range {scale_ranges[i]}', logger=logger)
        table_data = [header]
        for j in range(num_classes):
            row_data = [
                label_names[j], num_gts[i, j], results[j]['num_dets'],
                f'{recalls[i, j]:.3f}', f'{precisions[i, j]:.3f}', f'{aps[i, j]:.3f}'  #打印precision的值
            ]
            table_data.append(row_data)
        table_data.append(['mAP', '', '', '', '', f'{mean_ap[i]:.3f}'])  #多加个''对齐
        table = AsciiTable(table_data)
        table.inner_footing_row_border = True
        print_log('\n' + table.table, logger=logger)

 

 

另外,除了这种方法,实际上根据混淆矩阵也可以手算得到precision。

tools/analysis_tools/confusion_matrix.py可以得到混淆矩阵,但在这之前先使用test.py得到pkl文件,根据pkl文件计算混淆矩阵。但还是需要经过一些修改,confusion_matrix.py得到的混淆矩阵中的数值是经过归一化了的,可以在166行改成不进行归一化,分母删掉就行。然后211行打印%去掉,这样输出的混淆矩阵,就可以用来手算各种指标了,TP、FP、TN、FN、F1-Score、Precision、Recall、ACC等都可以根据公式计算。

 
转载:https://blog.csdn.net/lpan2020/article/details/125049238
posted @ 2022-06-15 16:12  海_纳百川  阅读(1871)  评论(0编辑  收藏  举报
本站总访问量