1、前言
在目标檢測中我們常常使用AP(Average Precision)作為模型對某種目标精測精度的評價名額,該如何計算AP呢?
AP就是P—R曲線下的面積,我們需要做的就是根據不同的置信度門檻值(p_threshold),計算出這模型得到的預測框的(R,P),然後作出P—R曲線,并求解面積,就能得到目标檢測模型對該檢測種類的AP。(在VOC2010之後,計算AP需要對做出來的P—R曲線做一個平滑,之後會提到)
和分類模型計算P(精确度)R(召回度)不一樣的是(分類模型計算P,R可以參看我這篇博文AUC、精确率和召回率),在目标檢測中我們是沒法知道我們模型出來的預測框的真實值是什麼的(甚至标記的真實框的個數和預測框的個數都是不比對的),該怎樣計算P和R呢?其實計算P,R最重要的名額隻有3個,分别是:
TP | 真實值為正——>預測值為正 |
FP | 真實值為負——>預測值為正 |
FN | 真實值為正——>預測值為負 |
是以在目标檢測中我們隻需要計算出以上三個名額就可以了。
2、例子
我們直接用例子來進行解釋,假設我們有5個GT(Ground_Truth就是目标檢測中人工标注的對象的矩形框,可以認為是真實物體的标簽,下面用BB1—BB5來表示),我們模型對該種識别種類傳回了10個預測框,接下來我們計算該種類的AP:
1、根據預測框計算與5個GT的IOU,如果IOU大于iou_threshold(IOU門檻值,不要和前面的p_threshold弄混了)則标記為1,否則标記為0。比如我們預測出來10個框,根據iou_threshold可以得到這些框的IOU結果分别為(1,0,1,0,1,1,1,0,0,1),還有這些框的置信度分别為[0.9,0.85,0.7,0.6,0.45,0.25,0.2,0.15,0.13,0.12](需要對框從小到大排序),并且我們還知道這些預測框和哪一個GT在做IOU,[BB1,BB2,BB1,BB2,BB3,BB4,BB3,BB1,BB4,BB5],如果做一個表來表示結果應該如下圖:
編号 | GT | 置信度 | IOU結果 |
1 | BB1 | 0.9 | |
2 | BB2 | 0.85 | |
3 | 0.7 | ||
4 | 0.6 | ||
5 | BB3 | 0.45 | |
6 | BB4 | 0.25 | |
7 | 0.2 | ||
8 | 0.15 | ||
9 | 0.13 | ||
10 | BB5 | 0.12 |
2、要注意雖然預測出來有10個框,但是我們實際上隻有5個GT(也就是隻有5個物體),換句話說其實你預測的10個框裡可能有對同一個GT的重複預測(可能有幾個預測框都和同一個GT滿足IOU>iou_threshold,比如1号框和3号框都是同時對BB1的預測)。
3、接下來我們就是需要根據不同的p_threshold(置信度門檻值),計算出這10個預測框的(R,P)點,然後作出P——R曲線,并求解面積。問題就在于如何求對應p_threshold下的P和R,下面我以p_threshold=0.6為例,計算上面表格中10個框的(R,P)具體做法。
- 由于編号1,2,3,4的預測框的置信度都大于等于p_threshold,是以我同意他們的IOU結果(即認為編号1預測框的标簽是BB1的準确框,編号2不是BB2的準确框,編号3也是BB1的準确框,編号4不是BB2的準确框),并且我認為前面四個框(編号1-4)都預測為正例。
- 其餘的預測框我都不認同他們的IOU結果(即我不認為編号5的預測框是BB3的準确框,我也不認為編号8不是BB1的準确框),并且我仍然把剩下的6個框都預測為負例。
- 由上面兩種看法,我們就可以得到當p_threshold=0.6時:這樣我們就可以算出P=TP/(TP+FP),R=TP/(TP+FN)
- TP = 1(隻有編号1是正确預測,編号3雖然也是正确預測但是屬于重複預測了歸納到FP中,誰讓它置信度小呢)
- FP = 3(因為編号2的IOU結果表示它為負類,但是我預測為正類,是以編号2是FP,同理編号4也是。編号3是認為重複預測了,因為編号1已經正确預測了BB1)
- FN = 4(這個名額可以直接由GT個數-TP個數得到,因為你可以了解為真實的有5個正例,但是你隻預測對了1個(TP=1),是以剩下的框都預測錯了,是以FN=GT-TP)
上面的例子說完其實可能有疑問說為什麼不取分析編号5-10的框呢?置信度小于我設定的門檻值p_threshold,我沒有辦法認同他們的IOU結果是以我不知道他們的IOU結果是對的還是錯的,是以我們并不能也沒有必要去分析他們。(因為我們并不在意TN是多少)
另一個疑問是,為什麼你要把置信度大于p_threshold的框都預測為正例,其餘的是負例,難道不是應該尊重IOU結果麼?我的想法是模型既然輸出的這些預測框,那麼肯定是模型認為這些預測框都是目标框,但是置信度小于了我設定的p_threshold自然是應該認為模型識别為負例了。
其實,以上的看法都是我我自己根據網上博文得到的結果的了解,并且計算之後發現這一套邏輯是符合最後結果的,為了友善大家及以和自己去了解這個名額。
3、AP的計算
通過上面的例子,我們知道不同的p_threshold可以計算得出不同的(R,P),由這些點可以畫出圖像(這個圖像就是P—R圖像),我們可以知道P會随着R上升而下降,根據VOC2010的計算公式,我們需要對P—R曲線做一個平滑,具體的方式很簡單。就是每一個點的R1所對應的P1調整為$P1 = \max\limits_{R>R1}P(R)$。用圖像來表示就是從圖一平滑成圖二。

圖一
圖二
根據平滑後的P—R圖像的結果我們就可以很輕松的計算面積了(其實就是矩形求面積)。
4、mAP的計算
對于mAP(mean of Average Precision)的計算,其實就是在目标檢測中我們可能是在檢測多個目标,是以我們對每種類型的目标都可以計算出這個種類的AP,最後再對各個種類進行求平均就可以了。
5、代碼及解釋
根據上面的分析我們可以知道,對我們在對P-R曲線做光滑的時候其實就是在保證P随着R的增加應該是單調不增的函數,如何得到呢?我們可以對precision清單(根據recall從小到大對應排序)采用從末尾到首端不斷取最大值就可以了。(也就是代碼的第x行—第x行)
其實我們還可以發現,我們并不需要對所有的p_threshold從0到1的所有取值去得到(R,P)點,因為隻有當p_threshold大于某個框的置信度的時候,P和R才會改變,是以我們算(R,P)點隻需要計算p_threshold等于各個框的置信度的時候就可以了。(并且我們會發現随着p_threshold的增加,racall是一定增加的。)