Soft(er)-NMS:非极大值抑制算法的两个改进算法
論文連接:
- Soft-NMS – Improving Object Detection With One Line of Code
- Softer-NMS: Rethinking Bounding Box Regression for Accurate Object Detection
之前用了一篇博客詳細說明了NMS的原理,Cython版加速實現和CUDA加速版實現,然而NMS還是存在一些問題,本篇博客介紹兩種NMS的改進——Soft-NMS和Softer-NMS,提高NMS的性能。
傳統NMS存在的問題
NMS是為了去除重復的預測框而設計的算法,首先我們回憶一下普通NMS的過程(具體的請參考這篇博客):
假設所有輸入預測框的集合為S,算法返回結果集合D初始化為空集,具體算法如下:
?
那么NMS存在什么問題呢,其中最主要的問題有這么幾個:
- 物體重疊:如下面第一張圖,會有一個最高分數的框,如果使用nms的話就會把其他置信度稍低,但是表示另一個物體的預測框刪掉(由于和最高置信度的框overlap過大)
-
存在一些,所有的bbox都預測不準,對于下面第二張圖我們看到,不是所有的框都那么精準,有時甚至會出現某個物體周圍的所有框都標出來了,但是都不準的情況
- 傳統的NMS方法是基于分類分數的,只有最高分數的預測框能留下來,但是大多數情況下IoU和分類分數不是強相關,很多分類標簽置信度高的框都位置都不是很準
Soft-NMS
發現了這些問題,讓我們想想如何避免:
首先說第一個問題:物體重疊是由于輸出多個框中存在某些其實是另一個物體,但是也不小心被NMS去掉了。這個問題的解法最終是要落在“將某個候選框刪掉”這一步驟上,我們需要找到一種方法,更小心的刪掉S中的框,而不是暴力的把所有和最高分框刪掉,于是有了這個想法:
對于與最高分框overlap大于閾值t的框M,我們不把他直接去掉,而是將他的置信度降低,這樣的方法可以使多一些框被保留下來,從而一定程度上避免overlap的情況出現。
那么讀者可能會問,如果只是把置信度降低,那么可能原來周圍的多個表示同一個物體的框也沒辦法去掉了。Soft-NMS這樣來解決這個問題,同一個物體周圍的框有很多,每次選擇分數最高的框,抑制其周圍的框,與分數最高的框的IoU越大,抑制的程度越大,一般來說,表示同一個物體的框(比如都是前面的馬)的IoU是會比另一個物體的框(比如后面的馬)的IoU大,因此,這樣就會將其他物體的框保留下來,而同一個物體的框被去掉。
接下來就是Soft NMS的完整算法:
紅色的部分表示原始NMS算法,綠色部分表示Soft-NMS算法,區別在于,綠色的框只是把si降低了,而不是把bi直接去掉,極端情況下,如果f只返回0,那么等同于普通的NMS。
接下來說一下f函數:f函數是為了降低目標框的置信度,滿足條件,如果bi和M的IoU越大,f(iou(M, bi))就應該越小,Soft-NMS提出了兩種f函數:
線性函數:
這個比較好理解,當iou條件滿足時,si乘上一個1-iou,線性變小?
高斯函數懲罰,越接近高斯分布中心,懲罰力度越大
分析
Soft-NMS的效果也比較明顯:重疊的物體被更大程度的保留下來,以下是效果圖
不過Soft-NMS還是需要調整閾值的,由于沒有“去掉”某些框的操作,因此,最后所有框都會被加入D中,只是那些被去掉的框的置信度明顯降低,所以需要一個閾值(通常很小)來過濾D中的輸出框,從而輸出最后的預測框。所以Soft-NMS還是需要一些調參的
這里放一個注釋版的Cython實現:
def cpu_soft_nms(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0):cdef unsigned int N = boxes.shape[0]cdef float iw, ih, box_areacdef float uacdef int pos = 0cdef float maxscore = 0cdef int maxpos = 0cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ovfor i in range(N):# 在i之后找到confidence最高的框,標記為max_posmaxscore = boxes[i, 4]maxpos = itx1 = boxes[i,0]ty1 = boxes[i,1]tx2 = boxes[i,2]ty2 = boxes[i,3]ts = boxes[i,4]pos = i + 1# 找到max的框while pos < N:if maxscore < boxes[pos, 4]:maxscore = boxes[pos, 4]maxpos = pospos = pos + 1# 交換max_pos位置和i位置的數據# add max box as a detection boxes[i,0] = boxes[maxpos,0]boxes[i,1] = boxes[maxpos,1]boxes[i,2] = boxes[maxpos,2]boxes[i,3] = boxes[maxpos,3]boxes[i,4] = boxes[maxpos,4]# swap ith box with position of max boxboxes[maxpos,0] = tx1boxes[maxpos,1] = ty1boxes[maxpos,2] = tx2boxes[maxpos,3] = ty2boxes[maxpos,4] = tstx1 = boxes[i,0]ty1 = boxes[i,1]tx2 = boxes[i,2]ty2 = boxes[i,3]ts = boxes[i,4]# 交換完畢# 開始循環pos = i + 1while pos < N:# 先記錄內層循環的數據bix1 = boxes[pos, 0]y1 = boxes[pos, 1]x2 = boxes[pos, 2]y2 = boxes[pos, 3]s = boxes[pos, 4]# 計算iouarea = (x2 - x1 + 1) * (y2 - y1 + 1)iw = (min(tx2, x2) - max(tx1, x1) + 1) # 計算兩個框交叉矩形的寬度,如果寬度小于等于0,即沒有相交,因此不需要判斷if iw > 0:ih = (min(ty2, y2) - max(ty1, y1) + 1) # 同理if ih > 0:ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih) #計算union面積ov = iw * ih / ua #iou between max box and detection boxif method == 1: # linearif ov > Nt: weight = 1 - ovelse:weight = 1elif method == 2: # gaussianweight = np.exp(-(ov * ov)/sigma)else: # original NMSif ov > Nt: weight = 0else:weight = 1boxes[pos, 4] = weight*boxes[pos, 4]# if box score falls below threshold, discard the box by swapping with last box# update Nif boxes[pos, 4] < threshold:boxes[pos,0] = boxes[N-1, 0]boxes[pos,1] = boxes[N-1, 1]boxes[pos,2] = boxes[N-1, 2]boxes[pos,3] = boxes[N-1, 3]boxes[pos,4] = boxes[N-1, 4]N = N - 1pos = pos - 1pos = pos + 1keep = [i for i in range(N)]return keepSofter-NMS
Soft-NMS只解決了三個問題中的第一個問題,那么剩下兩個問題如何解決呢?
我們先分析第三個問題,對于分類置信度和框的IoU不是強相關的問題,我們需要找到一種方法來衡量框的“位置置信度”,對于第二個問題我們也有辦法:只需要讓多個框加權合并生成最終的框就可以了,本文提出這兩個想法:
IoU置信度
Softer-NMS文章對預測框建模,以下公式中表示偏移前的預測框,表示偏移后的預測框,輸出的表示GT框,使用高斯函數對預測框建模:?
GT框建模:使用delta分布:?
上個式子里面的delta分布是當高斯分布的σ趨于0時的極限分布,大概就是這樣:
當σ越小,曲線越瘦高,當σ非常小的時候,幾乎是一條豎直的線,同時σ越小,表示越確定,因此1?σ可以作為置信度的,網絡結構圖如下,上面是原始fasterRCNN的結構,下面是softer-nms結構,多加了一個sigma預測,也就是box std,而Box的預測其實就是上面公式中的
計算過程:
- 通過,的2范數距離和σ算出
- 通過和的2范數距離算出
- 使用和計算KLs散度作為loss,最小化KLLoss
上面是和的說明圖,藍色部分是標準差為σ的高斯分布,橙色是當σ為0時的delta分布,高斯分布的中心表示最終預測框的位置,σ表示置信度
分析
我們分析一下,Softer-NMS使用了一個技巧:當高斯函數的σ區域0的時候是非常像delta分布的,因此在訓練的過程中,通過KL散度優化兩者的距離,其實是告訴網絡,調整置信度σ和,使網絡輸出的分布盡量輸出高置信度,而且接近GT的偏移框;
接下來做一些數學分析:
以上是KL散度的計算,后面兩個和預測出來的是無關的(在這一步已經確定),因此后面兩項可以去掉;
繼續看,求梯度發現梯度中σ在分母:
容易導致梯度爆炸,而且置信度“越高越好”才比較符合常理,所以這里把1/σ替換為了
并加上一個極小量來防止分母為0,這樣梯度就不會為0了,在和偏移太大的時候,文章也是用了和smoothl1算法類似方法,把loss由2次降為1次,來防止離群點對模型影響過大。
首先,網絡預測出的東西和普通的faster_RCNN有所不同:${x1i , y1_i , x2_i , y2_i , s_i , \sigma{x1,i} , \sigma_{y1,i} , \sigma_{x2,i} , \sigma_{y2,i }},后面幾個是四個坐標的,后面幾個是四個坐標的\sigma$
上表中的藍色的是soft-nms,只是降低了S的權值,重點看綠色的,綠字第一行表示拿出所有與B的IoU大于Nt的框(用idx表示),然后將所有這些框做一個加權,B[idx]/C[idx]其實是B[idx] * 1/C[idx],后者是置信度,并使用sum做了歸一化。需要注意的是,Softer-NMS算法中,B是不變的,softer-nms只調整每個框的位置,而不篩選框;(還沒來得及閱讀源碼,應該在這之后又進行了框的篩選,不過這個時候已經通過softer-nms使那些分類置信度較高的框有更好的localtion輸出了,所以效果應該會好很多)
下圖表示Softer-NMS將右邊woman的一個不準確的框移動為相對準確的框,藍色數字表示置信度σ
總結
本文總結了Soft-NMS和Softer-NMS兩篇文章,這兩篇文章都是基于傳統NMS上的改進,目的在于解決目標檢測中的物體重疊難以預測,分類分數與IoU不匹配的問題,可以尤其是Soft-NMS,能夠在不重新訓練模型的前提下,只通過修改少量的代碼就能帶來不少的提升,可以說是非常易用了。Softer-NMS的實現稍顯復雜,需要網絡重新訓練以預測出四個坐標(x1, x2, y1, y2)的坐標置信度,然后用此置信度作為權值加權。實現了”多框合一“,其中使用的高斯分布和delta分布建模的思想很有意思,給置信度的計算多了一些新的思路。
?
原文:http://blog.prince2015.club/2018/12/01/Soft-NMS/
總結
以上是生活随笔為你收集整理的Soft(er)-NMS:非极大值抑制算法的两个改进算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 苹果致力于手势再生研发,无须使用控制器即
- 下一篇: 发送国外邮箱失败