1. 程式人生 > >學習筆記-目標檢測、定位、識別(RCNN,Fast-RCNN, Faster-RCNN,Mask-RCNN,YOLO,SSD 系列)

學習筆記-目標檢測、定位、識別(RCNN,Fast-RCNN, Faster-RCNN,Mask-RCNN,YOLO,SSD 系列)

0. 前言

說到深度學習的目標檢測,就要提到傳統的目標檢測方法。

傳統的目標檢測流程:

1)區域選擇(窮舉策略:採用滑動視窗,且設定不同的大小,不同的長寬比對影象進行遍歷,時間複雜度高)

2)特徵提取(SIFT、HOG等;形態多樣性、光照變化多樣性、背景多樣性使得特徵魯棒性差)

3)分類器(主要有SVM、Adaboost等)

基於深度學習的目標檢測問題從2014年至今已經經歷過RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN 等版本的演變,效能和準確率也在不斷的提升,本篇部落格旨在將這些網路的結構和改進之處做一個總結回顧。認識粗淺,歡迎指正。

1. RCNN(2014)

流程:

輸入影象\RightarrowSelective Search(挑選2000和候選框)\RightarrowAlexNet網路提取特徵\RightarrowSVM分類

       Selective search方法來生成候選區域,這是一種啟發式搜尋演算法。它先通過簡單的區域劃分演算法將圖片劃分成很多小區域,然後通過層級分組方法按照一定相似度合併它們,最後的剩下的就是候選區域(region proposals),它們可能包含一個物體。示意圖如下:

        對於一張圖片,R-CNN基於selective search方法大約生成2000個候選區域,然後每個候選區域被resize成固定大小(227×227)並送入一個CNN模型中,使用AlexNet來提取影象特徵,最後得到一個4096維的特徵向量。然後這個特徵向量被送入一個多類別SVM分類器中,預測出候選區域中所含物體的屬於每個類的概率值。每個類別訓練一個SVM分類器,從特徵向量中推斷其屬於該類別的概率大小。為了提升定位準確性,R-CNN最後又訓練了一個邊界框迴歸模型。訓練樣本為(P,G),其中P=(Px,Py,Pw,Ph)為候選區域,而G=(Gx,Gy,Gw,Gh)為真實框的位置和大小。G的選擇是與P的IoU最大的真實框,迴歸器的目標值定義為:

        在做預測時,利用上述公式可以反求出預測框的修正位置。R-CNN對每個類別都訓練了單獨的迴歸器,採用最小均方差損失函式進行訓練。

        R-CNN是非常直觀的,就是把檢測問題轉化為了分類問題,但是,由於R-CNN使用計算複雜度極高的selective search提取候區域,並使用SVM來進行分類,並不是一個端到端的訓練模型。R-CNN模型在統一候選區的大小後才能進行特徵提取和特徵分類。並且提取的候選框會在特徵提取的時候會進行重複計算。


Selective Search介紹

step0:生成區域集R,具體參見論文《Efficient Graph-Based Image Segmentation》

step1:計算區域集R裡每個相鄰區域的相似度S={s1,s2,…} 
step2:找出相似度最高的兩個區域,將其合併為新集,新增進R 
step3:從S中移除所有與step2中有關的子集 
step4:計算新集與所有子集的相似度 
step5:跳至step2,直至S為空

論文中虛擬碼:

相似度計算

        在做物體識別(Object Recognition)過程中,不能通過單一的策略來區分不同的物體,需要充分考慮影象物體的多樣性(diversity)。另外,在影象中物體的佈局有一定的層次(hierarchical)關係,考慮這種關係才能夠更好地對物體的類別(category)進行區分。如下圖,(a)中的場景是一張桌子,桌子上面放了碗,瓶子,還有其他餐具等等。比如要識別“桌子”,我們可能只是指桌子本身,也可能包含其上面的其他物體。這裡顯示出了影象中不同物體之間是有一定的層次關係的。(b)中給出了兩隻貓,可以通過紋理(texture)來找到這兩隻貓,卻又需要通過顏色(color)來區分它們。(c)中變色龍和周邊顏色接近,可以通過紋理(texture)來區分。(d)中的車輛,我們很容易把車身和車輪看做一個整體,但它們兩者之間在紋理(texture)和顏色(color)方面差別都非常地大。

         

