Help us understand the problem. What is going on with this article?

【物体検出】mAP ( mean Average Precision ) の算出方法

物体検出の評価指標であるmAPの算出方法を詳しく説明している記事が少なかったのでまとめました.
修論執筆に際してかなり丁寧にまとめたつもりです.
スクリーンショット 2019-11-20 21.12.30.png

mAP(Mean Average Precision), AP(Average Precision)は物体検出の精度を比較するための指標です.

これらを理解するためには,TP(True Positive), FP(False Positive), FN(False Negative), TN(True Negative), Precision, Recallの概念と,物体検出において重要なIoU(Intersection over Union)の概念を知る必要があります.

画像分類と物体検出ではTP,FP,FN,TNの指す意味が異なってきます.

そこで,この記事ではそれらの違いを明確にするために

という流れで説明していきたいと思います.

1. TP, FP, FN, TN, Precision, Recall (ガンの場合)

まず、そもそもこれらの評価指標がどういう経緯で使われてきたのかというお話をします.
TP, FP, FN, TN, Precision, Recallなどの評価指標は従来,ガンの検査結果が実際にガンであるかといった事象を評価するために用いられてきました.
いわゆる陽性,陰性といった概念です.
この場合,検査(予測)結果である陽性はPositive陰性はNegativeを指します.
一方で,陽性や陰性の検査結果が実際に正しければTrue陽性や陰性の検査結果が実際には正しくなければFalseを指します.

ですので,ガンの場合,

  • TP(True Positive): 検査結果はガンで,実際もガンだった.
  • FP(False Positive): 検査結果はガンだったが,実際はガンではなかった.
  • FN(False Negative): 検査結果はガンではなかったが,実際はガンだった.
  • TN(True Negative): 検査結果はガンではなく,実際もガンではなかった.
実際はガン 実際はガンでない
検査結果はガン(陽性) TP FP
検査結果はガンでない(陰性) FN TN

ということになります.

そしてPrecisionとRecallはこれらを用いて以下のように表せます.

Precision =  \frac{TP}{TP + FP}
Recall =  \frac{TP}{TP + FN}

すなわち,

Precision =  \frac{陽性と出た検査結果が実際にガンであった数)}{検査結果の総数}
Recall =  \frac{実際にガンであったもののうち陽性と検査結果が出ていた数}{実際にガンであったものの総数}

となります.

もう少し詳しく見てみましょう.

Precisionは,全ての検査結果(陽性,陰性両方の結果)の内,正しくガンと検査できた割合を表します.
Precisionは一般には,「予測結果の精度」を見るための指標であり、大きな値であるほど予測した結果が確からしいということを表します.

しかしながら,Precisionの評価基準だけでは,「実際にはガンであったのに検査結果がガンでないとして取りこぼした場合」の精度評価を測ることができません.命に関わる致命的なミスですね.この「取りこぼしのなさ」を測る評価基準が欲しいものです.
そこで、この「取りこぼしのなさ」を示す評価基準がRecallというわけです.

Recallは,実際はガンであった全ての結果の内,陽性と正しく検査できた割合を表します.(式では同じTPですが、検査結果を基準に見るか、実際にガンであるかを基準で見るかでPrecisionとRecallでの意味が異なることが分かると思います.)
Recallは一般には,「取りこぼしのなさ」を見るための指標であり、大きな値であるほど取りこぼしの少なさを表すことになります.
蛇足ですが,携帯電話や自動車などに不備があり無料で回収することをリコールと言いますよね.そのリコールは回収という意味で、Recallが表すのは回収率(真値に対する再現率)ということなので、やや意味が異なります.

2. TP, FP, FN, TN, Precision, Recall (画像分類の場合)

画像分類の場合,ガンのときと同じようにTPなどを適用できます.

ここでは「StopSign, TrafficLight, Car」の3クラスの分類を例に取ってみましょう.

StopSignのクラスを対象に評価する場合、

  • TP(True Positive): 予測結果のラベルはStopSignで,正解データのラベルもStopSignだった.
  • FP(False Positive): 予測結果のラベルはStopSignだったが,正解データのラベルはStopSignではなかった.(TrafficLightかCarだった)
  • FN(False Negative): 予測結果のラベルはStopSignではなかったが,正解データのラベルはStopSignだった.
  • TN(True Negative): 予測結果のラベルはStopSignではなく,正解データのラベルもStopSignではなかった.
正解データのラベルがStopSign 正解データのラベルがStopSignでない
予測結果がStopSign TP FP
予測結果がStopSignでない FN TN

そしてPrecisionとRecallはこれらを用いて以下のように表せます.

Precision =  \frac{TP}{TP + FP}
Recall =  \frac{TP}{TP + FN}

すなわち,

Precision =  \frac{正しくStopSignと予測できた数}{予測した総数}
Recall =  \frac{正解データのStopSignラベルのうちStopSignを予測できた数}{正解データのStopSignラベルの総数}

となります.

他のクラス「TrafficLight, Car」についても同様に計算できますね.

3. IoU

「それでは,これを物体検出の例に当てはめてみましょう」と言いたいところなのですが,
その前にIoU(Intersection over Union)と呼ばれる概念を説明する必要があります.

