目标检测评价指标(mAP)

常见指标

  • precision 预测出的所有目标中正确的比例 (true positives / true positives + false positives).
  • recall 被正确定位识别的目标占总的目标数量的比例 (true positives/(true positives + false negatives)).

一般情况下模型不够理想,准确率高、召回率低,或者召回率低、准确率高。如果做疾病监测、反垃圾,则是保准确率的条件下,提升召回率。如果是做搜索,那就是保证召回的情况下提升准确率。[1]

Precision和Recall的计算图示如下:

precision-recall

以行人检测为例,精度就是检测出来的行人中确实是行人的所占的百分比;Recall就是正确检出的行人数量占行人总数的百分比,Recall=100%表示没有漏检;这两个常常是一对矛盾,通常我们总是希望既没有虚景也不会发生漏检的情况,也就是Precision和Recall均为100%的状况。

  • F1 score 通常我们使用precision和recall两个指标来衡量模型的好坏,但是同时要权衡这两个量,影响我们做决策的速度.可以使用F1 score来组合这两个量(又称F score,F measure,名称F没有什么意义):

\[F_1\ \text{Score} ={2\over {1\over P}+{1\over R}}= 2{PR\over P+R}\in[0,1] \]

F1 score 是 \(F=1/(\lambda{1\over P}+(1-\lambda){1\over R})\) 的简化版(\(\lambda=0.5\)).
P和R的值均是越大越好,因此F1 score也越大结果越好.

  • AUC ROC 曲线下的面积,面积越大,分类效果越好.ROC横轴为假正率(FP,false positive),纵轴为真正率(TP,true positive)。 通过给分类器设置不同的置信度阈值得到多组(FP,TP)数据绘制成ROC 曲线。ROC 曲线如下图所示:

ROC curve

AUC 的含义:AUC值是一个概率值,当你随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值。当然,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面,即能够更好的分类。

为什么使用ROC曲线?
评价标准已有很多,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。[2]

  • loss_bbox 预测边框和真实边框的坐标之间的差别,如采用smooth L1 loss计算.
  • mAP 对于每一类计算平均精度(AP,average precision),然后计算所有类的均值。mAP 综合考量了P、R,解决P,R的单点值局限性。PR曲线与ROC曲线类似,曲线下面积越大越好,因此我们定义PR曲线下面积为:

\[\rm{mAP} = \int_0^1 P(R)dR \]

当然,这种积分只是一种理想的计算方式, 实际中可采用 Approximated Average precision: \(\sum_{k=1}^N P(k)\Delta r(k)\). 表示当识别出k张图片(或目标)时准确率与召回率的变化量(从k-1变化到k)的乘积累加和.
另一种度量性能的标准:Interpolated Average Precision。这一新的算法不再使用P(k),而是使用:\(\sum_{k=1}^N \max_{\tilde{k}\ge k}P(\tilde{k})\Delta r(k)\).
使用Interpolated Average Precision算出的Average Precision值明显要比Approximated Average Precision的方法算出的要高。
很多文献都是用Interpolated Average Precision 作为度量方法,并且直接称算出的值为Average Precision 。PASCAL Visual Objects Challenge从2007年开始就是用这一度量制度,他们认为这一方法能有效地减少Precision-recall 曲线中的抖动。[1:1]

mAP (VOC)

在论文中常看到top-5 xxx, mAP@0.5等,下面对此作出解释.

\[AP = {1\over 11}\sum_{r\in \{0,0.1,...,1\}} P_{interp}(r) \\ \text{mAP} = {\sum_{q=1}^Q AP(q)\over Q} \]

首先用训练好的模型得到所有测试样本的confidence score.接下来对confidence score排序,然后计算precision和recall.
计算precision和recall时可以只计算按confidence score排序后top-n的样本,称为top-n precision/recall.
实际多类别分类任务中,我们通常不满足只通过top-5来衡量一个模型的好坏,而是需要知道从top-1到top-N(N是所有测试样本个数,本文中为20)对应的precision和recall。显然随着我们选定的样本越来也多,recall一定会越来越高,而precision整体上会呈下降趋势。把recall当成横坐标,precision当成纵坐标,即可得到常用的precision-recall曲线。precision-recall曲线如下:

P-R-curv

