博客專欄

EEPW首頁(yè) > 博客 > NMS技術(shù)總結(jié)(NMS原理、多類別NMS、NMS的缺陷、NMS的改進(jìn)思路、各種NMS方法)

NMS技術(shù)總結(jié)(NMS原理、多類別NMS、NMS的缺陷、NMS的改進(jìn)思路、各種NMS方法)

發(fā)布人:計(jì)算機(jī)視覺(jué)工坊 時(shí)間:2022-05-15 來(lái)源:工程師 發(fā)布文章

以下文章來(lái)源于CV技術(shù)指南 ,作者仿佛若有光157

作者丨仿佛若有光157

來(lái)源丨CV技術(shù)指南 


前言  本文介紹了NMS的應(yīng)用場(chǎng)合、基本原理、多類別NMS方法和實(shí)踐代碼、NMS的缺陷和改進(jìn)思路、介紹了改進(jìn)NMS的幾種常用方法、提供了其它不常用的方法的鏈接。

本文很早以前發(fā)過(guò),有個(gè)讀者評(píng)論說(shuō)沒(méi)有介紹多類別NMS讓他不滿意,因此特來(lái)補(bǔ)充。順便補(bǔ)充了NMS的缺點(diǎn)和改進(jìn)思路。


Non-Maximum Suppression(NMS)非極大值抑制。從字面意思理解,抑制那些非極大值的元素,保留極大值元素。其主要用于目標(biāo)檢測(cè),目標(biāo)跟蹤,3D重建,數(shù)據(jù)挖掘等。

目前NMS常用的有標(biāo)準(zhǔn)NMS, Soft  NMS, DIOU NMS等。后續(xù)出現(xiàn)了新的Softer NMS,Weighted NMS等改進(jìn)版。

原始NMS


以目標(biāo)檢測(cè)為例,目標(biāo)檢測(cè)推理過(guò)程中會(huì)產(chǎn)生很多檢測(cè)框(A,B,C,D,E,F等),其中很多檢測(cè)框都是檢測(cè)同一個(gè)目標(biāo),但最終每個(gè)目標(biāo)只需要一個(gè)檢測(cè)框,NMS選擇那個(gè)得分最高的檢測(cè)框(假設(shè)是C),再將C與剩余框計(jì)算相應(yīng)的IOU值,當(dāng)IOU值超過(guò)所設(shè)定的閾值(普遍設(shè)置為0.5,目標(biāo)檢測(cè)中常設(shè)置為0.7,僅供參考),即對(duì)超過(guò)閾值的框進(jìn)行抑制,抑制的做法是將檢測(cè)框的得分設(shè)置為0,如此一輪過(guò)后,在剩下檢測(cè)框中繼續(xù)尋找得分最高的,再抑制與之IOU超過(guò)閾值的框,直到最后會(huì)保留幾乎沒(méi)有重疊的框。這樣基本可以做到每個(gè)目標(biāo)只剩下一個(gè)檢測(cè)框。

圖片

原始NMS(左圖1維,右圖2維)算法偽代碼如下:

圖片圖片

實(shí)現(xiàn)代碼:(以pytorch為例)

def NMS(boxes,scores, thresholds):
    x1 = boxes[:,0]
    y1 = boxes[:,1]
    x2 = boxes[:,2]
    y2 = boxes[:,3]
    areas = (x2-x1)*(y2-y1)

    _,order = scores.sort(0,descending=True)
    keep = []
    while order.numel() > 0:
        i = order[0]
        keep.append(i)
        if order.numel() == 1:
            break
        xx1 = x1[order[1:]].clamp(min=x1[i])
        yy1 = y1[order[1:]].clamp(min=y1[i])
        xx2 = x2[order[1:]].clamp(max=x2[i])
        yy2 = y2[order[1:]].clamp(max=y2[i])

        w = (xx2-xx1).clamp(min=0)
        h = (yy2-yy1).clamp(min=0)
        inter = w*h

        ovr = inter/(areas[i] + areas[order[1:]] - inter)
        ids = (ovr<=thresholds).nonzero().squeeze()
        if ids.numel() == 0:
            break
        order = order[ids+1]
    return torch.LongTensor(keep)

除了自己實(shí)現(xiàn)以外,也可以直接使用torchvision.ops.nms來(lái)實(shí)現(xiàn)。

torchvision.ops.nms(boxes, scores, iou_threshold)

上面這種做法是把所有boxes放在一起做NMS,沒(méi)有考慮類別。即某一類的boxes不應(yīng)該因?yàn)樗c另一類最大得分boxes的iou值超過(guò)閾值而被篩掉。