所以相似度計算時候論文考慮了顏色,紋理,尺寸和空間交疊這4個引數。

1)顏色相似度(color similarity)
將色彩空間轉為HSV,每個通道下以bins=25計算直方圖,這樣每個區域的顏色直方圖有25*3=75個區間。 對直方圖除以區域尺寸做歸一化後使用下式計算相似度:

2)紋理相似度(texture similarity)

論文采用方差為1的高斯分佈在8個方向做梯度統計,然後將統計結果(尺寸與區域大小一致)以bins=10計算直方圖。直方圖區間數為8*3*10=240(使用RGB色彩空間)。

其中,是直方圖中第個bin的值。

3)尺寸相似度(size similarity)

保證合併操作的尺度較為均勻,避免一個大區域陸續“吃掉”其他小區域。

例:設有區域a-b-c-d-e-f-g-h。較好的合併方式是:ab-cd-ef-gh -> abcd-efgh -> abcdefgh。 不好的合併方法是:ab-c-d-e-f-g-h ->abcd-e-f-g-h ->abcdef-gh -> abcdefgh。

4)交疊相似度(shape compatibility measure)

5) 最終的相似度

 

關於Selective Search的程式碼:https://github.com/AlpacaDB/selectivesearch

RCNN的缺陷:

1)耗時的Selective search,每一幀影象,需要花費2s。

2)耗時的序列式CNN網路,每一個ROI都要經過一個CNN提取特徵,所有的ROI提取特徵大約47s。

3)三個模組分開訓練,儲存空間消耗大

 

2. Fast RCNN(2015)

Fast-RCNN先用Selective Search找出候選框,’而後整張圖過一次CNN,然後用RoI Pooling,將對應候選框的部分做取樣,得到相同長度的特徵,又經過兩層全連線層之後得到最終的特徵。接著產生兩個分支,一個分支給此特徵分類,另一個分支迴歸此特徵的候選框偏移。Fast-RCNN將分類和迴歸任務融合在一個模型中。

針對RCNN的改進:

1)取代RCNN序列特徵提取方式,直接用一個神經網路對全圖提取特徵。

2)除了Selective search,其他部分可以一起訓練

核心演算法:RoI Pooling

 

3. Faster RCNN(2016)

改進:

提出Region Proposal Network(RPN)生成待檢測網路,取代了原來的Selective Search,真正實現了端到端的訓練(end-to-end training)。

核心演算法:RPN

 

4. Mask RCNN(2017)

此部分較多參考網址:https://blog.csdn.net/WZZ18191171661/article/details/79453780

Mask RCNN是一個例項分割(Instance segmentation)演算法。

例項分割(Instance segmentation)和語義分割(Semantic segmentation)的區別和聯絡

聯絡:兩者都是目標分割中的兩個小領域,用來對輸入的圖片進行分割處理。

區別:例項分割對物件更加細化,如對於影象中不同的人,語義分割給了它們相同的顏色,而在例項分割中卻給了不同的顏色。即例項分割需要在語義分割的基礎上對同類物體進行更精細的分割。

Mask RCNN預期達到的效果:高速和高準確率,簡單直觀且以便於使用。

高速和高準確率:

為了實現這個目的,作者選用了經典的目標檢測演算法Faster-rcnn和經典的語義分割演算法FCN。Faster-rcnn可以既快又準的完成目標檢測的功能;FCN可以精準的完成語義分割的功能,這兩個演算法都是對應領域中的經典之作。Mask R-CNN比Faster-rcnn複雜,但是最終仍然可以達到5fps的速度,這和原始的Faster-rcnn的速度相當。由於發現了ROI Pooling中所存在的畫素偏差問題,提出了對應的ROIAlign策略,加上FCN精準的畫素MASK,使得其可以獲得高準確率。

簡單直觀且以便於使用:

整個Mask R-CNN演算法的思路很簡單,就是在原始Faster-rcnn演算法的基礎上面增加了FCN來產生對應的MASK分支。即Faster-rcnn + FCN,更細緻的是 RPN + ROIAlign + Fast-rcnn + FCN

