目标检测Object Detection下的Precision & Recall和分类问题中的有何不同?

一,目标检测中的Precision & Recall

Precision,准确率/查准率 Recall,召回率/查全率

P r e c i s i o n = T P T P + F P Precision= \frac{TP}{TP+FP} Precision=TP+FPTP
准确率比较好理解,就是检测出的所有正样本中多少是真正的正样本
R e c a l l = T P T P + F N Recall= \frac{TP}{TP+FN} Recall=TP+FNTP
Recall召回率其实最主要的是理解FN,其实FN(False Negative)就是被判断负样本但其实是正样本。以猫狗二分类问题为例,如果猫为正,狗为负,FN其实就是本来是猫判断为狗的样本,FN+TP其实就是样本中所有的猫

首先我们要知道,Precision和Recall是针对分类问题的,更准确的说是针对二分类问题的,网上铺天盖地的介绍这两个指标的文章都没有强调这一点,所以要在检测问题上使用这两个指标必须要转换成二分类问题来看。在计算的时候要清楚到底那些量要计入,哪些量不计入,比如5只没有识别出来的猫和识别成狗的猫对于计算猫这个分类的Precision和Recall来说都要记为Negative。

比如一个检测问题有80个类,要看模型检测猫分类的P和R,那其他所有分类都要看作Negative,猫是Positive。FN就是漏检加错检,比二分类多了个漏检。漏检就是比如有一只猫压根没检测出来,错检是本来是1只猫被检成了狗。所以这个Negtive就是漏了或者错了。对于猫这类来说,漏了的加上错了的加上对的其实就是GT中猫框的总数,也就是TP+FN。(补充一点,每一组TP和FN都是在某个IOU阈值和置信度阈值下来讨论的,一般会固定IOU,比如IOU固定0.5,然后从检测结果中挑出置信度大于,比如0.5,所有检测结果来计算一组P和R)

如果一只猫被检成了狗,那算不算猫分类的FN?算,同时,这也算狗分类的FP
如果一只狗被检成了猫,那算不算猫分类的FN?不算,这算猫分类的FP,狗分类的FN

举个栗子,111张图片里有100只猫,100只狗,我进行了一次检测,假设IOU阈值IOU0.5,预测置信度阈值0.5的条件下,100只猫识别正确了90只,5只没有识别出来,5只识别成了狗。100只狗识别正确了80只,17只识别成了猫,3只没有识别出来。

以猫为例,只要识别结果是猫就是正样本,区别是有些是真正样本,有些是假正样本
所以这个问题中一共识别出107只猫,其中
TP=90,FP=17,所以最后Precision = 90/(90+17)=0.84
再来看Recall,没有识别出来的猫和识别错误的猫(把猫识别成狗)都是假负样本,所以有
TP=90,FN=5+5,所以最后Recall = 90/(90+5+5)=0.9

我们来理解一下这两个数字,0.84表示对此测试集来说,识别猫的准确率只有0.84,0.9表示所有的猫我找出来了90%。

同样的,狗
Precision = 80/(80+5)=0.94,所有识别为狗的图像中,模型准确率为94%
Recall = 80/(80+17+3)=0.8,所有的狗我只找出了80%

扫描二维码关注公众号,回复: 15623424 查看本文章

我们发现,其实Recall的分母部分就是GT中的正样本数量。在检测问题中,这两个指标与多少张图片并没有关系,因为一张图里面常常有猫有狗,数量也不确定,所以在检测问题中样本数量和图像数量无关,就是看对应类别GT框的个数

画张图举个例子:

在这里插入图片描述

在0.6置信度阈值下,IOU阈值设为0.5,蓝色框是猫类别的GT,绿色框是IOU大于0.5的猫,红色框是IOU小于0.5的猫,紫色框是IOU大于0.5但把狗识别成了猫,求对于猫分类的P,R。

P = 3/(3+1)=0.75
R = 3/(3+2) = 0.6

首先要清楚这次计算到底有哪些预测框纳入计算?3绿1紫共4个框,右上角iou小于0.5实际上结果中会被删除
TP=3,所有检测出的3个绿框和1个紫框中有3个绿框是识别正确的
FP=1,首先FP中的P指的是识别出来的正样本,一共四个,其次要是识别错误的正样本,就是紫色的狗那个框
FN=2,分别是因为IOU低于0.5被剔除的右上角的红色猫框,其实是没捡出来,还有一个是左下角漏检的猫

置信度阈值影响结果吗?在这个问题中不影响,因为所有的预测结果都已经是在这个置信度阈值过滤后的结果了,如果置信度变了,上图中的框可能也会跟着变,就成了另一组P,R了。其实P-R曲线就是在某一个固定的IOU下,对置信度(0~1)所产生的所有P,R值的曲线。这个后面再说。

重复一下上面一句话:
如果一只狗被检成了猫,那算不算猫分类的FN?不算,这算猫分类的FP,狗分类的FN

这样这个问题就清楚了。

二,为什么要这两个指标?

假设有100个样本,其中有2只猫,98只狗,一个模型识别出了其中一只猫,其他都判断为狗

对狗来说:
Presision = 98/(98+1)=0.989
Recall=98/98=100%

用语言描述一下就是你检出的狗中正确率为98.9%,而且所有的狗100%检出。

对猫来说:
P = 1/(1+0) = 100%
R = 1/(1+1) = 50%

用语言描述一下就是你检出的猫的确100%都是猫,但是所有猫中你只检出50%。

三,代码解析

https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py
我们以pascal voc的map计算代码为例,看倒数几行

    # compute precision recall
    fp = np.cumsum(fp)
    tp = np.cumsum(tp)
    rec = tp / float(npos)
    # avoid divide by zero in case the first detection matches a difficult
    # ground truth
    prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps)
    ap = voc_ap(rec, prec, use_07_metric)

    return rec, prec, ap

就是计算fp,tp和tp+fn,其中tp+fn=代码中的float(npos)
我们来看一下npos的代码

npos = 0
    for imagename in imagenames:
        R = [obj for obj in recs[imagename] if obj['name'] == classname]
        bbox = np.array([x['bbox'] for x in R])
        difficult = np.array([x['difficult'] for x in R]).astype(np.bool)
        det = [False] * len(R)
        npos = npos + sum(~difficult)
        class_recs[imagename] = {
    
    'bbox': bbox,
                                 'difficult': difficult,
                                 'det': det}

这段代码的意思就是对于所有的图片中的所有=classname的对象,以猫为例,去掉difficult的数据,剩下的加起来就是npos的最终值,和我们上面说的FN+TP其实就是样本中所有的猫 一致,只是这边难样本被去掉不计入而已。

再稍微解释一下,difficult是一个list,按index标识R里的每个GT框,里面如果这个目标是difficult的记为1,不是记为0.例如difficult=[0,1,1,0,1]代表5个某类的GT检测框的对应难度,其中3个是难样本,2个不是。然后转换成bool类型,difficult=[false,true,true,false,true],取反,difficut=[true,false,false,true,false],求和就是其中需要被检测的不是难样本的框的数量,为2,代表5个框中有2个非难样本计数。注意取反操作对nparray有效,python list并不支持。

在此基础上,我们要计算AP,mAP就容易了,请看下一篇,关于AP和mAP,以及P-R曲线等,见

AP,mAP,P-R曲线详解

猜你喜欢

转载自blog.csdn.net/catscanner/article/details/111272936