ところで、物体検出と画像分類の根本的な違いはなんだと思いますか?
それは「クラスの分類すること」に加えて「物体の領域を検出すること」です.

物体検出の評価指標では、画像分類のときとは異なり「物体の領域を検出すること」を含めて評価する必要があり、物体の領域を予測した際の正しさを計算する上で使われる概念がIoUなのです.

iou_equation.png

IoUとはIntersection over Unionという名前の通り,2つの領域を見て,その「領域の積:Intersection」「領域の和:Union」「割る:over」することです.

これにより,「2つの領域がどれだけ重なっているのか[0,1]の値で見る」ことができます.
これについては少し先で詳しく説明します.

iou_stop_sign.jpg

物体検出ではBouding Boxと呼ばれる矩形状の境界線で物体を検出しますが,IoUを使うことで,
このBounding Boxが「予測されたもの:Predicted Bouding Box」「真値:Ground-truth Bounding Box」の2つのBounding Boxの間でどれくらいの違いがあるのかを数値として表すことができます.

IoUの数値は0~1の間の数値を取ります.
この数値が何を表しているかと言うと,

  • IoU = 0  ⇨   2つのBounding Boxが全く重なっていない
  • IoU = 1  ⇨   2つのBounding Boxが完全に重なっている

ということです.
もちろん完全に重なるケースは稀で,[0,1]のIoUの値によって重なりは以下の図のように変化します.

iou_examples.png

4. TP, FP, FN, TN, Precision, Recall (物体検出の場合)

ではこのIoUを用いて物体検出のTP, FP, FN, TN, Precision, Recallを算出していきます.

例として,

Label = ["StopSign", "TrafficLight", "Car"]

の3つの物体のクラスラベルを検出するモデルを扱いましょう.

その3つのLabelの内,まず"StopSign"について考えることにします.
ある物体検出モデルを用いて以下の表に示す結果が得られたとします.

表1."StopSign"と予測されたPredicted BBoxの検出結果(TP,FP)

Sorted Number Confidence Score(%) Correct?
#1 96 True
#2 92 True
#3 89 False
#4 88 False
#5 84 False
#6 83 True
#7 80 True
#8 78 False
#9 74 False
#10 72 True

こちらの表は,ある物体検出モデルが"StopSign"と検出した結果で,
信頼度スコア:Confidence Score順にソートしたものです.
(※信頼度スコアを簡潔に言うと,そのBounding Boxがどれくらい物体を含んでいるのかを表すスコアです.詳しくはこちらの記事を参照してください.)

ここでCorrect?の列は,
10個全てのPredicted Bounding Boxの内,IoU ≥ 0.5 であるものはTrue,それ以外はFalseと示しています.
このTrueと示しているものがTPに当たり,Falseと示しているものがFPに当たります.

TP, FPだけでなく,
ここで,物体検出の場合のTP, FP, FN, TN全てをまとめると,

  • TP: Predicted Bounding BoxとGround-truth Bounding Boxが十分に重なっている                 ※ほぼ同じ位置にある(IoU ≥ 0.5)
  • FP: Predicted Bounding Boxに対してGround-truth Bounding Boxが十分に重なっていない(予測基準)                 ※外れた位置にある(IoU < 0.5)
  • FN: Ground-truth Bounding Boxに対してPredicted Bounding Boxが十分に重なっていない(正解基準)                 ※外れた位置にある(IoU < 0.5)
  • TN: TPと同値なので考えない
IoU ≥ 0.5 IoU < 0.5
Predicted BBoxに対してGround-truth BBoxが TP FP
Ground-truth BBoxに対してPredicted BBoxが - FN

少々特殊ですが上記のようになります.

そしてPrecisionとRecallは以下で表せます.

Precision =  \frac{TP}{TP + FP}
Recall =  \frac{TP}{TP + FN}

そしてこれはすなわち,

Precision =  \frac{正しく(IoU ≥ 0.5)で検出できた数}{全てのPredicted BBoxの数}
Recall =  \frac{正しく(IoU ≥ 0.5)で検出できた数}{全てのGT BBoxの数}

少し詳しく見ると,ここでは,

Precisionは,全ての予測結果(IoUに限らず全てのPredicted BBox)の内,正しくIoUが0.5以上で予測できた割合を表します.

Recallは,実際の正解結果(GT BBox)の内,IoUが0.5以上で正解結果とほぼ近しい位置のBBoxを予測できた割合を表します.

例を用いてPrecisionとRecallの計算例を示します.
この表2の例ではGT BBoxの数=5個だとして,
Sorted Numberが3番目の計算を例にとります.

表2."StopSign"と予測されたPredicted BBoxの検出結果(Precision,Recall)