整個Mask R-CNN演算法非常的靈活,可以用來完成多種任務,包括目標分類、目標檢測、語義分割、例項分割、人體姿態識別等多個任務,具有很好的擴充套件性和易用性。

1)Mask R-CNN演算法步驟

  • 首先,輸入一幅你想處理的圖片,然後進行對應的預處理操作,或者預處理後的圖片;
  • 然後,將其輸入到一個預訓練好的神經網路中(ResNeXt等)獲得對應的feature map;
  • 接著,對這個feature map中的每一點設定預定個的ROI,從而獲得多個候選ROI;
  • 接著,將這些候選的ROI送入RPN網路進行二值分類(前景或背景)和BB迴歸,過濾掉一部分候選的ROI;
  • 接著,對這些剩下的ROI進行ROIAlign操作(即先將原圖和feature map的pixel對應起來,然後將feature map和固定的feature對應起來);
  • 最後,對這些ROI進行分類(N類別分類)、BB迴歸和MASK生成(在每一個ROI裡面進行FCN操作)。

2)Mask R-CNN的核心架構分解(ROIAlign和FCN)

 ROIPooling和ROIAlign的分析與比較

ROI Pooling和ROIAlign最大的區別是:前者使用了兩次量化操作,而後者並沒有採用量化操作,使用了線性插值演算法,具體的解釋如下所示

ROI Pooling技術:

為了得到固定大小(7X7)的feature map,我們需要做兩次量化操作:1)影象座標 — feature map座標,2)feature map座標 — ROI feature座標。我們來說一下具體的細節,如圖我們輸入的是一張800x800的影象,在影象中有兩個目標(貓和狗),狗的BB大小為665x665,經過VGG16網路後,我們可以獲得對應的feature map,如果我們對卷積層進行Padding操作,我們的圖片經過卷積層後保持原來的大小,但是由於池化層的存在,我們最終獲得feature map 會比原圖縮小一定的比例,這和Pooling層的個數和大小有關。在該VGG16中,我們使用了5個池化操作,每個池化操作都是2Pooling,因此我們最終獲得feature map的大小為800/32 x 800/32 = 25x25(是整數),但是將狗的BB對應到feature map上面,我們得到的結果是665/32 x 665/32 = 20.78 x 20.78,結果是浮點數,含有小數,但是我們的畫素值可沒有小數,那麼作者就對其進行了量化操作(即取整操作),即其結果變為20 x 20,在這裡引入了第一次的量化誤差;然而我們的feature map中有不同大小的ROI,但是我們後面的網路卻要求我們有固定的輸入,因此,我們需要將不同大小的ROI轉化為固定的ROI feature,在這裡使用的是7x7的ROI feature,那麼我們需要將20 x 20的ROI對映成7 x 7的ROI feature,其結果是 20 /7 x 20/7 = 2.86 x 2.86,同樣是浮點數,含有小數點,我們採取同樣的操作對其進行取整吧,在這裡引入了第二次量化誤差。其實,這裡引入的誤差會導致影象中的畫素和特徵中的畫素的偏差,即將feature空間的ROI對應到原圖上面會出現很大的偏差。原因如下:比如用我們第二次引入的誤差來分析,本來是2,86,我們將其量化為2,這期間引入了0.86的誤差,看起來是一個很小的誤差呀,但是你要記得這是在feature空間,我們的feature空間和影象空間是有比例關係的,在這裡是1:32,那麼對應到原圖上面的差距就是0.86 x 32 = 27.52。這個差距不小吧,這還是僅僅考慮了第二次的量化誤差。這會大大影響整個檢測演算法的效能,因此是一個嚴重的問題。