接下来说说AP的计算,此处参考的是PASCAL VOC challenge 的计算方法。首先设定一组阈值,[0, 0.1, 0.2, …, 1]。然后对于recall大于每一个阈值(比如recall>0.3),我们都会得到一个对应的最大precision。这样,我们就计算出了11个precision。AP即为这11个precision的平均值。这种方法英文叫做11-point interpolated average precision(差值平均精度)。具体流程为:

  1. 对于类别C,首先将算法输出的所有C类别的预测框,按置信度排序;
  2. 设定不同的k值,选择top k个预测框,计算FP和TP,使得 recall 分别等于0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0;
    计算Precision;
  3. 将得到的11个Precision取平均,即得到AP;
    AP是针对单一类别的,mAP是将所有类别的AP求和,再取平均:
    mAP = 所有类别的AP之和 / 类别的总个数

PASCAL VOC challenge 自2010年后换了另一种计算方法,提高了计算的精度,能更好地区分低准确率的方法。新的计算方法假设这N个样本中有M个正例,那么我们会得到M个recall值,对于每个recall值r,我们可以计算出对应(r' > r)的最大precision,然后对这M个precision值取平均即得到最后的AP值。参考voc2012/devkit_doc.
改进后曲线单调递减:

PR-curv2

改进后的 mAP 值通常比 VOC07 的方法得到的 mAP 高一些(一般5%以内), 但也存在变低的情况。因为计算的是曲线下的面积,有时也写作ap_auc。可参考下文的代码进行理解。

AP衡量的是学出来的模型在每个类别上的好坏,mAP是取所有类别AP的平均值,衡量的是在所有类别上的平均好坏程度。

AP(COCO)[3]

在 MSCOCO 竞赛中\(AP^{50}\)或者AP@0.5指的是当设置IoU为0.5时的平均准确率。\(AP^{75}\) 是严格模式的测量. \(AP^\rm{small},AP^\rm{medium},AP^\rm{large}\) 分别对应面积 \(area <32^2,32^2 < area < 96^2,area > 96^2\) 的目标分别测试的值.

mAP@[.5:.95]是在不同 IoU (从 0.5 到 0.95, 步长0.05) 设置下的平均值,又可写作mmAP或 AP, 参考cocoeval.py.

mAP 代码参考

VOC 目标检测评估函数

function [rec,prec,ap] = VOCevaldet(VOCopts,id,cls,draw)

% npos 为ground truth objects的数目, 计算中会忽略difficult的样本
% sort detections by decreasing confidence  
[sc,si]=sort(-confidence);   %按照score降序排序  
ids=ids(si);  
BB=BB(:,si);  
  
% assign detections to ground truth objects  
nd=length(confidence);  
tp=zeros(nd,1);  
fp=zeros(nd,1);  
tic;  
for d=1:nd  
    % find ground truth image  
    i=strmatch(ids{d},gtids,'exact');  
    if isempty(i)  
        error('unrecognized image "%s"',ids{d});  
    elseif length(i)>1  
        error('multiple image "%s"',ids{d});  
    end  
  
    % assign detection to ground truth object if any  
    bb=BB(:,d);  
    ovmax=-inf;  
    for j=1:size(gt(i).BB,2)  
        bbgt=gt(i).BB(:,j);  
        bi=[max(bb(1),bbgt(1)) ; max(bb(2),bbgt(2)) ; min(bb(3),bbgt(3)) ; min(bb(4),bbgt(4))];  
        iw=bi(3)-bi(1)+1;  
        ih=bi(4)-bi(2)+1;  
        if iw>0 & ih>0                  
            % compute overlap as area of intersection / area of union  
            ua=(bb(3)-bb(1)+1)*(bb(4)-bb(2)+1) + (bbgt(3)-bbgt(1)+1)*(bbgt(4)-bbgt(2)+1) - iw*ih;
            ov=iw*ih/ua;  
            if ov>ovmax  
                ovmax=ov;  
                jmax=j;  
            end  
        end  
    end  
    % assign detection as true positive/don't care/false positive  
    if ovmax>=VOCopts.minoverlap  
        if ~gt(i).diff(jmax)  
            if ~gt(i).det(jmax)  
                tp(d)=1;            % true positive  
                gt(i).det(jmax)=true;  
            else  
                fp(d)=1;            % false positive (multiple detection)   % 若多个目标框对应同一个gt,则将后续(低score的)目标设为FP
            end  
        end  
    else  
        fp(d)=1;                    % false positive  
    end  
end  

% 由于目标框按score排序,设置不同的score阈值可以得到不同的P/R, 因此可以通过累加操作计算
fp=cumsum(fp);  
tp=cumsum(tp);  
rec=tp/npos;  
prec=tp./(fp+tp);  

% VOC2007: compute 11 point average precision  
ap=0;  
for t=0:0.1:1  
    p=max(prec(rec>=t));  
    if isempty(p)  
        p=0;  
    end  
    ap=ap+p/11;  
end  

% VOC2012: 
ap_new = VOCap(rec,prec);

% VOCap计算方式如下:
function ap = VOCap(rec,prec)

mrec=[0 ; rec ; 1]; % 在召回率列表首尾添加两个值
mpre=[0 ; prec ; 0];
for i=numel(mpre)-1:-1:1
    mpre(i)=max(mpre(i),mpre(i+1)); % 使mpre单调递减
end
i=find(mrec(2:end)~=mrec(1:end-1))+1; % 找出召回率产生变化的下标
ap=sum((mrec(i)-mrec(i-1)).*mpre(i)); % 计算ROC曲线下面积

重叠度(IoU,Intersect over Union):

因为我们算法不可能百分百跟人工标注的数据完全匹配,因此就存在一个对于bounding box的定位精度评价公式:IoU。 它定义了两个bounding box的重叠度,如下图所示

IOU

IoU就是矩形框A、B的重叠面积占A、B并集的面积比例(\(A\bigcap B\over A\bigcup B\))。
这与Jaccard相似度定义类似: \(J(A,B)={|A\cap B| \over |A\cup B|}\)

通常我们认为:
• Correct: 类别正确 且 IoU > .5
• Localization: 类别正确, .1 < IoU < .5
• Similar: 类别近似, IoU > .1
• Other: 类别错误, IoU > .1
• Background: IoU < .1 的任意目标

python代码实现

# Calculate Intersect over usion between boxes b1 and b2, here each box is defined with 2 points
# box(startX, startY, endX, endY), there are other definitions ie box(x,y,width,height)
def calc_iou(b1, b2):
 # determine the (x, y)-coordinates of the intersection rectangle
 xA = max(b1[0], b2[0])
 yA = max(b1[1], b2[1])
 xB = min(b1[2], b2[2])
 yB = min(b1[3], b2[3])

 # compute the area of intersection rectangle
 area_intersect = (xB - xA + 1) * (yB - yA + 1)

 # Calculate area of boxes
 area_b1 = (b1[2] - b1[0] + 1) * (b1[3] - b1[1] + 1)
 area_b2 = (b2[2] - b2[0] + 1) * (b2[3] - b2[1] + 1)

 # compute the intersection over union by taking the intersection
 # area and dividing it by the sum of prediction + ground-truth
 # areas - the intersection area
 iou = area_intersect / float(area_b1 + area_b2 - area_intersect)

 # return the intersection over union value
 return iou

# IoU 实现 numpy 方式
import numpy as np

def calc_iou_np(xy_min1, xy_max1, xy_min2, xy_max2):
    # Get areas
    areas_1 = np.multiply.reduce(xy_max1 - xy_min1)
    areas_2 = np.multiply.reduce(xy_max2 - xy_min2)

    # determine the (x, y)-coordinates of the intersection rectangle
    _xy_min = np.maximum(xy_min1, xy_min2) 
    _xy_max = np.minimum(xy_max1, xy_max2)
    _wh = np.maximum(_xy_max - _xy_min, 0)

    # compute the area of intersection rectangle
    _areas = np.multiply.reduce(_wh)

    # return the intersection over union value
    return _areas / np.maximum(areas_1 + areas_2 - _areas, 1e-10)

参考


  1. https://cblog.xyz/article/292 ↩︎ ↩︎

  2. http://alexkong.net/2013/06/introduction-to-auc-and-roc/ ↩︎

  3. http://cocodataset.org/#detection-eval ↩︎

posted @ 2018-04-02 21:15  康行天下  阅读(27611)  评论(4编辑  收藏  举报