使用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等都可以根据公式计算。
文章出处登录后可见!
已经登录?立即刷新