ROIAlign技術:

 為了得到為了得到固定大小(7X7)的feature map,ROIAlign技術並沒有使用量化操作,即我們不想引入量化誤差,比如665 / 32 = 20.78,我們就用20.78,不用什麼20來替代它,比如20.78 / 7 = 2.97,我們就用2.97,而不用2來代替它。這就是ROIAlign的初衷。那麼我們如何處理這些浮點數呢,我們的解決思路是使用“雙線性插值”演算法。雙線性插值是一種比較好的影象縮放演算法,它充分的利用了原圖中虛擬點(比如20.56這個浮點數,畫素位置都是整數值,沒有浮點值)四周的四個真實存在的畫素值來共同決定目標圖中的一個畫素值,即可以將20.56這個虛擬的位置點對應的畫素值估計出來。厲害哈。如圖11所示,藍色的虛線框表示卷積後獲得的feature map,黑色實線框表示ROI feature,最後需要輸出的大小是2x2,那麼我們就利用雙線性插值來估計這些藍點(虛擬座標點,又稱雙線性插值的網格點)處所對應的畫素值,最後得到相應的輸出。這些藍點是2x2Cell中的隨機取樣的普通點,作者指出,這些取樣點的個數和位置不會對效能產生很大的影響,你也可以用其它的方法獲得。然後在每一個橘紅色的區域裡面進行max pooling或者average pooling操作,獲得最終2x2的輸出結果。我們的整個過程中沒有用到量化操作,沒有引入誤差,即原圖中的畫素和feature map中的畫素是完全對齊的,沒有偏差,這不僅會提高檢測的精度,同時也會有利於例項分割。

we propose an RoIAlign layer that removes the harsh quantization of RoIPool, properly aligning the extracted features with the input. Our proposed change is simple: we avoid any quantization of the RoI boundaries or bins (i.e., we use x=16 instead of [x=16]). We use bilinear interpolation [22] to compute the exact values of the input features at four regularly sampled locations in each RoI bin, and aggregate the result (using max or average), see Figure 3 for details. We note that the results are not sensitive to the exact sampling locations, or how many points are sampled, as long as no quantization is performed。

雙線性插值:

       
3)LOSS計算與分析

由於增加了mask分支,每個ROI的Loss函式如下所示:

其中Lcls和Lbox和Faster r-cnn中定義的相同。對於每一個ROI,mask分支有Km*m維度的輸出,其對K個大小為m*m的mask進行編碼,每一個mask有K個類別。我們使用了per-pixel sigmoid,並且將Lmask定義為the average binary cross-entropy loss 。對應一個屬於GT中的第k類的ROI,Lmask僅僅在第k個mask上面有定義(其它的k-1個mask輸出對整個Loss沒有貢獻)。我們定義的Lmask允許網路為每一類生成一個mask,而不用和其它類進行競爭;我們依賴於分類分支所預測的類別標籤來選擇輸出的mask。這樣將分類和mask生成分解開來。這與利用FCN進行語義分割的有所不同,它通常使用一個per-pixel sigmoid和一個multinomial cross-entropy loss ,在這種情況下mask之間存在競爭關係;而由於我們使用了一個per-pixel sigmoid 和一個binary loss ,不同的mask之間不存在競爭關係。經驗表明,這可以提高例項分割的效果。

一個mask對一個目標的輸入空間佈局進行編碼,與類別標籤和BB偏置不同,它們通常需要通過FC層而導致其以短向量的形式輸出。我們可以通過由卷積提供的畫素和畫素的對應關係來獲得mask的空間結構資訊。具體的來說,我們使用FCN從每一個ROI中預測出一個m*m大小的mask,這使得mask分支中的每個層能夠明確的保持m×m空間佈局,而不將其摺疊成缺少空間維度的向量表示。和以前用fc層做mask預測的方法不同的是,我們的實驗表明我們的mask表示需要更少的引數,而且更加準確。這些畫素到畫素的行為需要我們的ROI特徵,而我們的ROI特徵通常是比較小的feature map,其已經進行了對其操作,為了一致的較好的保持明確的單畫素空間對應關係,我們提出了ROIAlign操作。

FCN回顧

 

3)Mask R-CNN的主要貢獻

  • 分析了ROI Pool的不足,提升了ROIAlign,提升了檢測和例項分割的效果;
  • 將例項分割分解為分類和mask生成兩個分支,依賴於分類分支所預測的類別標籤來選擇輸出對應的mask。同時利用Binary Loss代替Multinomial Loss,消除了不同類別的mask之間的競爭,生成了準確的二值mask;
  • 並行進行分類和mask生成任務,對模型進行了加速。
     

