クラウドエンジニアのノート

情報技術系全般,自分用メモを公開してます。

mAP(mean Average Precision)を手っ取り早く上げるには

はじめに

signateの物体認識コンペ(魚群検知)に参加したので、そのときに得た知見をいくつか共有したいと思います。(複数記事に分ける予定)

signate.jp

新記事公開しました。(21.02.11)

tmyoda.hatenablog.com

結論

先に結論を言ってしまうと、mAPを上げるには、推論時のconfidenceスコアのフィルターの値を小さくして大量に予測値を出すことです。
このコンペでは、1枚1クラス20まで予測を提出できたので、その上限まで予測値を出すのが良いです。

理由

お恥ずかしながらmAPの計算方法をきちんと把握してなかったのですが、計算式を追えば自明のことでした。

mAPの算出方法

物体認識の場合、TN(True Negative)は特に考えません。また、PrecisionとRecallの算出方法も少し違います。

mAPなので名前の通り、AP(Average Precision)の平均です。クラスごとにAPを計算してその平均がmAPになります。

APの算出方法

クラスごとにAPを算出します。 まず、この記事の通り、APはprecision-recall曲線の下側の面積です。

precisionとrecallの算出方法は、通常のクラス分類と同じです。

  • Precisionの算出方法

$$ Precision = \frac{正しく予測できた数}{予測の数} $$

  • Recallの算出方法

$$ Recall = \frac{正しく予測できた数}{すべての正解の数} $$

物体検出の場合は、予測1つ1つに対してこのprecisionとrecallを算出し、recall値0から1まででprecisionを積分します。

りんごが3つ写っている画像に対する予測が以下の7つだったとします。

このときの、りんごクラスのAPを求めてみます。ここでCorrect?とは、iouしきい値を満たし正解ラベルと予測ラベルが一致している場合はTrue、それ以外はFalseです。

Confidence score (Sorted) Correct? Precision Recall
0.99 True 1/1 (1.0) 1/3 (0.3)
0.97 False 1/2 (0.5) 1/3 (0.3)
0.84 False 1/3 (0.3) 1/3 (0.3)
0.74 True 2/4 (0.5) 2/3 (0.7)
0.32 False 2/5 (0.4) 2/3 (0.7)
0.21 False 2/6 (0.3) 2/3 (0.7)
0.01 True 3/7 (0.4) 3/3 (1.0)

次にrecall値0から1までで積分を行います。グラフを滑らかにするために、各Recallの値で横に見た時に、Precisionの値が最大の値に置き換えます。

f:id:tontainoti:20210210002654p:plain
りんごAP

そして、離散値なので、複数の点をサンプリングして積分計算します。 例として、recallを0.1刻みずつ(0.0, 0.1, 0.2, ..., 1.0)の合計11点で計算する場合は、以下の式になります。(COCOの場合は101点で補間するらしい) $$ AP = \frac{1}{11} \times (1.0 + 1.0 + 1.0 + 1.0 + 0.5 + 0.5 + 0.5 + \frac{3}{7} + \frac{3}{7} + \frac{3}{7} + \frac{3}{7}) = 0.655... $$

あとは、クラスごとのAPの平均を取ればmAPが算出できます。
また、COCOやPascal VOCでもmAPの算出方法は若干異なるようです。

mAPを上げるには

もう一度言いますが、予測を増やせばAPが上がるのでmAPも上がります。

上の例のように、たとえconfidence scoreが0.01でも、それが正解ならば、APは上がるのは見ての通りだと思います。

もう少し深く考えてみると、すべて正解数しないとrecall 1のときのprecisionが0になります。 recallが低いところしかprecisionの値がなくて、recallが高くなるとprecisionが0に近くなり、積分計算で大きくロスします。 つまり、とにかく予測しまくって、低confidenceスコアでも正解bboxを予測してたら、高recallでの低precisionを回避できるという訳です。