准确率(Precision),也叫正确预测率(positive predictive value),在模式识别、信息检索、机器学习等研究应用领域,准确率用来衡量模型预测的结果中相关或者正确的比例。而召回率(recall),也叫敏感度(sensitivity),即模型预测的结果中相关或正确的数量占样本中实际相关或正确的数量的比例。一般在计算机视觉领域物体分类检测任务中,检测出的物体轮廓框如果类别和ground truth的类别相同,并且两者之间IoU大于一个阈值(一般为0.5),那么该预测值是正确的。如果模型预测出数据集中有N个horse这一类的物体,并给出其轮廓框,而实际场景中有T个horse标签的ground truth。在2000个预测值中,有些是错误的,即和ground truth的IoU小于阈值,又或者IoU大于阈值,但是该ground truth已经有和其相关的预测值了,此时该预测值均为假正例(false positive,FP),有些和ground truth的IoU大于阈值,并且为唯一和ground truth相关的预测值,那么该预测值为真正例(true positive, TP)。那么此时准确率的计算为precision=TP/(TP+FP)。而召回率的计算则为recall=TP/T.

准确率和召回率是一对矛盾的度量尺度,一般来说,准确率高时,召回率往往很低,而召回率高时,准确率往往偏低。例如在物体分类检测任务中,一组预测轮廓框有两个指标,一个是分类的score,一组是轮廓框的坐标位置。若希望将找出更多的该类的预测轮廓框,则需要将分类score的阈值降低,输出更多的结果,此时必然会有些预测值为假,造成准确率下降,但是召回率会得以提高。但是如果想准确率高,则需要提高分类score,将分类得分很低的预测值丢弃,那么可能会漏掉很多和ground truth的IoU大于阈值的预测结果,造成召回率降低。

在很多情况中,需要对模型的预测结果进行排序,在物体分类检测中,一般是按照分类score进行排序,排在前面的预测结果一般被认为“最可能”为真正例的预测结果,排在后面的则是模型认为“可能性低”的真正例。按照此顺序逐个把预测结果进行分析,每个预测值均可以得到一个准确率和召回率,以召回率为横轴,准确率为纵轴作图,就得到了准确率-召回率曲线,一般称为precision-recall曲线。Precision-recall曲线图直观地显示了模型在数据集上的准确率、召回率详细分布情况。在进行模型选择时,直观上可以看到,如果模型A的precision-recall曲线将模型B的precision-recall曲线完全包住,则模型A的性能优于B。而若模型A的precision-recall曲线和模型C的precision-recall曲线有交点,则此时无法直观上判定模型的优劣,此时一般用precision-recall曲线下面积的大小来进行比较,这个面积在物体分类检测任务中是另外一项衡量模型优劣的指标ap(average precision)值。而如果数据集有多类,那么每个类计算得到ap后再平均所有类的ap即使mAP. mAP是评估模型在数据集上各个类上的整体表现性能,也是以各个数据集为基础举办各种物体检测竞赛的主要评估指标。

计算AP和mAP的代码,来自PASCAL VOC物体检测竞赛的devkit,是和数据集一起公开的测试评估代码,供参赛者提交代码前进行初步的模型性能评估。可以看到代码先计算了预测值和ground truth的IoU,再而计算tp, fp, precision和recall.而后根据precision和recall计算precision-recall曲线下的面积,即AP,并将每类的precision-recall曲线绘制。下图给出根据precision-recall曲线计算ap的结果。图中给出PASCAL VOC 2007数据检测结果其中两类的precision-recall曲线,从图中可以看出,car这类的曲线弧度比较大,因此ap值比较大。而chair这类的曲线则是直线下降的,因此ap值比较小。

工程上,我们一般要求recall很高,而precision也很高。那么上图中,对chair这一类的检测就无法达到这个目标,在recall很高时,precision就会很低,也就造成很高的误检率。这种时候,为了降低误检率,即tp,会将ap图从中间截断,根据工程需要,选择一个阈值,如图所示,蓝色红色绿色三条线分别对应不同的recall和precison,如果你想要大的precision,选择蓝色线处,如果想要大recall,选择绿色线处截断ap图。