Sorted Number Confidence Score(%) Correct? Precision Recall
#1 96 True 1/1 = 1 1/5 = 0.2
#2 92 True 2/2 = 1 2/5 = 0.4
#3 89 False 2/3 = 0.667 2/5 = 0.4
#4 88 False 2/4 = 0.5 2/5 = 0.4
#5 84 False 2/5 = 0.4 2/5 = 0.4
#6 83 True 3/6 = 0.5 3/5 = 0.6
#7 80 True 4/7 = 0.571 4/5 = 0.8
#8 78 False 4/8 = 0.5 4/5 = 0.8
#9 74 False 4/9 = 0.444 4/5 = 0.8
#10 72 True 5/10 = 0.5 5/5 = 1.0

このときこのソートされたBBox列の3番目におけるPrecisionは

Precision =  \frac{それまで見てきたTrueの数}{それまで見てきたPredicted BBoxの総数} = 2/3 = 0.667

また,このソートされたBBox列の3番目におけるRecallは

Recall =  \frac{それまで見てきたTrueの数}{全てのGT BBoxの数} = 2/5 = 0.4

のように計算できます.

5. AP, mAP

最後に,先ほど求めた物体検出のPrecisionとRecallを用いて,APとmAPを計算していきます.

APを出すために,表2の結果のRecallを横軸,Precisionを縦軸にとり,グラフを描きます.
1_VenTq4IgxjmIpOXWdFb-jg.png

APは一般的に,

AP = \int_0^1 p(r) dr

のように積分を用いて表せます.
ここで,$p$はPrecisionの変数,$r$はRecallの変数です.

1_zqTL1KW1gwzion9jY8SjHA.png

積分を行うために,上図のようにジグザグなパターンを滑らかにします.
具体的には,下図のように,各Recallのレベルで横に見た時に,Precisionの値が最大の値に置き換えます.

1_pmSxeb4EfdGnzT6Xa68GEQ.jpeg

ここで原理的には通常の積分を行うのですが,
プログラム上で積分を行う際には,全ての点を扱うわけにはいかないので
この例のケースでは11点の代表点を取り,

1_naz02wO-XMywlwAdFzF-GA.jpeg

APを求めるための積分として以下の計算を行います.

AP = \frac{1}{11}*(p(0) + p(0.1) + ・・・ + p(1.0)) 
AP = \frac{1}{11}*(1.0 * 5 + 0.571 * 4 + 0.5 * 2) = \frac{1}{11}*8.284 = 0.753 

この手法は,物体検出のタスクの分野で有名なデータセットであるPASCAL VOCデータセットのAP算出でも用いられているものです.
これにより,"StopSign"のAP=0.753を得ることができました.

同様の方法で,Label = ["StopSign", "TrafficLight", "Car"]の3つ全てのクラスラベルのAPを以下のように算出できたとしましょう.

AP_{StopSign} = 0.753
AP_{TrafficLight} = 0.990 
AP_{Car} = 0.683

この時のmAPは全てのクラスラベルのAPの平均を取れば良いので,

mAP = \frac{1}{3} * (0.753 + 0.990 + 0.683) = 0.8086

となり,最終的にこのモデルの$mAP=0.8086$(80.86%)という結果が得られました.(※論文などでは%表記で表示することが多いです.)

Mean Average Precisionの文字通り,APを全てのクラスについてさらに平均したものという訳ですね.

今回はIoU ≥ 0.5として説明を行いましたが,mAPを算出する際のこのIoUの閾値はもちろん任意に選択できます.
1_09w7--mzDQ3Nqd81t-XOjw.png

よく論文の表などで出てくる$AP_{50}$や$AP_{75}$などは実はmAPを計算する際のIoUの閾値を表しています.
IoUの閾値を上げるとその分TPの判定がシビアになるので,AP,mAPはその分低下する傾向にあることを覚えておいてください.

mAP評価プログラムの実装

実際に物体検出モデルでmAPを出したい場合はrafaelpadillaさんのGithubリポジトリを使います.
このリポジトリのプログラムは物体検出モデルの予測結果と正解データがあれば各AP値やRecall-Precisionのグラフも出力してくれるのでオススメです.

ただし「①物体検出モデルの予測結果を表す所定フォーマットのテキストファイル」と「②正解データを表す所定フォーマットのテキストファイル」が必要となります.

②についてはrafaelpadillaさんのGithubリポジトリで提供してあります.
しかし①については自分で実装して出力する必要があります.

①については私の方でAPIを作成し、私のgithubリポジトリに公開しました!

皆さんも私のgithubリポジトリで画像ごとのテキストファイルを吐き出した後、その結果をrafaelpadillaさんのGithubリポジトリで使用してmAPを計算することができますので、ご自身で物体検出モデルの精度を確かめて見てください.


これにて物体検出におけるmAPの算出方法についての説明を終わります.
間違いやご指摘などありましたら,コメント欄にて教えていただけるとうれしいです.

P.S.

機械学習,画像処理,自動運転などをゆるーく発信しているのでQiitaと twitter
フォローお待ちしています!お仕事の依頼はTwitterのDMからお願いします.

参考文献

mdo4nt6n
副業OKの某大手企業/東大院/ 東京大学制作展2018 "Dest-logy" REBUILD -The world line-(http://bit.ly/2FUKmoF)/ 未踏IT2018クリエイター/ 機械学習(センサ活用/物体検出)
https://github.com/Ryo-Kawanami
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした