1. 程式人生 > >目標檢測(二)——Fast R-CNN

目標檢測(二)——Fast R-CNN

學習Fast R-CNN之前我們先了解一下SPP-Net網路

SPP-net

SPP-net(Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition, He et al. 2014)提出的起因是解決影象分類中要求輸入圖片固定大小的問題,但是SPP-net中所提出的空間金字塔池化層(Spatial Pyramid Pooling Layer, SPP)可以和R-CNN結合在一起並提升其效能。採用深度學習模型解決影象分類問題時,往往需要影象的大小固定(比如224×224224×224),這並不是CNN層的硬性要求,主要原因在於CNN層提取的特徵圖最後要送入全連線層(如softmax層),對於變大小圖片,CNN層得到的特徵圖大小也是變化的,但是全連線層需要固定大小的輸入,所以必須要將圖片通過resize, crop或wrap等方式固定大小(訓練和測試時都需要)。但是實際上真實的圖片的大小是各種各樣的,一旦固定大小可能會造成影象損失,從而影響識別精度。為了解決這個問題,SSP-net在CNN層與全連線層之間插入了空間金字塔池化層來解決這個矛盾。

 現在的問題是每個Region Proposal的尺度不一樣,直接這樣輸入全連線層肯定是不行的,因為全連線層輸入必須是固定的長度。SPP-NET恰好可以解決這個問題。

     

    由於傳統的CNN限制了輸入必須固定大小(比如AlexNet是224x224),所以在實際使用中往往需要對原圖片進行crop或者warp的操作:     - crop:擷取原圖片的一個固定大小的patch     - warp:將原圖片的ROI縮放到一個固定大小的patch

   無論是crop還是warp,都無法保證在不失真的情況下將圖片傳入到CNN當中:    - crop:物體可能會產生截斷,尤其是長寬比大的圖片。    - warp:物體被拉伸,失去“原形”,尤其是長寬比大的圖片

   SPP為的就是解決上述的問題,做到的效果為:不管輸入的圖片是什麼尺度,都能夠正確的傳入網路。    具體思路為:CNN的卷積層是可以處理任意尺度的輸入的,只是在全連線層處有限制尺度——換句話說,如果找到一個方法,在全連線層之前將其輸入限制到等長,那麼就解決了這個問題。

   具體方案如下圖所示:

   

    如果原圖輸入是224x224,對於conv5出來後的輸出,是13x13x256的,可以理解成有256個這樣的filter,每個filter對應一張13x13的activation map。如果像上圖那樣將activation map pooling成4x4 2x2 1x1三張子圖,做max pooling後,出來的特徵就是固定長度的(16+4+1)x256那麼多的維度了。如果原圖的輸入不是224x224,出來的特徵依然是(16+4+1)x256;直覺地說,可以理解成將原來固定大小為(3x3)視窗的pool5改成了自適應視窗大小,視窗的大小和activation map成比例,保證了經過pooling後出來的feature的長度是一致的。

    使用SPP-NET相比於R-CNN可以大大加快目標檢測的速度,但是依然存在著很多問題:     (1) 訓練分為多個階段,步驟繁瑣: 微調網路+訓練SVM+訓練訓練邊框迴歸器     (2) SPP-NET在微調網路的時候固定了卷積層,只對全連線層進行微調,而對於一個新的任務,有必要對卷積層也進行微調。(分類的模型提取的特徵更注重高層語義,而目標檢測任務除了語義資訊還需要目標的位置資訊)     針對這兩個問題,RBG又提出Fast R-CNN, 一個精簡而快速的目標檢測框架。

Fast R-CNN

解決的問題: 之所以提出Fast R-CNN,主要是因為R-CNN存在以下幾個問題:

1、訓練分多步。通過上一篇博文我們知道R-CNN的訓練先要fine tuning一個預訓練的網路,然後針對每個類別都訓練一個SVM分類器,最後還要用regressors對bounding-box進行迴歸,另外region proposal也要單獨用selective search的方式獲得,步驟比較繁瑣。

2、時間和記憶體消耗比較大。在訓練SVM和迴歸的時候需要用網路訓練的特徵作為輸入,特徵儲存在磁碟上再讀入的時間消耗還是比較大的。

