用于评估对象检测模型。告诉我们检测的怎么样。 。 首先我们来了解一些前述知识: FN(false negatives)假阴性 首先我们的预测是错误的,结果是负面的。 就比如我们新冠检测是错的,但是我们感染了新冠,也就是说检测出来我们没感染,实际上感染了。 FP(false positives)假阳性 首先我们的预测是错误的,结果是积极的。 就比如我们新冠检测是错的,但是我们没感染新冠,也就是说检测出来我们感染了,实际上没感染。 TN(true negatives)真阴性 首先我们的预测是正确的,结果是阴性。 新冠检测是正确的,我们确实没感染新冠。 TP(true positives)真阳性 首先我们的预测是正确的,结果是阳性。 新冠检测是正确的,我们确实感染了新冠。
若是觉得不好记,就记住,真不变假变。
precision精确度:
recall召回率:
不同的应用方向,召回率和精确度的注重程度不一样。
在我们求出准确度和召回率之后,我们需要画图 y轴是准确度,x轴是召回率 假设我们有2个检测项目,一个是狗,一个是猫。
假设狗的AP 是0.4,猫的AP是0.6 那么mAP就是:
如果那么看到mAP@0.5:0.05:0.95。这个意思是IOU精度是0.5,0.55,0.95,我们要根据不同的iou设定,进行计算,然后将所得的各个mAP进行平均计算,最终的结果才是mAP@0.5:0.05:0.95的值。
mAP代码实现:
其中intersection_over_union的代码在我上一个目标检测专栏里面。
import torch
from collections import Counter
from iou import intersection_over_union
def mean_average_precision(pred_boxes, true_boxes, iou_threshold
, box_format="corners", num_classes=20):
average_precisions = []
epsilon = 1e-6
for c in range(num_classes):
detections = []
ground_truths = []
for detection in pred_boxes:
if detection in pred_boxes == c:
detections.append(detection)
for true_box in true_boxes:
if true_box[1] == c:
ground_truths.append(true_box)
amount_bboxes = Counter([gt[0] for gt in ground_truths])
for key,val in amount_bboxes.items():
amount_bboxes[key] = torch.zeros(val)
detections.sort(key=lambda x:x[2],reverse=True)
TP = torch.zeros((len(detections)))
FP = torch.zeros((len(detections)))
total_true_bboxes = len(ground_truths)
for detection_idx,detection in enumerate(detections):
ground_truths_img = [
bbox for bbox in ground_truths if bbox[0] ==detection[0]
]
num_gts = len(ground_truths_img)
best_iou = 0
for idx , gt in enumerate(ground_truths_img):
iou = intersection_over_union(
torch.tensor(detection[3:]),
torch.tensor(gt[3:]),
box_format=box_format
)
if iou>best_iou:
best_iou = iou
best_gt_idx = idx
if best_iou>iou_threshold:
if amount_bboxes[detection[0]][best_gt_idx] == 0:
TP[detection_idx]=1
amount_bboxes[detection[0]][best_gt_idx] = 1
else:
FP[detection_idx]=1
else:
FP[detection_idx] =1
TP_cumsum = torch.cumsum(TP,dim=0)
FP_cumsum = torch.cumsum(FP,dim=0)
recalls = TP_cumsum / (total_true_bboxes + epsilon)
precisions = torch.divide(TP_cumsum,(TP_cumsum + FP_cumsum + epsilon))
precisions = torch.cat((torch.tensor([1]),precisions))
recalls = torch.cat((torch.tensor([0]),recalls))
average_precisions.append(torch.trapz(precisions,recalls))
return sum(average_precisions) / len(average_precisions)
|