【问题标题】:Understanding COCO evaluation "maximum detections"了解COCO评估“最大检测数”
【发布时间】:2019-03-21 05:13:05
【问题描述】:

我开始使用cocoapi 来评估使用Object Detection API 训练的模型。 在阅读了各种解释平均精度 (mAP) 和召回率的资料后,我对 cocoapi 中使用的“最大检测数”参数感到困惑。

据我了解(例如hereherehere),通过计算各种模型得分阈值的精度和召回率来计算 mAP。这给出了精确召回曲线,mAP 被计算为该曲线下面积的近似值。或者,以不同的方式表示为定义的召回范围内的最大精度的平均值 (0:0.1:1)。

但是,cocoapi 似乎会计算给定数量的最大检测 (maxDet) 的精度和召回率,并获得最高分。从那里得到maxDets = 1, 10, 100 的精确召回曲线。为什么这是一个很好的指标,因为它显然与上述方法不同(它可能排除数据点)?

在我的示例中,每张图像有大约 3000 个对象。使用 cocoapi 评估结果会产生可怕的召回率,因为它将检测到的对象的数量限制为 100。

出于测试目的,我将评估数据集作为基本事实和检测到的对象(带有一些人工分数)提供。我希望精确度和召回率非常好,这实际上正在发生。但是,一旦我输入超过 100 个对象,精度和召回率就会随着“检测到的对象”数量的增加而下降。尽管他们都是“正确的”!这有什么意义?

【问题讨论】:

    标签: tensorflow object-detection-api mscoco


    【解决方案1】:

    我得出的结论是,这正是 cocoapi 定义其指标的方式。这在他们的上下文中可能是有道理的,但我也可以根据我在上面阅读和链接的文章来定义我自己的(这就是我所做的)。

    【讨论】:

      【解决方案2】:

      您可以更改maxDets 参数并定义一个新的summarize() 实例方法。

      让我们创建一个COCOeval 对象:

      cocoEval = COCOeval(cocoGt,cocoDt,annType)
      cocoEval.params.maxDets = [200]
      cocoEval.params.imgIds  = imgIdsDt
      cocoEval.evaluate()
      cocoEval.accumulate()
      cocoEval.summarize_2() # instead of calling cocoEval.summarize()
      

      现在,在cocoeval.py 模块中定义summarize_2() 方法如下:

      def summarize_2(self):
          # Copy everything from `summarize` method here except
          # the function `_summarizeDets()`.
          def _summarizeDets():
              stats = np.zeros((12,))
              stats[0] = _summarize(1, maxDets=self.params.maxDets[0])
              stats[1] = _summarize(1, iouThr=.5, maxDets=self.params.maxDets[0])
              stats[2] = _summarize(1, iouThr=.75, maxDets=self.params.maxDets[0])
              stats[3] = _summarize(1, areaRng='small', maxDets=self.params.maxDets[0])
              stats[4] = _summarize(1, areaRng='medium', maxDets=self.params.maxDets[0])
              stats[5] = _summarize(1, areaRng='large', maxDets=self.params.maxDets[0])
              stats[6] = _summarize(0, maxDets=self.params.maxDets[0])
              stats[9] = _summarize(0, areaRng='small', maxDets=self.params.maxDets[0])
              stats[10] = _summarize(0, areaRng='medium', maxDets=self.params.maxDets[0])
              stats[11] = _summarize(0, areaRng='large', maxDets=self.params.maxDets[0])
              return stats
          # Copy other things which are left from `summarize()` here.
      

      如果你在你的数据集上运行上述方法,你会得到类似这样的输出:

       Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=200 ] = 0.507
       Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets=200 ] = 0.699
       Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets=200 ] = 0.575
       Average Precision  (AP) @[ IoU=0.50:0.95 | area= small | maxDets=200 ] = 0.586
       Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=200 ] = 0.519
       Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets=200 ] = 0.501
       Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets=200 ] = 0.598
       Average Recall     (AR) @[ IoU=0.50:0.95 | area= small | maxDets=200 ] = 0.640
       Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=200 ] = 0.566
       Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets=200 ] = 0.564
      

      【讨论】:

        猜你喜欢
        • 2020-04-05
        • 2020-08-23
        • 1970-01-01
        • 2018-03-19
        • 2022-01-24
        • 2020-03-27
        • 2018-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多