mAP(mean Average Precision)を手っ取り早く上げるには
はじめに
signateの物体認識コンペ(魚群検知)に参加したので、そのときに得た知見をいくつか共有したいと思います。(複数記事に分ける予定)
新記事公開しました。(21.02.11)
結論
先に結論を言ってしまうと、mAPを上げるには、推論時のconfidenceスコアのフィルターの値を小さくして大量に予測値を出すことです。
このコンペでは、1枚1クラス20まで予測を提出できたので、その上限まで予測値を出すのが良いです。
理由
お恥ずかしながらmAPの計算方法をきちんと把握してなかったのですが、計算式を追えば自明のことでした。
mAPの算出方法
わかりやすいQiita記事 qiita.com
Qiita記事の元記事 jonathan-hui.medium.com
物体認識の場合、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の値が最大の値に置き換えます。
そして、離散値なので、複数の点をサンプリングして積分計算します。 例として、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を回避できるという訳です。