J'ai commencé à utiliser le cocoapi pour évaluer un modèle formé à l'aide du Object Detection API . Après avoir lu diverses sources qui expliquent la précision moyenne moyenne (mAP) et le rappel, je suis confondu avec le paramètre "détections maximales" utilisé dans le cocoapi.
D'après ce que j'ai compris (par exemple ici , ici ou ici ), on calcule mAP en calculant la précision et le rappel pour différents seuils de score de modèle. Cela donne la courbe de rappel de précision et mAP est calculé comme une approximation de l'aire sous cette courbe. Ou, exprimé différemment, comme la moyenne de la précision maximale dans des plages de rappel définies (0: 0,1: 1).
Cependant, le cocoapi semble calculer la précision et le rappel pour un nombre donné de détections maximales (maxDet
) avec les scores les plus élevés. Et à partir de là, obtenez la courbe de rappel de précision pour maxDets = 1, 10, 100
. Pourquoi est-ce une bonne mesure car elle n'est clairement pas la même que la méthode ci-dessus (elle exclut potentiellement les points de données)?
Dans mon exemple, j'ai ~ 3000 objets par image. L'évaluation du résultat à l'aide du cocoapi donne un rappel terrible car elle limite le nombre d'objets détectés à 100.
À des fins de test, j'alimente l'ensemble de données d'évaluation en tant que vérité fondamentale et les objets détectés (avec des scores artificiels). Je m'attendrais à de la précision et je me souviens assez bien, ce qui se passe réellement. Mais dès que j'alimente plus de 100 objets, la précision et le rappel diminuent avec l'augmentation du nombre "d'objets détectés". Même s'ils sont tous "corrects"! Comment cela peut-il avoir un sens?
J'en suis venu à la conclusion que c'est exactement ainsi que le cocoapi définit sa métrique. Cela a probablement du sens dans leur contexte, mais je peux aussi bien définir le mien (ce que j'ai fait), sur la base des articles que j'ai lus et liés ci-dessus.
Vous pouvez modifier le paramètre maxDets
et définir une nouvelle méthode d'instance summarize()
.
Créons un objet 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()
Maintenant, définissez la méthode summarize_2()
dans le module cocoeval.py
De la manière suivante:
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.
Si vous exécutez la méthode ci-dessus sur votre jeu de données, vous obtiendrez une sortie similaire à ceci:
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