3、測試的時候也比較慢,每張圖片的每個region proposal都要做卷積,重複操作太多。

基於VGG16的Fast RCNN演算法在訓練速度上比RCNN快了將近9倍,比SPPnet快大概3倍;測試速度比RCNN快了213倍,比SPPnet快了10倍。在VOC2012上的mAP在66%左右。

演算法概要: 演算法的主網路還是VGG16,按訓練過程和測試過程來講會清晰點。

訓練的過程:  輸入是224*224,經過5個卷積層和2個降取樣層(這兩個降取樣層分別跟在第一和第二個卷積層後面)後,進入ROIPooling層,該層是輸入是conv5層的輸出和region proposal,region proposal的個數差不多2000。然後再經過兩個都是output是4096的全連線層。最後分別經過output個數是21和84的兩個全連線層(這兩個全連線層是並列的,不是前後關係),前者是分類的輸出,代表每個region proposal屬於每個類別(21類)的得分,後者是迴歸的輸出,代表每個region proposal的四個座標。最後是兩個損失層,分類的是softmaxWithLoss,輸入是label和分類層輸出的得分;迴歸的是SmoothL1Loss,輸入是迴歸層的輸出和target座標及weight。

測試的過程:  與訓練基本相同,最後兩個loss層要改成一個softma層,輸入是分類的score,輸出概率。最後對每個類別採用NMS(non-maximun suppression)。

詳解:

ROI pooling:ROI Pooling的作用是對不同大小的region proposal,從最後卷積層輸出的feature map提取大小固定的feature map。簡單講可以看做是SPPNet的簡化版本,因為全連線層的輸入需要尺寸大小一樣,所以不能直接將不同大小的region proposal對映到feature map作為輸出,需要做尺寸變換。在文章中,VGG16網路使用H=W=7的引數,即將一個h*w的region proposal分割成H*W大小的網格,然後將這個region proposal對映到最後一個卷積層輸出的feature map,最後計算每個網格里的最大值作為該網格的輸出,所以不管ROI pooling之前的feature map大小是多少,ROI pooling後得到的feature map大小都是H*W。

因此可以看出Fast RCNN主要有3個改進:

1、卷積不再是對每個region proposal進行,而是直接對整張影象,這樣減少了很多重複計算。原來RCNN是對每個region proposal分別做卷積,因為一張影象中有2000左右的region proposal,肯定相互之間的重疊率很高,因此產生重複計算。

2、用ROI pooling進行特徵的尺寸變換,因為全連線層的輸入要求尺寸大小一樣,因此不能直接把region proposal作為輸入。

3、將regressor放進網路一起訓練,每個類別對應一個regressor,同時用softmax代替原來的SVM分類器。

畫一畫重點: R-CNN有一些相當大的缺點(把這些缺點都改掉了,就成了Fast R-CNN)。 大缺點:由於每一個候選框都要獨自經過CNN,這使得花費的時間非常多。 解決:共享卷積層,現在不是每一個候選框都當做輸入進入CNN了,而是輸入一張完整的圖片,在第五個卷積層再得到每個候選框的特徵

原來的方法:許多候選框(比如兩千個)-->CNN-->得到每個候選框的特徵-->分類+迴歸 現在的方法:一張完整圖片-->CNN-->得到每張候選框的特徵-->分類+迴歸

所以容易看見,Fast RCNN相對於RCNN的提速原因就在於:不過不像RCNN把每個候選區域給深度網路提特徵,而是整張圖提一次特徵,再把候選框對映到conv5上,而SPP只需要計算一次特徵,剩下的只需要在conv5層上操作就可以了。

在效能上提升也是相當明顯的:

 

總結: Fast RCNN將RCNN眾多步驟整合在一起,不僅大大提高了檢測速度,也提高了檢測準確率。其中,對整張影象卷積而不是對每個region proposal卷積,ROI Pooling,分類和迴歸都放在網路一起訓練的multi-task loss是演算法的三個核心。另外還有SVD分解等是加速的小貢獻,資料集的增加時mAP提高的小貢獻。  當然Fast RCNN的主要缺點在於region proposal的提取使用selective search,目標檢測時間大多消耗在這上面(提region proposal 2~3s,而提特徵分類只需0.32s),這也是後續Faster RCNN的改進方向之一。

參考資料