【mAP】mean average precision 平均精度及其实现

用于评估对象检测模型。告诉我们检测的怎么样。

首先我们来了解一些前述知识:
FN(false negatives)假阴性
首先我们的预测是错误的,结果是负面的。
就比如我们新冠检测是错的,但是我们感染了新冠,也就是说检测出来我们没感染,实际上感染了。
FP(false positives)假阳性
首先我们的预测是错误的,结果是积极的。
就比如我们新冠检测是错的,但是我们没感染新冠,也就是说检测出来我们感染了,实际上没感染。
TN(true negatives)真阴性
首先我们的预测是正确的,结果是阴性。
新冠检测是正确的,我们确实没感染新冠。
TP(true positives)真阳性
首先我们的预测是正确的,结果是阳性。
新冠检测是正确的,我们确实感染了新冠。

若是觉得不好记,就记住,真不变假变。
【mAP】mean average precision 平均精度及其实现_第1张图片


precision精确度:

【mAP】mean average precision 平均精度及其实现_第2张图片


recall召回率:

【mAP】mean average precision 平均精度及其实现_第3张图片
不同的应用方向,召回率和精确度的注重程度不一样。

在我们求出准确度和召回率之后,我们需要画图
y轴是准确度,x轴是召回率
假设我们有2个检测项目,一个是狗,一个是猫。

【mAP】mean average precision 平均精度及其实现_第4张图片
假设狗的AP 是0.4,猫的AP是0.6
那么mAP就是:

在这里插入图片描述
如果那么看到[email protected]:0.05:0.95。这个意思是IOU精度是0.5,0.55,0.95,我们要根据不同的iou设定,进行计算,然后将所得的各个mAP进行平均计算,最终的结果才是[email protected]: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):
    # num_classes是根据不同的数据集变化的。
    # pred_boxes(是一个列表):[[train_idx,class_pred,pred_score,x1,y1,x2,y2],...]

    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)
        # 如果image0 有3个检测框,image 有5个检测框
        # 那么 amount_bboxes = {0:3,1:5}
        amount_bboxes = Counter([gt[0] for gt in ground_truths])

        for key,val in amount_bboxes.items():
            amount_bboxes[key] = torch.zeros(val)
        # amount_bboxes = {0:torch.tensor([0,0,0],1:torch.tensor([0,0,0,0,0]}
        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

        #这是求累计的和
        #比如[1,0,1,1,0,1] >>cumsum>> [1,1,2,3,3,4]
        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)

你可能感兴趣的:(目标检测,深度学习,机器学习,目标检测,计算机视觉,人工智能)