5. YOLO(2016)

以下寫貼一些別人對YOLO的評價吧

 

  • YOLO是我見過的最elegant的方法(直接回歸bounding boxes coordinates和all C class probabilities)。具體如下:先將圖片resize成448*448(L*L)大小,將圖片劃分成S*S個grid(S=7,所以每個64*64大小的sub-image屬於一個grid)。然後每個grid負責propose B個bounding box(B=2),每個bounding box對應4個coordinates、1個confidence(表示P(object)*對應的bounding box和any ground truth box的intersection of union(IOU)大小,即P(Object)*IOU^{truth}_{pred}),另外,每個grid還要生成C個conditional class probabilities(表示該grid內部的sub-image包含object時,這個object屬於各個類別上的概率,即P(C_{i}|Object);因為總共有20個類別,所以C=20)。這樣,一個image最終產生S*S*(B*5+C)個輸出(7*7*(2*5+20)=1470個輸出)。然後就是找ground truth進行訓練,要考慮不同任務的權重。預測時,使用P(C_{i}|Object)*P(Object)*IOU^{truth}_{pred}找到最大的C_{i}即可。可以看到,YOLO模型非常簡單,所以最大的好處是,時間快,做到了實時;另外,由於看到的context資訊比較多,多以background很少分錯。缺點是特徵粒度太粗,small object容易分錯,accuracy相對較低(主要錯誤在於localization,這個也是顯而易見的)。===》本人檢視並修改了YOLO的原始碼,確實很經典,而且實現起來很簡單,效果也不錯。===》據說YOLO-V2版本中,將每個grid生成C個conditional class probabilities(然後讓該grid對應的所有bounding boxes共享這C個conditional class probabilities)改成了為每個bounding boxes生成各自獨立的C個conditional class probabilities,此時效果有明顯提升!!
  • YOLO是一個可以一次性預測多個Box位置和類別的卷積神經網路,能夠實現端到端的目標檢測和識別,其最大的優勢就是速度快。事實上,目標檢測的本質就是迴歸,因此一個實現迴歸功能的CNN並不需要複雜的設計過程。YOLO沒有選擇滑窗或提取proposal的方式訓練網路,而是直接選用整圖訓練模型。這樣做的好處在於可以更好的區分目標和背景區域,相比之下,採用proposal訓練方式的Fast-R-CNN常常把背景區域誤檢為特定目標。當然,YOLO在提升檢測速度的同時犧牲了一些精度。下圖所示是YOLO檢測系統流程:1.將影象Resize到448*448;2.執行CNN;3.非極大抑制優化檢測結果。

6.SSD(2015)

  • SSD。有人說SSD相當於YOLO(直接回歸bounding boxes coordinates和all C class probabilities) + RPN的anchor(每個feature map用一個小視窗掃描,對每個掃描位置生成k個default的bounding boxes) + multi-scale的prediction。個人感覺SSD最大的特點是multi-scale的prediction,從一個image中生成多個不同scale、spatial_ratio的feature maps(具體實現時,就是把網路的最後幾層設計成不同的scale,全部作為feature maps),然後在每個feature map上生成需要的資料(bounding boxes、class probabilities等),然後聯合訓練。具體的,仍然用3*3的視窗對每個feature map進行掃描,在每個掃描位置生成k個不同大小的default bounding boxes,每個boxes對應4個coordinates和C個class probabilities(和YOLO一樣,直接是C個類別對應的概率;不同於Faster-R-CNN的2個輸出,只能代表是不是object的概率,還需後續classification)。然後就是找ground truth進行訓練,要考慮不同任務的權重。可以看到對於M*N的feature map,輸出節點數為M*N*K*(C+4),另外因為有F個feature map,所以還要再乘以F。
     

 

 

 

 

 

 

參考網址

1. 基於CNN目標檢測方法(RCNN,Fast-RCNN,Faster-RCNN,Mask-RCNN,YOLO,SSD)行人檢測,目標追蹤,卷積神經網路

2. 選擇性搜尋(selective search)

3. R-CNN,Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列,深度學習object detection梳理

推薦閱讀

4. R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD, R-FCN系列深度學習檢測方法梳理