Понимание оценки COCO "максимальное количество обнаружений"
Я начал использовать cocoapi для оценки модели, обученной с использованием API обнаружения объектов. После прочтения различных источников, которые объясняют среднюю среднюю точность (mAP) и отзыв, я путаюсь с параметром "максимальные обнаружения", используемым в cocoapi.
Из того, что я понял (например, здесь, здесь или здесь), каждый вычисляет mAP, вычисляя точность и вспоминая для различных пороговых значений модели. Это дает кривую точного возврата, и mAP рассчитывается как приближение к площади под этой кривой. Или, выраженный по-другому, как среднее значение максимальной точности в определенных диапазонах отзыва (0:0,1:1).
Тем не менее, Cocoapi, похоже, рассчитывает точность и отзыв для данного числа максимальных обнаружений (maxDet
) с самыми высокими баллами. И оттуда получить кривую точности-отзыва для maxDets = 1, 10, 100
, Почему это хороший показатель, поскольку он явно не совпадает с описанным выше методом (он потенциально исключает точки данных)?
В моем примере у меня есть ~ 3000 объектов на изображение. Оценка результата с использованием cocoapi дает ужасный отзыв, поскольку ограничивает количество обнаруженных объектов до 100.
В целях тестирования я передаю оценочный набор данных как основную правду и обнаруженные объекты (с некоторыми искусственными оценками). Я хотел бы ожидать точности и вспомнить довольно хорошо, что на самом деле происходит. Но как только я добавляю более 100 объектов, точность и отзыв снижаются с увеличением количества "обнаруженных объектов". Хотя они все "правильные"! Как это имеет смысл?
1 ответ
Я пришел к выводу, что именно так Cocoapi определяет свою метрику. Это, вероятно, имеет смысл в их контексте, но я также могу определить свою собственную (что я и сделал), основываясь на статьях, которые я прочитал и на которые ссылался выше.
Вы можете изменить 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()
Теперь определим summarize_2()
метод в cocoeval.py
модуль следующим образом:
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