用商汤的mmdetection 学习目标检测中的 Recalls, Precisions, AP, mAP 算法 Part1
學習目標檢測一定少不了的評測方式, 就是透過recalls, precisions, 來計算出類別的AP, 以及最后所有AP的平均值 mAP(mean Average Precision) 也就是我們最關心的數值
這邊先簡單的了解一下confusion matrix, 也就是所謂的混肴矩陣, 我個人不覺得這是一個很好的翻譯, 最好記得英文就行, 在分類任務中這是一個非常重要的評測指標
下圖是一個基本的confusion matrix
下面我直接帶入例子會比較好解釋
假設你的數據集一共是2分類, 第一類是人, 第二類是汽車
而測試集只有兩張圖片
Actual Value and Predicted Value
Actual value :實際的值, 在目標檢測領域中, 我們可以理解為ground truth, 就是人或者是汽車在圖片上的真實坐標
predicted value:這個就很好理解了, 就是指我們模型預測出來的坐標
pos 和 neg 這邊不先定義, 我講下去你就知道了
TP FP FN TN
這里通常很容易被弄混, 難怪叫做混肴矩陣, 跟著我的步伐走就沒問題,強烈建議拿出紙筆把矩陣畫一次就清楚了
- TP (TruePositive): 正確預測出類別的 (正確識別為人或是汽車)
- FP (FalsePositive):錯誤預測類別的 (人當成汽車)
- FN(FalseNegative): ground truth中沒有被檢測到的
- TN(TrueNegative):理論上來講就是檢測出不是這個類別的數量, 但是并不適用在目標檢測領域, 因為通常一張圖后會有非常多的bbox是沒有檢測到groundtruth的, 所以這無法計算, 并不影響, 因為也用不上
Recalls and Precisions
Recalls
可以叫做查全率又或者是召回率, 可以當做是所有類別x中預測為正確的
也就是 TPTP+FN\frac{TP}{TP+FN}TP+FNTP? , 對應圖片的藍框公式很直觀, 就是所有的ground truth(所有測試集中的樣本每張圖片上的人 或者 汽車的總數)里面檢測出人 或者 汽車的數量
比如圖中有5個標注為汽車的ground truth, 那么你檢測到的汽車有兩個, 那么對于這張圖, 汽車類的 recalls 就是 2/5
Precisions
可以叫做精準率, 就是你檢測到結果里面, 實際上真的正確的為多少?TPTP+FP\frac{TP}{TP+FP}TP+FPTP?
TP就是檢測正確的, FP就是檢測錯誤的, 那么加起來不就是你所有檢測的結果? 對應圖中紅框
比如圖中有3個人的ground truth, 你檢測到的也是三個框, 但是其中只有一個框檢測吻合到你的ground truth,另外兩個檢測成人了, TP = 1, FP = 2, 那么precision 就是 1/3
到這邊如果沒明白就先理清楚在往下看吧
首先來用mmdetection 的檢測代碼mean_ap.py來說明會更清晰
我不打算放出全部代碼, 這樣太亂了 我們看最主要的部分加深印象就行 !
首先看到eval_map這個函數, 看名字就很直觀 evaluation mAP
def eval_map(det_results,gt_bboxes,gt_labels,gt_ignore=None,scale_ranges=None,iou_thr=0.5,dataset=None,print_summary=True):說幾個重要的參數就好
也就是說如果要檢測出recall precision mAP這些指標, 就要以上這些重要的值
那么計算recall precision 之前 我們就得先算出 TP FP FN 這些重要的指標, 所有一開始的矩陣是不是很重要?
函數tpfp_default 就是負責計算出TP FP的
我們需要以下參數, 注意該函數是針對單張圖像的
我們的訓練集只有兩張
如果人label = 1, 汽車label=2, 下面直接用vector表示
搬出ground truth
ground truth 最后面的#1 or #2表示label
#groubd gt_bbox1 = np.array([[358, 288, 498, 387], #1[356, 425, 525, 570], #1[377, 119, 478, 189], #2[180, 68, 314, 142], #1[417, 159, 575, 240]], dtype=np.float32)#1gt_bbox2 = np.array([[258, 188, 398, 287], #2[256, 325, 425, 470], #2[277, 19, 378, 89], #1[280, 168, 414, 242]], dtype=np.float32)#2然后我們檢測到的結果是下面這樣, 都是bbox的坐標值, 一共兩張圖片, 圖上都會有每個檢測到的類別的坐標
檢測到的結果 det_results
'''det_results 圖片 _ 類別''' det_results1_1 = np.array([[359, 289, 499, 388], [346, 415, 515, 560], [367, 109, 468, 179], [190, 78, 324, 152], [430, 172, 588, 253]], dtype=np.float32)det_results1_2 = np.array([[259, 189, 399, 288],[236, 315, 415, 440], [267, 9, 368, 79],[290, 178, 424, 252]], dtype=np.float32) det_results2_1 = np.array([[359, 289, 499, 388], [346, 415, 515, 560], [367, 109, 468, 179], [190, 78, 324, 152],[430, 172, 588, 253], [230, 72, 388, 53]], dtype=np.float32)det_results2_2 = np.array([[259, 189, 399, 288], [236, 315, 415, 440], [267, 9, 368, 79], [290, 178, 424, 252],[159, 89, 299, 188]], dtype=np.float32) #not ok可以看出det_result1_1 表示第一張圖的label 1 檢測到的框
那么det_result2_2 就表示第二張圖檢測到label 2的框
所以可以總結
label1 一共檢測出11個(TP+FP)
label2 一共檢測出 9 個 (TP+FP)
好了, 回到tpfp_default
為了要檢查出模型檢測的是不是正確的, 也就是TP, 我們就用到了iou_thr這個閾值
一般會是0.5, 那么還要計算出IOU(交并比), 什么是IOU請直走左轉找到人就問, 如果連這都寫, 篇幅會太長
透過以下的函數進行計算
ious = bbox_overlaps(det_bboxes, gt_bboxes)得出來的ious會長這樣子
#這是label 1的第一張圖檢測與gt的ious結果[[0.9665272 0. 0. 0. ][0. 0.7804878 0. 0. ][0. 0. 0. 0.05691057][0. 0. 0.6701031 0. ][0. 0. 0. 0.6295463 ]]#這是label1 的第二張圖檢測與gt的結果[[0. ][0. ][0. ][0.03430409][0. ][0. ]] #這是label 2的第一張圖檢測與gt的ious結果[[0.00107885][0. ][0. ][0.03430409]]#這是label 2的第二張圖檢測與gt的ious結果[[0.9665272 0. 0.36517328][0. 0.6413269 0. ][0. 0. 0. ][0.41336057 0. 0.6701031 ][0.00149158 0. 0.01764335]]一臉懵?
沒事的, 我剛看到也是懵
label1 圖1 檢測到的不是五個bbox嗎 那么拿去和gt計算 就會有五個分數了
那圖2 檢測到的6個bbox 也當然就有6個分數了
不要太注意shape不同, 只要注意分數就好
很明顯的模型在檢測 label1 的時候, 在圖1的表現好很多 !我們發現到
[0. 0. 0. 0.05691057] 這行分數很低接近于0,因為圖1的label是[1, 1, 2, 1, 1]
在第三個值是label 2, 所以算出來的IOU幾乎為0, 因為并不屬于label1的
在來看到label2 的iou
#這是label 2的第一張圖檢測與gt的ious結果[[0.00107885][0. ][0. ][0.03430409]]分數基本都趨近于0, 就表示模型在圖1 完全沒找到什么都沒檢測到
你可以比較一下det_result1_2的坐標和gt_bbox1的坐標就很清楚了, 坐標完全沒重合的感覺
如此一來我們就有了label1 和 label2 所有檢測到的框和ground truth的 IOU值了
得到了IOU在透過一開始給的iou_thr 閾值, 不就能篩選出誰是TP 誰是 FP了嗎?
來, 咱們在復習一次 , 跟著我大聲念!
檢測大于閾值的叫做TP(TruePositive)
低于閾值的也就是錯誤的叫做FP (FalsePositive)
喝口水繼續
我們將剛剛的ious 進行整理
輸出會是下面這個樣子, 是不是, 說shape先別在意的 !反正都會變這個樣子
ious_max [0.9665272 0.7804878 0.05691057 0.6701031 0.6295463 ]
ious_argmax [0 1 3 2 3]
接下來就是透過閾值篩選, 過程代碼比較多, 不全寫出來
if ious_max[i] >= iou_thr:matched_gt = ious_argmax[i]tpfp_default函數輸出就會是像這樣
tp: [[1. 1. 0. 1. 1.]]
fp: [[0. 0. 1. 0. 0.]]
是不是一目了然? 也能夠對應到分數?iou高說明檢測正確并且歸納在TP 用1表示
而分數低的自然就是FP了 用0表示
拿到了TP FP 就離我們的recalls 和 precisions 不遠了啊 !
好了 這只是上半場
由于篇幅的關系 我臨時決定分成兩章來寫完
說老實話, 這要是一篇文章能解決我也是佩服佩服
總結
以上是生活随笔為你收集整理的用商汤的mmdetection 学习目标检测中的 Recalls, Precisions, AP, mAP 算法 Part1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 游戏建模师自学3D建模有哪些教材?自学难
- 下一篇: c语言投票系统程序,C语言智能投票系统.