指标含义

参考  https://zhuanlan.zhihu.com/p/60707912
mmap的解释:
给定一组IOU阈值,在每个IOU阈值下面,求所有类别的AP,并将其平均起来,作为这个IOU阈值下的检测性能,称为mAP(比如mAP@0.5就表示IOU阈值为0.5时的mAP);最后,将所有IOU阈值下的mAP进行平均,就得到了最终的性能评价指标:mmAP。

值得注意的一个细节是:在实际计算时,mmAP并不会把所有检测结果都考虑进来,因为那样总是可以达到Recall=100%,为了更有效地评价检测结果,mmAP只会考虑每张图片的前100个结果。这个数字应该随着数据集变化而改变,比如如果是密集场景数据集,这个数字应该提高。

关键过程和解析

分别读取检测结果的json文件和gt的json文件,然后进行评估

(1)COCOeval的初始化

cocoEval = COCOeval(cocoGt, cocoDt, iou_type)
其中cocoGt和cocoDt都是pycocotools.coco.COCO类

        self.cocoGt   = cocoGt              # ground truth COCO APIself.cocoDt   = cocoDt              # detections COCO APIself.evalImgs = defaultdict(list)   # per-image per-category evaluation results [KxAxI] elementsself.eval     = {}                  # accumulated evaluation resultsself._gts = defaultdict(list)       # gt for evaluationself._dts = defaultdict(list)       # dt for evaluationself.params = Params(iouType=iouType) # parametersself._paramsEval = {}               # parameters for evaluationself.stats = []                     # result summarizationself.ious = {}                      # ious between all gts and dtsif not cocoGt is None:self.params.imgIds = sorted(cocoGt.getImgIds())self.params.catIds = sorted(cocoGt.getCatIds())

(2)设置cocoEval的相关属性

cocoEval.params.catIds = self.cat_ids
cocoEval.params.imgIds = self.img_ids
cocoEval.params.maxDets = list(proposal_nums)
cocoEval.params.iouThrs = iou_thrs

(3) evaluate函数

p = self.params
p.imgIds = list(np.unique(p.imgIds))
p.catIds = list(np.unique(p.catIds))
p.maxDets = sorted(p.maxDets)
#prepare:将gt和dt重新处理为字典。
self._prepare()gts=self.cocoGt.loadAnns(self.cocoGt.getAnnIds(imgIds=p.imgIds))dts=self.cocoDt.loadAnns(self.cocoDt.getAnnIds(imgIds=p.imgIds))self._gts = defaultdict(list)for gt in gts:#(image_id,category_id)作为key,value是一个list,包含了该图该类别下的每一个gtself._gts[gt['image_id'], gt['category_id']].append(gt)dts做相同的处理,得到self._dts

#self.ious是一个字典,key为(imgId,catId),value是一个N*M的array,N是该图该类别的gt_bbox,M是该图该类别的det_bbox,array是gt_bbox和det_bbox的IoU
self.ious = {(imgId, catId): computeIoU(imgId, catId) for imgId in p.imgIds for catId in catIds}
#self.evalImgs生成每张图片每个类别在10个不同的IoU的阈值(0.5-0.95)下的匹配情况。
self.evalImgs = [evaluateImg(imgId, catId, areaRng, maxDet)for catId incatIdsfor areaRng in p.areaRngfor imgId in p.imgIds]def evaluateImg(self, imgId, catId, aRng, maxDet):

self.evalImgs共imagescateroryarea range条,每一条表示当前图像、当前类别、当前目标范围的各个目标的检测结果。

self.evalImgs[0]中的dtMatches:
共10行,每一行表示在当前IoU阈值下,dt box的匹配情况。因为我们总共有10个阈值(array([0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95])),所以结果有10行。
每一行的具体含义,以第一行(1,0,2)为例,表示dt box 1<->gt box1,dt box3<->gt box2。可以参考下面的self._dts和self._gts来理解。
self.evalImgs[0]中的gtMatches:
gtMatches的含义与dtMatches基本一致。
注意:dtIds和gtMatches是针对全部的检测目标而言,而不是针对某张图或某个类别。所以在后面的匹配信息中,dtIds和gtMatches都会很大