對(duì)于多類別NMS來(lái)說(shuō),它的思想比較簡(jiǎn)單:每個(gè)類別內(nèi)部做NMS就可以了。

實(shí)現(xiàn)方法:把每個(gè)box的坐標(biāo)添加一個(gè)偏移量,偏移量由類別索引來(lái)決定。

下面是torchvision.ops.batched_nms的實(shí)現(xiàn)源碼以及使用方法

#實(shí)現(xiàn)源碼
max_coordinate = boxes.max()
offsets = idxs.to(boxes) * (max_coordinate + torch.tensor(1).to(boxes))
boxes_for_nms = boxes + offsets[:, None]
keep = nms(boxes_for_nms, scores, iou_threshold)
return keep

#使用方法
torchvision.ops.boxes.batched_nms(boxes, scores, classes, nms_thresh)

這里偏移量用boxes中最大的那個(gè)作為偏移基準(zhǔn),然后每個(gè)類別索引乘以這個(gè)基準(zhǔn)即得到每個(gè)類的box對(duì)應(yīng)的偏移量。這樣就把所有的boxes按類別分開(kāi)了。

在YOLO_v5中,它自己寫(xiě)了個(gè)實(shí)現(xiàn)的代碼。

c = x[:, 5:6] * (0 if agnostic else max_wh)  # classes
boxes, scores = x[:, :4] + c, x[:, 4]  # boxes (offset by class), scores
i = torchvision.ops.nms(boxes, scores, iou_thres) 

這里的max_wh相當(dāng)于前面的boxes.max(),YOLO_v5中取的定值4096。這里的agnostic用來(lái)控制是否用于多類別NMS還是普通NMS。


NMS的缺點(diǎn)


1. 需要手動(dòng)設(shè)置閾值,閾值的設(shè)置會(huì)直接影響重疊目標(biāo)的檢測(cè),太大造成誤檢,太小達(dá)不到理想情況。

2. 低于閾值的直接設(shè)置score為0,做法太hard。

3. 只能在CPU上運(yùn)行,成為影響速度的重要因素。

4. 通過(guò)IoU來(lái)評(píng)估,IoU的做法對(duì)目標(biāo)框尺度和距離的影響不同。


NMS的改進(jìn)思路


1. 根據(jù)手動(dòng)設(shè)置閾值的缺陷,通過(guò)自適應(yīng)的方法在目標(biāo)系數(shù)時(shí)使用小閾值,目標(biāo)稠密時(shí)使用大閾值。例如Adaptive NMS

2. 將低于閾值的直接置為0的做法太hard,通過(guò)將其根據(jù)IoU大小來(lái)進(jìn)行懲罰衰減,則變得更加soft。例如Soft NMS,Softer NMS。

3. 只能在CPU上運(yùn)行,速度太慢的改進(jìn)思路有三個(gè),一個(gè)是設(shè)計(jì)在GPU上的NMS,如CUDA NMS,一個(gè)是設(shè)計(jì)更快的NMS,如Fast NMS,最后一個(gè)是掀桌子,設(shè)計(jì)一個(gè)神經(jīng)網(wǎng)絡(luò)來(lái)實(shí)現(xiàn)NMS,如ConvNMS。

4. IoU的做法存在一定缺陷,改進(jìn)思路是將目標(biāo)尺度、距離引進(jìn)IoU的考慮中。如DIoU。

下面稍微介紹一下這些方法中常用的一部分,另一部分僅提供鏈接。


Soft NMS


根據(jù)前面對(duì)目標(biāo)檢測(cè)中NMS的算法描述,易得出標(biāo)準(zhǔn)NMS容易出現(xiàn)的幾個(gè)問(wèn)題:當(dāng)閾值過(guò)小時(shí),如下圖所示,綠色框容易被抑制;當(dāng)過(guò)大時(shí),容易造成誤檢,即抑制效果不明顯。因此,出現(xiàn)升級(jí)版soft NMS。

圖片

Soft NMS算法偽代碼如下:

圖片標(biāo)準(zhǔn)的NMS的抑制函數(shù)如下:圖片
    IOU超過(guò)閾值的檢測(cè)框的得分直接設(shè)置為0,而soft NMS主張將其得分進(jìn)行懲罰衰減,有兩種衰減方式,第一種懲罰函數(shù)如下:

圖片

    

這種方式使用1-Iou與得分的乘積作為衰減后的值,但這種方式在略低于閾值和略高于閾值的部分,經(jīng)過(guò)懲罰衰減函數(shù)后,很容易導(dǎo)致得分排序的順序打亂,合理的懲罰函數(shù)應(yīng)該是具有高iou的有高的懲罰,低iou的有低的懲罰,它們中間應(yīng)該是逐漸過(guò)渡的。因此提出第二種高斯懲罰函數(shù),具體如下:

