1. 程式人生 > >目標檢測演算法理解:從R-CNN到Mask R-CNN

目標檢測演算法理解:從R-CNN到Mask R-CNN

  因為工作了以後時間比較瑣碎,所以更多的時候使用onenote記錄知識點,但是對於一些演算法層面的東西,個人的理解畢竟是有侷限的。我一直做的都是影象分類方向,最近開始接觸了目標檢測,也看了一些大牛的論文,雖然網上已經有很多相關的演算法講解,但是每個人對同一個問題的理解都不太一樣,本文主要結合自己的理解做一下記錄,也歡迎大家批評指正~

  在講解object detection演算法之前,我們需要明白影象處理領域的幾個任務的區別,比如image classification、semantic segmention、instance segmention。image classification是對整個影象做識別,判斷其屬於哪一類,比如名人識別。object detection是檢測影象中有什麼,如果有的話會框出所有該物件所在的子區域,值得一提的是,這裡的物件可以是多類,比如一副圖中同時包含貓、狗、鴨等物件,一個目標檢測演算法可以分別找到所有這些物件。semantic segmention是不考慮影象中的目標實體,將每個畫素劃分到不同的類別。instance segmention不僅要檢測出物件,還要對物件按照其真實邊緣進行精確的分割。

R-CNN

  R-CNN的全稱是Region-Based Convolutional Networks,它是一種比較符合常規思路的目標檢測演算法。從字面意思就可以看出,卷積網路的輸入是影象的某個子區域,而不是整個影象。傳統的SIFT和HOG淺層特徵並不能很好地表徵影象中的模式,作者採用了深層CNN網路來提取影象中的判別資訊。下面按照模型定義->模型訓練->模型測試->postprocessing的思路講解這個演算法。

R-CNN網路結構

  R-CNN網路結構主要包含兩大部分,CNN網路和SVM分類演算法,前者用於提特徵,將單個候選區域轉換成一維的特徵向量,後者包含了多個svm分類器,分類器的個數與目標的類別數相同,具體的網路結構如下,

資料準備和模型訓練

  object detection任務也屬於有監督學習演算法,每一個影象對應著標籤,這裡的標籤包括圖片中物件的bounding box和該box中物件的類別。對於每一幅影象,文章採用了selective search策略提取出2000個候選區域,這裡不妨把候選區域稱作子影象塊。整個模型的訓練是分階段進行的,先訓練前面的CNN網路,再訓練後面的SVM分類器,下面分開介紹這兩個階段。
  對於CNN網路來說,在訓練該模型時,它的標籤包含了兩類影象塊,positive樣本和negative樣本,positive指IoU值大於0.5的影象塊,negative指Iou值小於0.5的影象塊(IoU的全稱是intersection-over-union,表示影象塊和對應的bounding box之間的交集區域面積與並集區域面積的比值,顯然,當影象塊和bounding box重疊時,IoU取最大值1)。因為CNN網路的輸入影象尺寸是固定的,所以為了更夠正常地輸入到網路中,需要先將這些影象塊縮放到規定的尺寸。
  通常,與image classification任務不同,目標檢測的訓練影象數量通常都相對較少,所以訓練CNN網路的時候,並不能從頭開始訓練,而是基於已經訓練好的的CNN網路,對其輸出層引數進行微調,這種思想也可以看作是“遷移學習”。這裡順便回答一下為什麼不直接用CNN網路的提取出的特徵,而是要進行finetune階段呢?因為一些經典的CNN網路結構,比如Alexnet和Resnet等模型,它們都是基於Imagenet資料集進行訓練的,也就是說它們在挖掘imagenet資料集中的模式的效果比較好,但是不同資料集的分佈是有差異的,原生的Alexnet網路並不能很好地提取出新的目標檢測資料集中的規律。
  對於SVMs來說,因為SVM在訓練樣本數比較少時也有很好的分類效果,所以它對訓練樣本的構造比較“挑剔”,只有當子影象塊將整個bounding box框住的時候才會被作為positive樣本,只有當子影象塊的Iou值小於0.3才會被作為negative樣本。其他的子影象塊全部忽略。顯然,這些子影象塊可能包含了不同的目標,比如有的包含飛機,有的包含人物,還有的包含電視監視器,那麼就相當於是一個多分類問題, 而SVM實現多分類是通過將其分解成多個二分類問題解決的。比如在訓練第一個二分類模型,判斷是否為飛機時,可以選擇包含飛機的影象塊作為正例,其它的影象塊作為反例。
  到這裡,還需要解釋兩個問題,一是為什麼CNN網路和SVM的訓練樣例的選擇標準會不同呢?二是為什麼作者不直接使用CNN的分類器輸出作為預測標籤,而要額外引入SVM呢?對於第一個問題,因為在訓練CNN網路時,為了避免網路模型over fitting,需要使用更多的訓練樣本,於是就必然要用到可信度較低的positive樣本(Iou值介於0.5和1之間)。對於第二個問題,因為CNN網路的訓練樣本魚龍混雜,所以並不能實現精確定位出目標區域,所以僅作為特徵提取,而額外採用SVM來判別影象塊的類別。