(3) accumulate函数

    def accumulate(self, p = None):'''Accumulate per image evaluation results and store the result in self.eval:param p: input params for evaluation:return: None'''print('Accumulating evaluation results...')tic = time.time()if not self.evalImgs:print('Please run evaluate() first')# allows input customized parametersif p is None:p = self.paramsp.catIds = p.catIds if p.useCats == 1 else [-1]T           = len(p.iouThrs)#T=10,iouThrs为array([0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95])R           = len(p.recThrs)# R01,p.recThrs为0-1,0.001为间隔K           = len(p.catIds) if p.useCats else 1#K是类别数,K=4A           = len(p.areaRng)#A=4,p.areaRng[[0, 10000000000.0], [0, 1024], [1024, 9216], [9216, 10000000000.0]]M           = len(p.maxDets)#M=3,maxDets为[100, 300, 1000]precision   = -np.ones((T,R,K,A,M)) # shape为(10,101,4,4,3)-1 for the precision of absent categoriesrecall      = -np.ones((T,K,A,M))#shape为(4,4,3)scores      = -np.ones((T,R,K,A,M))# shape为(10,101,4,4,3)# create dictionary for future indexing_pe = self._paramsEvalcatIds = _pe.catIds if _pe.useCats else [-1]setK = set(catIds)#{0, 1, 2, 3}setA = set(map(tuple, _pe.areaRng))#{(0, 10000000000.0), (1024, 9216), (0, 1024), (9216, 10000000000.0)}setM = set(_pe.maxDets)#{1000, 100, 300}setI = set(_pe.imgIds)#所有的图像# get inds to evaluatek_list = [n for n, k in enumerate(p.catIds)  if k in setK]#[0, 1, 2, 3]m_list = [m for n, m in enumerate(p.maxDets) if m in setM]#[100, 300, 1000]a_list = [n for n, a in enumerate(map(lambda x: tuple(x), p.areaRng)) if a in setA]#[0, 1, 2, 3]i_list = [n for n, i in enumerate(p.imgIds)  if i in setI]I0 = len(_pe.imgIds)#1468A0 = len(_pe.areaRng)#4# retrieve E at each category, area range, and max number of detections#T、R、K、A、M分别代表(IoU的threshold的个数,0.5-0.95共10个),(recall的阈值个数,从0.0-1.0共分了100组),(类别数,每个类别分别统计),(area的个数,目前共all,small,middle,big4个值),(MaxDet的个数,共100,300,1000这3种选项)

输出结果为
precision,shape为T R K A M,以precision[0,0,0,0,0],其含义为(IoU阈值选为0.5时),(只挑选det score大于某个阈值的det_box,使得good_det_box/all_gt_box的值小于0.01,但是大于0.00),(针对某个类别),(针对某个区域大小),(在指定的MaxDet)下的precision,即满足上述条件的det_box/all_det_box. 当R的阈值很小时,我们对recall的要求低,因此我们尽量挑选出质量高的det_box,所以precision大。
scores, shape为T R K A M.以scores[0,0,0,0,0]为例,其含义为(IoU阈值选为0.5时),(只挑选det score大于某个阈值的det_box,使得good_det_box/all_gt_box的值小于0.01,但是大于0.00),(针对某个类别),(针对某个区域大小),(在指定的MaxDet)下的score, 当R的阈值较小时,要求我们选出来高质量的det_box, score的值也比较大。
recall,shape为TKAM,表示recall[0,0,0,0]表示(IoU阈值选为0.5时),(该类别),(该区域大小下),(MaxDet为指定值)时的recall值,即所有的det_box中的good_det_box/all_gt_box
实际使用时:
(1)AP,mAP,或mmAP评估更科学,但是不太直观。针对某一具体问题,我们需要知道某一类别在指定IoU阈值,指定Det_box的分数阈值时,该类别的TP,FP,FN。目前的COCO eval并没有给出这些,需要我们去修改pycocotools/cocoeval.py,保存gt的个数、TP的个数、FP的个数。

gt_all[k,a,m] = npig
tp_all[t,k,a,m] = tp[-1]
fp_all[t,k,a,m] = fp[-1]

修改coco的evaluate函数,保存tp,fp,gt

IoU_pr_p,k_pr_p,area_pr_p,maxdet_pr_p = pr_params
tp_pr_p = cocoEval.eval['tp_all'][IoU_pr_p,k_pr_p,area_pr_p,maxdet_pr_p]
fp_pr_p = cocoEval.eval['fp_all'][IoU_pr_p,k_pr_p,area_pr_p,maxdet_pr_p]
gt_pr_p = cocoEval.eval['gt_all'][k_pr_p,area_pr_p,maxdet_pr_p]
with open(osp.join(out_dir,'tp_fp_fn.csv'),'w') as t_f_file:t_f_file.write(f'tp:{tp_pr_p}  fp:{fp_pr_p}  gt:{gt_pr_p} \r\n')

mmdetection中调用过程

#构造iou_thrs array([0.5 , 0.55, 0.6 , 0.65, 0.7 , 0.75, 0.8 , 0.85, 0.9 , 0.95])
iou_thrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True)

result_files, tmp_dir = self.format_results(results, jsonfile_prefix)
#我们的metrics只有1个,[bbox]
for metric in metrics:#将检测结果转为指定的格式<pycocotools.coco.COCO object at 0x7f464c2c4e10> cocoDt = cocoGt.loadRes(result_files[metric])#cocoGt,cocoDt分别表示gt和检测结果,iou_type为'bbox'cocoEval = COCOeval(cocoGt, cocoDt, iou_type) #cocoEval.params的属性catIds、imgIds(各个图片的image_id)、maxDets(用于计算recall,比如recall@100,recall@300,recall@1000,默认值[100,300,1000])cocoEval.params#cocoEval.evaluate()cocoEval.accumulate()cocoEval.summarize()