圖片

這樣soft NMS可以避免閾值設(shè)置大小的問(wèn)題。

Soft NMS還有后續(xù)改進(jìn)版Softer-NMS,其主要解決的問(wèn)題是:當(dāng)所有候選框都不夠精確時(shí)該如何選擇,當(dāng)?shù)梅指叩暮蜻x框并不更精確,更精確的候選框得分并不是最高時(shí)怎么選擇 。論文值得一看,本文不作更多的詳解。

此外,針對(duì)這一閾值設(shè)置問(wèn)題而提出的方式還有Weighted NMS和Adaptive NMS。

Weighted NMS主要是對(duì)坐標(biāo)進(jìn)行加權(quán)平均,實(shí)現(xiàn)函數(shù)如下:

圖片

其中Wi = Si *IoU(M,Bi),表示得分與IoU的乘積。

Adaptive NMS在目標(biāo)分布稀疏時(shí)使用小閾值,保證盡可能多地去除冗余框,在目標(biāo)分布密集時(shí)采用大閾值,避免漏檢。


Softer NMS論文鏈接:

https://arxiv.org/abs/1809.08545

Softer NMS論文代碼:

https://github.com/yihui-he/softer-NMS

Weighted NMS論文鏈接:

https://ieeexplore.ieee.org/document/8026312/

Adaptive NMS論文鏈接:

https://arxiv.org/abs/1904.03629


DIoU NMS


圖片

當(dāng)IoU相同時(shí),如上圖所示,當(dāng)相鄰框的中心點(diǎn)越靠近當(dāng)前最大得分框的中心點(diǎn),則可認(rèn)為其更有可能是冗余框。第一種相比于第三種更不太可能是冗余框。因此,研究者使用所提出的DIoU替代IoU作為NMS的評(píng)判準(zhǔn)則,公式如下:

圖片

DIoU定義為DIoU=IoU-d2/c2,其中c和d的定義如下圖所示

圖片

在DIoU實(shí)際應(yīng)用中還引入了參數(shù)β,用于控制對(duì)距離的懲罰程度。

圖片

當(dāng) β趨向于無(wú)窮大時(shí),DIoU退化為IoU,此時(shí)的DIoU-NMS與標(biāo)準(zhǔn)NMS效果相當(dāng)。

當(dāng) β趨向于0時(shí),此時(shí)幾乎所有中心點(diǎn)與得分最大的框的中心點(diǎn)不重合的框都被保留了。

注:除了DIoU外,還有GIoU,CIoU,但這兩個(gè)都沒(méi)有用于NMS,而是用于坐標(biāo)回歸函數(shù),DIoU雖然本身也是用于坐標(biāo)回歸,但有用于NMS的。


GIoU


GIoU的主要思想是引入將兩個(gè)框的距離。尋找能完全包圍兩個(gè)框的最小框(計(jì)算它的面積Ac)。

圖片

計(jì)算公式如下:

圖片

當(dāng)兩個(gè)框完全不相交時(shí),沒(méi)有抑制的必要。

當(dāng)兩個(gè)框存在一個(gè)大框完全包圍一個(gè)小框時(shí)或大框與小框有些重合時(shí),GIoU的大小在(-1,1)之間,不太好用來(lái)作為NMS的閾值。

GIoU的提出主要還是用于坐標(biāo)回歸的loss,個(gè)人感覺(jué)用于NMS不合適,CIoU也是如此,這里之所以提這個(gè),是因?yàn)樗cDIoU、CIoU一般都是放一起講的。


其它相關(guān)NMS


為了避免閾值設(shè)置大小、目標(biāo)太密集等問(wèn)題,還有一些其他方法使用神經(jīng)網(wǎng)絡(luò)去實(shí)現(xiàn)NMS,但并不常用,這里只提一筆,感興趣的讀者請(qǐng)自行了解。如:

ConvNMS:A Convnet for Non-maximum Suppression

Pure NMS Network:Learning non-maximum suppression

Yes-Net: An effective Detector Based on Global Information

Fast NMS:

https://github.com/dbolya/yolact

Cluster NMS:

https://github.com/Zzh-tju/CIoU

Matrix NMS:

https://github.com/WXinlong/SOLO

Torchvision封裝的免編譯CUDA NMS

此處參考:

https://zhuanlan.zhihu.com/p/157900024

本文僅做學(xué)術(shù)分享,如有侵權(quán),請(qǐng)聯(lián)系刪文。


*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



關(guān)鍵詞: AI

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