模型測試

  在模型測試階段,輸入的是單幅影象,然後採用selective search方法生成2000個候選區域,對於每一個候選區域,先使用CNN網路模型提取其一維特徵向量,然後使用SVMs輸出該特徵向量屬於不同類別的scores,預測出該特徵向量對應的類別標籤。當所有2000個候選區域均打分完成時,對於每一個類別,使用貪婪的non-maximum supression演算法捨棄掉某些區域,關於這個演算法,原文中是這麼說的”rejects a region if it has an intersection-over-union
(IoU) overlap with a higher scoring selected region larger than a learned threshold”。可以這麼理解,比如當前類別有五個影象塊,編號分別為A、B、C、D、E,先將這些影象塊按照score由高到低排列,假設排序後為B、A、D、E、C,先保留得分最高的影象塊(或者稱作候選區域),也即B,然後分別計算A、D、E、C與B之間的IoU值,如果IoU值大於設定的threshold,就捨棄該影象塊,比如A和B之間的IoU值為0.9,大於設定的threshold=0.7,那麼就捨棄影象塊A,現在就剩下D、E、C需要取捨了,思路同上,也是要先保留三者中Iou最大的影象塊,對於每一類都這樣進行下去,就可以得到影象中所有類別的物件的子區域。

postprocessing

  在上一步得到所有候選區域中可信度較高的影象塊後,我們通常的想法是到這裡已經處理完了,但作者在文章最後闡述了Bounding-Box Regression。具體來說,它是用於對影象塊的位置進行微呼叫的,使其更加接近真實的boundingbox,記P=( P x , P y , P w , P h )表示當前候選的影象塊,G=( G x , G y , G w , G h )表示真實的boundingbox位置,在訓練該回歸模型的時候,分別使用線性迴歸模型對G中的四個引數建模,該模型的輸入是輸入影象塊在第5個pooling層的特徵表示,通過定義帶二範數約束的均方誤差損失函式,可以求解出迴歸模型的引數。迴歸模型的優化過程比較簡單,在這裡就不詳細展開講了,具體的可以參見原文中的7.3部分。

Fast R-CNN

  在2015年,作者提出了新的目標檢測模型Fast R-CNN,它是R-CNN的改進版本。那麼,為什麼要對R-CNN演算法進行改進呢,因為它存在如下3大缺點:
  (1)訓練過程是多階段的,先後分別訓練了ConvNet、SVM和bounding-box regressors;
  (2)訓練過程耗時較長且需要較大的儲存空間;
  (3)在測試階段進行目標檢測很慢,因為要分別對每一個候選區域進行前向傳播。

Fast R-CNN網路結構

  Fast R-CNN使用了單階段的多工網路模型進行目標檢測,該模型的輸入為整個影象和影象中的所有目標區域。從訊號流的前像傳播的角度來看,從輸入到輸出經過了下面幾個階段:
  (1)該網路先採用了多個卷積和池化操作提取出高階抽象特徵,將輸入影象轉換成了一個conv feature map。然後,因為該feature map和輸入影象的尺寸不一樣,需要將輸入影象中的目標區域投影到該feature map上去;
  (2)為了使所有投影后的影象塊能和後面的fully connected layer神經元數目保持一致,需要將這些大小不一的影象塊變換到相同尺寸,這裡便用到了RoI pooling layer,具體來說,比如一個大小為 h w 的影象塊,可以把它劃分成 H W 的網格,然後對每個小格子中的所有畫素進行max-pooling操作,那麼不管投影后的影象塊的大小如何,經過RoI pooling層後都會被轉化為相同的尺寸了;
  (3)池化後的二維特徵經過多個全連線層,轉化為一維的特徵向量,即RoI feature vector;
  (4)基於上面得到的feature vector,引出兩個分支,分別為softmax分類器和bbox regressor。softmax分類器用於輸出候選窗屬於K個類別物件的概率,bbox regressor用於輸出對應的K個類別物件的位置,該位置分別用4個實數表示。
  整個模型的架構如下圖,

模型訓練

  該網路結構是改進版的CNN模型,也可以使用預訓練的imagenet網路來初始化模型中的引數,只不過要用上圖中的陰影部分的子網路替換imagenet網路中最後一個池化層及其後面的子網路。在模型引數finetune階段,只需要對上圖陰影部分子網路中的引數進行優化。作者在文章中提出了一種更加高效的訓練演算法,通過使用分層次取樣來更好地利用特徵共享。具體來說,比如要從N=2個影象中取樣出R=128個候選區域,那麼由於同一影象中的所有候選區域在forward propagation和backward propagation過程中共享計算和儲存,因此比對128幅不同影象取樣快了64倍(注:R-CNN演算法就是對128幅不同影象取樣的)。
  由於Fast R-CNN模型不僅要預測類別標籤還要確定物件的位置,這便是典型的Multi-task問題,那麼損失函式也應該是這兩個子任務的損失之和,損失函式表示式如下,


  其中, L c l s ( p , u ) = l o g p u 表示softmax輸出層的損失,衡量的是預測值p和真實類別標籤u之間的差異性。 L l o c ( t u , v ) 表示bbox regressor輸出層的損失。u表示類別標籤,v表示真實的位置座標 v x , v y , v w , v h t u 表示類別u對應的預測位置座標。 [ u >= 1 ] 是一個符號函式,當括號內為真時結果為1,為假時結果為0,它用於過濾掉背景類別的損失,因為只有背景類別的u值為0。引數 λ 用於對這兩個任務的損失進行折中。
  儘管現在的一些深度學習框架,基本都帶有自動求微分功能,但是這裡引入了RoI池化層這一新概念,感覺還是有必要明白bp演算法在這一層是如何實現的。RoI pooling層的影象化效果如下圖,

