欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mAP的计算方法

程序员文章站 2022-04-23 15:46:26
...

AP的计算

AP(Average Precision)计算方法为PR曲线下覆盖的面积
Precision与Recall数据的取值范围都在0~1之间,以Recall为X轴、以Precision为Y轴可以绘制PR曲线。
由于计算积分相对困难,因此引入插值法计算,计算AP公式如下:
mAP的计算方法

VOC2007对计算出来结果,根据原始取得的recall进行最大插值为11点的方式来计算AP,图示如下:
mAP的计算方法
mAP的计算方法
当前PASCAL VOC都是基于全插值方式来计算AP,全插值方法,同样是基于最大值进行插值,得到曲线显示如下:
mAP的计算方法

import numpy as np

def voc_ap(rec, prec, use_07_metric=False):
    """ ap = voc_ap(rec, prec, [use_07_metric])
    Compute VOC AP given precision and recall.
    If use_07_metric is true, uses the
    VOC 07 11 point method (default:False).
    """
    # 针对2007年VOC,使用的11个点计算AP,现在不使用
    if use_07_metric:
        # 11 point metric
        ap = 0.
        for t in np.arange(0., 1.1, 0.1):
            if np.sum(rec >= t) == 0:
                p = 0
            else:
                p = np.max(prec[rec >= t])
            ap = ap + p / 11.
    else:
        # correct AP calculation
        # first append sentinel values at the end
        mrec = np.concatenate(([0.], rec, [1.]))  #[0.  0.0666, 0.1333, 0.4   , 0.4666,  1.] 
        mpre = np.concatenate(([0.], prec, [0.])) #[0.  1.,     0.6666, 0.4285, 0.3043,  0.]

        # compute the precision envelope
        # 计算出precision的各个断点(折线点)
        for i in range(mpre.size - 1, 0, -1):
            mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i])  #[1.     1.     0.6666 0.4285 0.3043 0.    ]

        # to calculate area under PR curve, look for points
        # where X axis (recall) changes value
        i = np.where(mrec[1:] != mrec[:-1])[0]  #precision前后两个值不一样的点
        print(mrec[1:], mrec[:-1])
        print(i) #[0, 1, 3, 4, 5]

        # AP= AP1 + AP2+ AP3+ AP4
        ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1])
    return ap

rec = np.array([0.0666, 0.1333,0.1333, 0.4, 0.4666])
prec = np.array([1., 0.6666, 0.6666, 0.4285, 0.3043])
ap = voc_ap(rec, prec)

print(ap) #输出:0.2456

mAP的计算

最终根据每个类别的AP求和之后除以总的检测类别数目就得到mAP(mean Average Precision)。

mAP = sum(AP) / N
其中N表示总的类别数目

computer_mAP.py

from voc_eval import voc_eval
import os

mAP = []
# 计算每个类别的AP
for i in range(8):
    class_name = str(i)  # 这里的类别名称为0,1,2,3,4,5,6,7
    rec, prec, ap = voc_eval('path/{}.txt', 'path/Annotations/{}.xml', 'path/test.txt', class_name, './')
    print("{} :\t {} ".format(class_name, ap))
    mAP.append(ap)

mAP = tuple(mAP)

print("***************************")
# 输出总的mAP
print("mAP :\t {}".format( float( sum(mAP)/len(mAP)) ))