關於SSD和YOLO對小目標的思考


所謂的小目標,要看是絕對小目標(像素),和相對小目標(相對原圖的長寬來看的)。大目標小目標只跟receptive field(感受野)有關,cnn本身可以檢測任何尺度的物體。ssd對小目標檢測不太適用,但R-FCN速度和魯棒存在問題。

小目標分為很多種,背景單一還是比較好做的。有一篇小人臉檢測用的是 fullyconvolutionalnetwork(FCN) + ResNet ,此篇論文檢測小目標用了其周邊的信息,如頭發,肩膀。

小目標像素特征少,不明顯,因此和大目標相比,小目標的檢測率低,這個用任何算法上都是無法避免的。SSD,YOLO等單階段多尺度算法,小目標檢測需要高分辨率,但是SSD對小目標的檢測是在淺層特征上進行,而深層的特征用來檢測大目標,但是!深層的特征語義信息非常豐富,這是一個矛盾。例如底層conv4_3anchor設置的是0.1~0.2:30x60,對於720p的圖像檢測尺寸就有72個像素,還是太大了。事實上SSD的源碼允許一個特征層做多個尺度的滑窗,將參數min_sizes里的每個元素初始化為一個列表,就可以在相應特征層中生成不同尺度的anchor,如果你設計的足夠仔細,基本就可以覆蓋足夠小的目標了,不過此時anchor的數量估計會漲不少,速度也會降下來。

faster rcnn,yolo,ssd對小目標檢測結果都不好,原因在於卷積網絡結構的最后一層feature map太小,例如32*32的目標經過vgg后變成2*2,導致之后的檢測和回歸無法滿足要求。卷積網絡越深語義信息越強,而越低層則是描述的局部外觀信息越多,而且我想VGG16卷積層設計成這么多肯定是有意義的,如果靠前的效果好,VGG的研究者應該想到減少層數了,我覺得可以考慮提取多層的特征這樣表達能力強些。比如樣本貓狗圖像,較小的貓的ground truth只是出現在底層,高層沒有貓的ground truth,而較大物體狗匹配到的ground truth在高層feature map上),其他層的信息只是簡單拼接(所以小物體檢測的語義信息,contex信息差一些)。

SSD是多尺度的特征圖進行paopasal提取,ssd相對於yolo來說對小目標更穩定。yolo則是通過全局特征去直接得到預測結果,完全要靠數據堆積起來,對待小目標我覺得要考慮減少pooling;

SSD里負責檢測小目標的層為conv4_3(38*38)對應的尺度為0.2(可人為設置)。這就對應了SSD所能檢測的尺度大概為0.2上下。在這種情況下,如果物體過於小的話,甚至在訓練階段,GT都沒法找到相應的的default box與它匹配,效果怎么可能會好。如果不介意整體檢測效果的話,可以把尺度調低,看看對於小目標的檢測效果是否有提升。另外,利用多尺度進行檢測也能提高小物體的檢測效果

SSD使用的VGG16作為特征抽取,在conv4_3 feature map 的分辨率已經縮小了8倍,在conv5_3縮小了16倍,比如一個32*32大小的物體,在vgg16 的 conv5_3的feature map 對應僅為2*2,位置信息有較大的損失。有兩種方法可解決這個問題:1.使用不同層的特征,比如hyperNet,MultiPath。2.保證感受也不縮小的情況下feature map的分辨率不至於縮小太多,如采用DeepLab中采用的Hole algorithm,在保證感受野的同時分辨變化較小

他們對小目標檢測不好的原因主要是,SSD/YOLO 對原圖做了縮放,因為感受野的原因,導致“相對尺寸小”目標檢測困難。如果說RCNN系列,並沒有對原圖進行縮放,但是如果”絕對尺寸小“的話,也沒有辦法,因為到了一定深度的Feature map,小目標可能已經丟失response了。

1.小目標往往更依賴淺層特征,因為淺層特征有更高的分辨率,然而對語義區分較差。

2.SSD檢測和分類一起做,會把一些檢測到但是分類模糊,分數不高的結果過濾掉。而rpn不會,前200個候選繼續分類,都會有個結果。

3.為了速度,本來是全卷積網絡,卻也固定了輸入尺寸,對大圖的小目標影響很大。

一些比較好的觀點