coco中PR曲线

https://zhuanlan.zhihu.com/p/60707912

其他的语句就是一些plt.相关的用来画图的语句了。

plt.grid是用来在图中加网格。

plt.legend是用来在图中添加注释。

coco evaluate相关推荐

  1. 关于MLPerf的一些调查

    文章目录 更新 2021-09-27 1. MLPerf 介绍 2. MLPerf 思路 3. MLPerf Training 3.1 Training Division 3.1.1 Closed M ...

  2. map评价吗 voc数据集可以用coco_【庖丁解牛】从零实现RetinaNet(九):使用COCO预训练权重在VOC上训练RetinaNet...

    下列代码均在pytorch1.4版本中测试过,确认正确无误. 如何载入COCO预训练权重 由于其他数据集如VOC的类别数不一定和COCO数据集相同,载入COCO预训练权重后要先去掉和类别有关的卷积层权 ...

  3. coco关键点标注json_COCO 数据集中目标检测标注说明

    此篇文章会不断补充内容,建议长期关注.最后更新日期为2018年11月25日. 需要用到的工具: UltraEdit Git Python ,包含 jupyter notebook,以及其它必要的包 A ...

  4. 目标检测实战篇1——数据集介绍(PASCAL VOC,MS COCO)

    前言   前面我们讲过了目标检测的YOLO系列算法,SSD算法.从这个博文开始,我们要真实开启实战篇章.在正式介绍实战篇之前,我们需要先知道两个数据集:PASCAL VOC和COCO数据集. 一.PA ...

  5. 利用COCO API测试自己数据集训练的YOLOv3模型的mAP(VOC格式数据集)

    目录 工具 前言 生成标注集的json文件 数据集准备 将voc注解格式数据集的注解转换成txt注解格式 自定义数据集的注解转换成coco的注解格式 生成结果集的json文件 安装darknet 获取 ...

  6. 《Microsoft COCO Captions Data Collection and Evaluation Server》论文笔记

    出处:CVPR2015 Motivation 本文描述了MSCoco标题数据集及评估服务器(Microsoft COCO Caption dataset and evaluation server), ...

  7. 修改COCO评价指标 maxDets=[10,15,20]

    默认的COCO评价指标 maxDets=[1,10,100] 该指标的意思是分别保留测试集的每张图上置信度排名第1.前10.前100个预测框,根据这些预测框和真实框进行比对,来计算AP.AR等值(有点 ...

  8. 数据集COCO在目标检测的介绍与使用

    COCO数据集介绍 COCO数据集主页:http://cocodataset.org COCO数据集是大规模的数据集,用于Object Detection + Segmentation + Local ...

  9. Microsoft COCO: Common Objects in Context - 目标检测评估 指标(Detection Evaluation)

    参考博客 coco官网 coco目标检测评估指标 以下12个指标用于描述COCO上的对象检测器的性能: Average Precision (AP): AP % AP at IoU=.50:.05:. ...

最新文章

  1. 回顾与展望:大热的AutoML究竟是什么? | 技术头条
  2. 如何简单形象又有趣地讲解神经网络是什么?(知乎) 说的人很多,理解很充分_kebu12345678的博客-CSDN博客_神经网络知乎
  3. 例5.12 输入一串字符,字符个数不超过100,且以.结束。 (信息学奥赛一本通)...
  4. ubuntu宽带拨号linux,Ubuntu 通过无线进行ADSL拨号
  5. python关闭读写的所有的文件-Python读写txt文本文件的操作方法全解析
  6. 全球及中国EDM放电加工机行业运营盈利前景与渠道分析报告2022版
  7. MySQL 用户创建及设置
  8. different color in Chrome Development Tool
  9. 浅谈 PHP 与手机 APP 开发(API 接口开发) 1
  10. python快速整理excel_python批量处理excel文件数据
  11. awk命令详解+示例
  12. 在低代码中平台记录sortablejs拖拽使用经验
  13. 电子科技大学计算机学院拟录取,2021年电子科技大学硕士研究生拟录取名单
  14. 【coq】函数语言设计 笔记 07 - indProp
  15. Exchange Server 2013 VS 2016
  16. mysql让其他机器访问_mysql设置允许其它机器连接
  17. 「TCG 规范解读」初识基础设施工作组
  18. 【windows10】 解决PPT不能播放视频
  19. bookkeeper命令行操作
  20. Powershell--正则表达式--字符--含义

热门文章

  1. 雷军做程序员时写的博客,很强大~
  2. office2010 excel多个窗口互相独立显示
  3. Git LFS是什么?
  4. Blender图解教程:手把手教你做一个马里奥金币 之 纯建模方法(附模型下载)
  5. 用Python写一个游戏
  6. 奥德装备冲刺深交所:年营收5亿 周定山控制79%股权
  7. 被一只狗改变命运的女孩....
  8. 洛谷P3413 SAC#1 - 萌数【数位DP】
  9. [COCI2017-2018#3] Aron
  10. Linux正确的关机命令