假設輸入x是大小為6×6的影象塊,池化後的影象塊記作y,且其標準尺寸設定為2×2,那麼就需要將輸入網格拆分成4份,如圖中紅色線條所示,然後對每一個3×3的子影象塊取maxpooling操作,就可以得到池化後的值了,圖中A、B、C和D分別表示四個子影象塊中元素的最大值。損失函式關於輸入的偏導數公式如下,

其中,r表示候選區域的索引,j表示池化後圖像塊y中的元素索引, i ( r , j ) 表示y中第j個元素對應到影象塊x中的索引,比如y中的元素A,對應到x中即是 x 2 , 1 ,所以 ( L ) x 2 , 1 = ( L ) y 1 , 1 ( L ) x 1 , 5 = ( L ) y 1 , 2 ( L ) x 6 , 3 = ( L ) y 2 , 1 ( L ) x 5 , 5 = ( L ) y 2 , 2 ,L關於x中其它元素的偏導數均為0。

Faster R-CNN

  在2016年,微軟研究院的學者們提出了新的目標檢測演算法,Faster R-CNN,顧名思義,它是Fast R-CNN模型的改進版,因為Fast-RCNN使用了“selective search”策略生成初始候選區域,具體來說,該策略基於人工的淺層特徵,採用貪婪的思想合併超畫素,從而得到一些候選區域,這種方法的時間複雜度比較高,在單cpu上處理一幅影象耗時2秒。Faster R-CNN之所以快,就是因為引入了“Region Proposal Network”來自動生成候選區域,計算複雜度明顯降低。

Faster R-CNN網路結構

  Faster R-CNN網路模型包括了兩個基本網路,RPN(Region Proposal Networks)網路和Fast R-CNN網路,前者負責生成候選區域,後者負責目標定位和識別。Faster R-CNN網路模型的結構圖如下,


其中,RPN網路包括conv layers和proposals部分,Fast R-CNN網路包括conv layers、RoI pooling和classifier部分。從網路結構上來看,Faster R-CNN和Fast R-CNN結構非常相似,區別在於,前者從feature maps中自動提取出目標候選區域,並把生成的目標區域對映到feature maps上面,而後者是從初始輸入影象image中提取候選區域,然後將其直接對映到feature maps上面,下面介紹RPN網路是如何生成候選區域,並傳遞給Fast R-CNN網路的。

RPN網路

  RPN網路是一個全卷積網路(fully convolutional network),它可以同時預測出輸入影象的每一個畫素的object bounds和objectness scores,’object bounds’表徵的是以當前畫素為中心的一個目標區域,’objectness scores’表徵的是當前目標區域屬於每一個類別的概率。這裡順便提及一下什麼叫全卷積網路,通常的卷積網路是對輸入一幅影象,輸出一個class標籤,主要用於影象分類任務中,而全卷積網路的輸入影象和輸出影象的尺寸是相同的,也就是說,輸出影象中的畫素和輸入影象中的畫素存在一一對映關係,主要用於影象分割(semantic segmention)任務中。論文中的網路結構圖比較抽象,這裡就借用另一篇部落格上的一幅圖進行闡述(參考資料中有引用),

  在具體介紹RPN網路的前向傳播過程之前,需要解釋一個新的概念,什麼是’anchor’?論文中針對anchor的概念給出了下圖,


  ‘anchors’是一些reference boxes’,每個畫素點都有若干個anchors,比如圖中紅色正方形中心的畫素,如果選擇3種不同尺度和3種長寬比,就會得到k=9個anchors,所以對於大小為W×H的feature map,總共有WHk個anchors。但是,這裡要強調的一點是,這些anchors是人為假定的,RPN模型預測出的k個候選區域分別是關於這k個參考boxes的函式,而這些anchors並不作為RPN子網路的輸入影象塊。 可能大家會想,既然不作為輸入,為什麼還要引入anchors這一概念呢?因為你想生成候選區域,至少得告訴設計的網路模型要生成多少個候選區域吧,這裡還有一點需要說明一下,從損失函式的角度來講,RPN模型的目的就是對於每一個畫素的每一個anchor,使預測出的候選區域儘量逼近該anchor