CNN特征的分辨率較差,這點不比其它low-level(淺層)的特征,證據就是在pedestrian detection(行人檢測)上, 一些hand-crafted features(手工制作特征)的效果還是不錯的;Faster-rcnn和SSD本身的問題,原始的Faster-rnn在RPN中將input的最短邊固定resize到600>SSD512>SSD300,SSD使用300和512的原因是為了提高detection speed,所以SSD才這樣快;同時為保證精度,SSD才加上了multi-scale和data augmentation(尤其值得注意這個augmentation,數據增強)。

yolo和ssd確實對小物體很無力,而有些普通的圖像算法對小物體檢測反而好的多,只是不太魯棒。可以嘗試下R-FCN,我測試了幾張,好像對小物體還可以,但是速度慢些。在970下0.18s一張的樣子。我之前在VGG16上做過R-FCN的實驗,使用相同的res101-proposal(只關注detection的效果所以使用的一樣),效果不如fast rcnn。同理,在google-v1上(也是全卷積)也是不如,我估計是淺網絡的overfitting問題(因為用VGG的proposal去做效果很不好)。

SSD是一種基於全卷積的網絡的檢測器,用不同層檢測不同大小的物體。這中間有個矛盾,前面的 feature map大,但semantic(語義)不夠,后面的sematic夠了,但經過太多的pooling,feature map太小了。要檢測小物體,既需要一張足夠大的feature map來提供更加精細的特征和做更加密集的采樣,同時也需要足夠的semantic meaning來與背景區分開。參會時問過SSD的作者,如果將最后的feature map放大接上前面的話,是不是能夠改善性能,作者說值得一試

SSD is a class aware RPN with a lot of bells and whistles。每一個feature map上面的pixel對應幾個anchor,這個網絡對anchor進行訓練,以此驅動對feature進行訓練。這是前言。作為小物體,其所對應的anchor比較少 (gt overlap > 0.5 的 anchor),也就是說對應feature map上的pixel難以得到充分訓練。讀者可以腦補每一個大的ROI可能覆蓋很多 anchor,那么這些 anchor 均有機會得到訓練。然而一個小物體並不能覆蓋很多 anchor。沒有得到充分訓練有什么問題?在test的時候這個pixel的預測結果可能就是亂的,會極大干擾正常結果。為什么SSD的data augmentation能漲這么多點,就是因為通過randomly crop,讓每一個anchor都得到充分訓練(也就是說,crop出一個小物體,在新圖里面就變成大物體了)只能說這種without region propisal的結果 naturally 不擅長小物體。通過往上堆 hack 才能慢慢比上吧。

我試過SSD最前面的卷積為深度殘差網絡,檢測小物體效果還不錯,比YOLO要好得多

另外SSD原論文中,多級別的物體基本尺寸從0.1到0.8,實際上0.1的比例還是很大的,如1024*1024的輸入,0.1都到102了,其實不小。可以根據需求調整級別,我使用的為1/64~1,即不同級別格子本身大小。當然,級別從線性分割變成指數分割后,在基本大小之上的各個變形也需要調整一下(主要是變大),不然有可能覆蓋不到有些位於兩個格子中間的某些大小的物體。YOLO比較坑的地方在於倒數第二層為全連接,后面的7*7格子不能擴張太大,不然前面的全連接要爆。格子大了,同一個格子可能會包括多個小物體,檢測就不好搞了。而YOLO全連接的作用又是整合全局信息,要去掉全連接,就需要增加最后點的感受野,所以深度殘差就非常適合。提到深度殘差,再說另外一點。在深度殘差的作者kaiming大神另一篇文章R-FCN: Object Detection via Region-based Fully Convolutional Networks,中有使用空間pooling,發現深度殘差就是天然的自帶空間pooling效果的結構啊。補充一點,SSD前面的CNN結構,一定要是全對稱的,特別是pooling的時候,這樣最后輸出點的感受野中心才與每個格子的中心是重合的。如果是非對稱的,CNN前面特征提取的時候,它會糾結,造成大量的小物體不好學習。而YOLO最后有全連接都還好,問題不大。最后一句,深度殘差就是自帶空間pooling結構,這個怎么理解呢。深度殘差中的最小單元,一邊為兩個卷積壘在一起,假設作用只是把圖像平移,另一個為直連,那最后接合在一起,就是一個空間相關的組合了嘛。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM