cocoapi を使用して Object Detection API を使用してトレーニングされたモデルを評価し始めました。平均平均精度(mAP)と再現率を説明するさまざまなソースを読んだ後、cocoapiで使用されている「最大検出」パラメーターと混同しています。
私が理解したこと(たとえば、 ここ 、 ここ または ここ ))から、さまざまなモデルスコアのしきい値の精度と再現率を計算してmAPを計算します。これにより、精度-再現率曲線が得られ、mAPはこの曲線の下の面積の近似値として計算されます。または、定義された再現範囲(0:0.1:1)の最大精度の平均として別の表現をします。
ただし、cocoapiは、特定の数の最大検出(maxDet
)の精度が高く、スコアが最も高いリコールを計算しているようです。そして、そこからmaxDets = 1, 10, 100
の精度再現曲線を取得します。明らかに上記の方法と同じではない(データポイントを除外する可能性がある)ため、これはなぜ良い指標なのですか?
私の例では、画像ごとに約3000個のオブジェクトがあります。 cocoapiを使用して結果を評価すると、検出されたオブジェクトの数が100に制限されるため、ひどい再現率が得られます。
テストの目的で、評価データセットをグラウンドトゥルースおよび検出されたオブジェクト(人工スコア付き)としてフィードします。私は正確さを期待し、実際に起こっているかなり良い思い出します。しかし、100を超えるオブジェクトをフィードすると、「検出されたオブジェクト」の数が増えるにつれて、精度と再現率が低下します。それらはすべて「正しい」にもかかわらず!それはどういう意味ですか?
私は結論に達しました、これは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
_