比如在某次训练的检测器中,对类别car的检测结果如下,因为需要降低误检,此时选择了f1=2*precision*recall/(precision+recall)最高时的阈值,可以看到此时ap并不是很高,说明该检测器还有待提升。

至于map,那就是mean ap的缩写。即各个类的ap做个均值即可,那么就是各个类都高了,均值就高了,map也就大了。

附录是matlab代码,python版本的现在也一大堆,因为我最开始做检测是一句一句解读matlab代码开始的,所以附上,算作纪念:

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

% load test set
[gtids,t]=textread(sprintf(VOCopts.imgsetpath,VOCopts.testset),'%s %d'); % load ground truth objects
tic;
npos=0;
gt(length(gtids))=struct('BB',[],'diff',[],'det',[]);
for i=1:length(gtids)
% display progress
if toc>1
fprintf('%s: pr: load: %d/%d\n',cls,i,length(gtids));
drawnow;
tic;
end % read annotation
rec=PASreadrecord(sprintf(VOCopts.annopath,gtids{i})); % extract objects of class
clsinds=strmatch(cls,{rec.objects(:).class},'exact');
gt(i).BB=cat(1,rec.objects(clsinds).bbox)';
gt(i).diff=[rec.objects(clsinds).difficult];
gt(i).det=false(length(clsinds),1);
npos=npos+sum(~gt(i).diff);
end % load results
[ids,confidence,b1,b2,b3,b4]=textread(sprintf(VOCopts.detrespath,id,cls),'%s %f %f %f %f %f');
BB=[b1 b2 b3 b4]'; % sort detections by decreasing confidence
[sc,si]=sort(-confidence);
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');
% 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)
end
end
else
fp(d)=1; % false positive
end
end
% compute precision/recall
fp=cumsum(fp); tp=cumsum(tp); rec=tp/npos; prec=tp./(fp+tp);
% compute 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
if draw
% plot precision/recall
plot(rec,prec,'-');
grid;
xlabel 'recall'
ylabel 'precision'
title(sprintf('class: %s, subset: %s, AP = %.3f',cls,VOCopts.testset,ap));
end

  

物体检测序列之一:ap, map的更多相关文章

  1. 评价目标检测(object detection)模型的参数:IOU,AP,mAP

    首先我们为什么要使用这些呢? 举个简单的例子,假设我们图像里面只有1个目标,但是定位出来10个框,1个正确的,9个错误的,那么你要按(识别出来的正确的目标/总的正确目标)来算,正确率100%,但是其实 ...

  2. 目标检测的评价标准mAP, Precision, Recall, Accuracy

    目录 metrics 评价方法 TP , FP , TN , FN 概念 计算流程 Accuracy , Precision ,Recall Average Precision PR曲线 AP计算 A ...

  3. 手把手教你用深度学习做物体检测(五):YOLOv1介绍

    "之前写物体检测系列文章的时候说过,关于YOLO算法,会在后续的文章中介绍,然而,由于YOLO历经3个版本,其论文也有3篇,想全面的讲述清楚还是太难了,本周终于能够抽出时间写一些YOLO算法 ...

  4. 目标检测评价标准(mAP, 精准度(Precision), 召回率(Recall), 准确率(Accuracy),交除并(IoU))

    1. TP , FP , TN , FN定义 TP(True Positive)是正样本预测为正样本的数量,即与Ground truth区域的IoU>=threshold的预测框 FP(Fals ...

  5. 物体检测之FPN及Mask R-CNN

    对比目前科研届普遍喜欢把问题搞复杂,通过复杂的算法尽量把审稿人搞蒙从而提高论文的接受率的思想,无论是著名的残差网络还是这篇Mask R-CNN,大神的论文尽量遵循著名的奥卡姆剃刀原理:即在所有能解决问 ...

  6. 物体检测丨Faster R-CNN详解

    这篇文章把Faster R-CNN的原理和实现阐述得非常清楚,于是我在读的时候顺便把他翻译成了中文,如果有错误的地方请大家指出. 原文:http://www.telesens.co/2018/03/1 ...

  7. Tensorflow 之物体检测

    1)安装Protobuf TensorFlow内部使用Protocol Buffers,物体检测需要特别安装一下. # yum info protobuf protobuf-compiler 2.5. ...

  8. cs231n---语义分割 物体定位 物体检测 物体分割

    1 语义分割 语义分割是对图像中每个像素作分类,不区分物体,只关心像素.如下: (1)完全的卷积网络架构 处理语义分割问题可以使用下面的模型: 其中我们经过多个卷积层处理,最终输出体的维度是C*H*W ...

  9. 手把手教你用深度学习做物体检测(六):YOLOv2介绍

    本文接着上一篇<手把手教你用深度学习做物体检测(五):YOLOv1介绍>文章,介绍YOLOv2在v1上的改进.有些性能度量指标术语看不懂没关系,后续会有通俗易懂的关于性能度量指标的介绍文章 ...

  10. 利用modelarts和物体检测方式识别验证码

    近来有朋友让老山帮忙识别验证码.在github上查看了下,目前开源社区中主要流行以下几种验证码识别方式: tesseract-ocr模块: 这是HP实验室开发由Google 维护的开源 OCR引擎,内 ...

