在物体检测任务中,mAP(mean Average Precision)是一个常用的评价指标,用于衡量模型在检测任务中的精度。mAP@0.5 和 mAP@0.5:0.95 是两个常用的变种,它们代表了在不同 IoU(Intersection over Union)阈值下计算得到的 mAP。
mAP@0.5
mAP@0.5 表示在 IoU 阈值为 0.5 时计算得到的 mAP。
IoU 是预测的边界框与真实边界框之间的重叠度量,IoU = 交集面积 / 并集面积。
应用场景中一般0.5的IoU足够了,并不需要过度严格的指标,比如行人检测、人脸检测等等
当 IoU ≥ 0.5 时,预测结果被认为是正确的。
mAP@0.5:0.95
mAP@0.5:0.95 表示在多个 IoU 阈值(从 0.5 到 0.95,步长为 0.05)下计算得到的平均 mAP。
这意味着模型在多个不同的 IoU 阈值下的表现都会被考虑,提供一个更全面的评估。
具体来说,mAP@0.5:0.95 是在以下 IoU 阈值下计算得到的平均值:
0.5
0.55
0.6
0.65
0.7
0.75
0.8
0.85
0.9
0.95
那AP是什么呢,Average Precision,是单个类别平均精确度,而mAP是所有类别的平均精确度
AP是Precision-Recall Curve曲线下面的面积
曲线面积越大说明AP的值越大,类别的检测精度就越高。Recall官方称为召回率,可以考虑叫做查全率,Precision官网称为准确率叫做查准率,两者是相互矛盾的指标,如果能够较好的平衡两者,将在不同的条件下得到较好的检测效果,也就是图中的曲线面积。
PRC怎么看:先看平滑不平滑(蓝线明显好些),在看谁上谁下(同一测试集上),一般来说,上面的比下面的好(绿线比红线好)。
为什么 mAP@0.5:0.95 更重要?
- 更严格的评估标准:相比于 mAP@0.5,mAP@0.5:0.95 提供了更严格的评估标准,因为它考虑了更高的 IoU 阈值。
- 全面性:mAP@0.5:0.95 更全面地反映了模型在不同 IoU 阈值下的表现,不仅关注模型能否大致定位目标,也关注模型能否精确定位目标。
示例代码
以下是一个计算 mAP@0.5 和 mAP@0.5:0.95 的示例代码:
import numpy as np
def calculate_iou(box1, box2):
x1, y1, w1, h1 = box1
x2, y2, w2, h2 = box2
xi1 = max(x1, x2)
yi1 = max(y1, y2)
xi2 = min(x1 + w1, x2 + w2)
yi2 = min(y1 + h1, y2 + h2)
inter_area = max(0, xi2 - xi1) * max(0, yi2 - yi1)
box1_area = w1 * h1
box2_area = w2 * h2
union_area = box1_area + box2_area - inter_area
return inter_area / union_area if union_area > 0 else 0
def calculate_precision_recall(pred_boxes, true_boxes, iou_threshold):
tp, fp, fn = 0, 0, 0
for true_box in true_boxes:
matched = False
for pred_box in pred_boxes:
iou = calculate_iou(true_box, pred_box)
if iou >= iou_threshold:
tp += 1
matched = True
break
if not matched:
fn += 1
fp = len(pred_boxes) - tp
precision = tp / (tp + fp) if tp + fp > 0 else 0
recall = tp / (tp + fn) if tp + fn > 0 else 0
return precision, recall
def calculate_ap(precisions, recalls):
precisions = [0] + precisions + [0]
recalls = [0] + recalls + [1]
for i in range(len(precisions) - 1, 0, -1):
precisions[i - 1] = max(precisions[i - 1], precisions[i])
indices = [i for i in range(len(recalls) - 1) if recalls[i + 1] != recalls[i]]
ap = sum((recalls[i + 1] - recalls[i]) * precisions[i + 1] for i in indices)
return ap
def calculate_map(pred_boxes, true_boxes, iou_thresholds):
aps = []
for iou_threshold in iou_thresholds:
precisions = []
recalls = []
for pred, true in zip(pred_boxes, true_boxes):
precision, recall = calculate_precision_recall(pred, true, iou_threshold)
precisions.append(precision)
recalls.append(recall)
ap = calculate_ap(precisions, recalls)
aps.append(ap)
return np.mean(aps)
pred_boxes = [
[[50, 50, 100, 100], [30, 30, 50, 50]],
[[70, 80, 100, 100], [20, 30, 40, 50]]
]
true_boxes = [
[[55, 55, 90, 90], [35, 35, 45, 45]],
[[75, 85, 95, 95], [25, 35, 35, 45]]
]
iou_thresholds = np.arange(0.5, 1.0, 0.05)
map_05 = calculate_map(pred_boxes, true_boxes, [0.5])
map_05_095 = calculate_map(pred_boxes, true_boxes, iou_thresholds)
print(f"mAP@0.5: {map_05}")
print(f"mAP@0.5:0.95: {map_05_095}")
总结
- mAP@0.5:在 IoU 阈值为 0.5 时计算得到的 mAP,适用于评估模型能否大致定位目标。
- mAP@0.5:0.95:在多个 IoU 阈值(从 0.5 到 0.95,步长为 0.05)下计算得到的平均 mAP,提供了更全面和严格的评估标准。
- 计算方法:通过计算不同 IoU 阈值下的 AP,然后取平均值得到 mAP@0.5:0.95。
通过理解和计算这些指标,可以更好地评估和改进物体检测模型的性能。