随机推荐

  1. Spring(XML方式)简单入门

    环境准备 maven jdk Spring Eclipse 项目创建 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0 ...

  2. 微软GraphRAG框架源码解读

    两个月前,微软发布了GraphRAG的论文<From Local to Global: A Graph RAG Approach to Query-Focused Summarization&g ...

  3. PowerBuilder编程新思维6.5:外传1(PowerPlume的设计与规划)

    <第五部分 Otherside 意外的宝藏> 每一颗种子都有发芽的梦想.PowerPlume(孔雀翎)开发交流群:286502392    PowerBuilder编程新思维6.5:外传1 ...

  4. oeasy教您玩转vim - 72 - # 缩写abbreviation

    ​ 缩写abbreviation 回忆上次折叠的细节 这次了解到了:mkview.:loadview 保存和加载视图 可以把当前的状态保存下来 可以在 viewoption 中配置保存选项,设置哪些需 ...

  5. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-59 - 判断元素是否显示 - 上篇

    1.简介 有些页面元素的生命周期如同流星一闪,昙花一现.我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒.我们就来判断元素是否显示出现过. 在操作元素之前,可以先判断元素的状 ...

  6. Jmeter函数助手38-isVarDefined

    isVarDefined函数用于判断变量是否存在. 变量的名称:填入变量名称.如果变量存在返回true,如果不存在返回false 1.先一些定义变量 ${__isVarDefined(now)},no ...

  7. 对比python学julia(第一章)--(第三节)山巅一寺一壶酒

    在小学阶段背过圆周率的同学对这节的标题应该不陌生.π(3.14159-)是大家熟悉的普通无理数,但也是非常神秘的一组数字,例如几个世纪以来,埃及考古学家和神秘主义追随者一直痴迷于胡夫金字塔暗藏的圆周率 ...

  8. 【ActiveJdbc】05

    一.事务 通常在 Java ORM 中有一个显式连接或管理器对象(JPA 中的 EntityManager,Hibernate 中的 SessionManager 等). ActiveJDBC 中没有 ...

  9. 【ECharts】04 数据交互

    ECharts 异步加载数据 ECharts 通常数据设置在 setOption 中,如果我们需要异步加载数据,可以配合 jQuery等工具,在异步获取数据后通过 setOption 填入数据和配置项 ...

  10. 【Layui】11 滑块 Slider

    文档地址: https://www.layui.com/demo/slider.html 基本滑块: <fieldset class="layui-elem-field layui-f ...