Fast R-CNN論文解讀

論文鏈接:https://arxiv.org/abs/1504.08083
代碼鏈接:https://github.com/rbgirshick/fast-rcnn.

Abstract

這篇論文提出了一種基於卷積神經網絡做目標檢測的算法——Fast R-CNN,它是建立在之前R-CNN的基礎上使用深度卷積神經網絡進行高效的目標檢測。Fast R-CNN做了幾點創新來提高訓練和測試階段的速度,同時提高了檢測的準確率。

  1. Fast R-CNN使用的是VGG16網絡,訓練速度比R-CNN快了9倍,測試速度快了213倍,並且在PASCAL VOC 2012上實現了更高的map;
  2. 與SSPnet相比,Fast R-CNN訓練速度快了3倍,測試速度快了10倍,並且準確率更高;

1. Introduction

目前深度神經網絡已經極大的提高了圖形分類和目標檢測的精度,與圖像分類相比,目標檢測明顯更爲複雜,現在的方法在訓練網絡時會分多個階段,這樣會導致訓練和運行時間過長。

目前檢測有兩個最基本的挑戰:

  1. 如何產生候選框;
  2. 候選框只是提供了一個粗略的定位範圍,所以需要進一步的修正纔可以得到更精確的定位,這意味着我們的方法需要在速度、精度和簡單性之間做權衡;

在本片論文中,我們簡化了訓練過程,提出了以一種單階段的訓練算法——分類和邊框迴歸的loss合併,梯度回傳。

1.1 R-CNN and SPPnet

在談Fast R-CNN之前,我們先來說說R-CNN存在的問題:

  1. 訓練分多步。通過上一篇博文我們知道R-CNN的訓練先要fine tuning一個預訓練的網絡,然後針對每個類別都訓練一個SVM分類器,最後還要對每個類別用regressor模型對bounding-box進行迴歸(分類和邊框預測是分開的,但實際上兩者之間是有聯繫的,是個待解決問題),另外region proposal也要單獨用selective search的方式獲得,步驟比較繁瑣。
  2. 時間和內存消耗比較大。在訓練SVM和迴歸的時候分別需要用網絡訓練得到的fc7和pool5層的特徵作爲輸入,特徵保存在磁盤上再讀入的時間消耗還是比較大的。舉個例子,當使用深度神經網絡(如VGG16),對於5k張VOV07訓練集上的圖片做訓練大約需要2.5GPU-days。這些特徵需要上千GB的存儲空間。
  3. 測試的時候也比較慢,每張圖片的每個region proposal都要做卷積,重複操作太多。用VGG16做檢測一張圖片需要47s。

制約R-CNN速度的一個重要因素在於每個候選框(大約2000個)都需要經過卷積神經網絡,這裏面沒有共享計算,裏面有大量的冗餘計算(有很多重疊部分)。空間金字塔層池化網絡(Spatial pyramid pooling networks,SSPnets)可以通過計算共享來加速R-CNN,SSPnet是先對整張圖片做卷積,由於卷積池化之後得到的特徵圖與原圖片的特徵位置是相對應的,所以直接在特徵圖上截取候選框,然後再使用做不同尺寸的最大池化將得到的特徵向量拼接得到最終的特徵向量。SSPnet相比於R-CNN測試速度加速了10-100倍,訓練時間較少了3倍。
在這裏插入圖片描述
但SSPnet也有和R-CNN類似的缺點,訓練過程是一個多階段的,涉及特徵提取、使用交叉熵損失函數調優、訓練SVM,最後再做邊框迴歸,特徵向量需要寫入磁盤。但是不像R-CNN,在SSPnet中的調優算法不能更新金字塔池化層之前的卷積層,不出意料,這使得我們網絡的準確率受限很嚴重。

1.2 共享

我們提出了一種新的訓練算法 ,它結合了R-CNN和SSPnet的優勢,在提高速度的同時提高了精度。我們將這種方法叫做Fast R-CNN,它具有以下優勢:

  1. 比SSPnet和R-CNN都高的map;
  2. 訓練是單階段的,使用了一個多任務的loss;
  3. 訓練可以更新所有層的參數;
  4. 特徵緩存不需要磁盤存儲;

2. Fast R-CNN architecture and training

在這裏插入圖片描述
Figure1展示了Fast R-CNN的結構,其輸入爲整張圖片和使用SS算法提取的2000個候選框的信息array([r, c, h, w]),其中(r, c)爲某個region左上角的座標,(h, w)爲它的高和寬。下圖表示了一個圖片中的候選框經過一次卷積核池化之後的(r, c, w, h)的變化關係這說明我們根據2000個候選框的信息完全可以在經過多層卷積和池化之後的特徵圖上得到我們對應的候選框。

邊和點映射的具體細節可以參加這篇文章:https://zhuanlan.zhihu.com/p/60919662
在這裏插入圖片描述接着由於這些候選框大小不一,我們將其送入ROI層(單層金字塔池化)得到統一維度的特徵向量,之後再過兩個全連接層(4096個神經元)接入兩個分支,一個分支爲(K+1)個神經元的FC層+softmax,這裏的K指的是類別數;第二個分支爲4個神經元的FC層,做迴歸。

2.1 The RoI pooling layer

RoI最大池化層就是將原來尺寸爲 h x w的RoI窗口劃分爲 H x W的網格大小,然後在每個小格子範圍內通道獨立的做最大池化得到 維度爲H x W x 通道數的特徵。

2.2 Initializing from pre-trained networks

作者使用有5個最大池化層和5到13個不等的卷積層的三種網絡進行預訓練:CaffeNet,VGG_CNN_M_1024,VGG-16,使用這些網絡初始化Fast R-CNN前,需要以下修改:

  1. 用RoI pooling layer取代網絡的最後一個池化層;
  2. 最後一個FC層和softmax被替換成fast R-CNN框架圖介紹的兩個並列層;
  3. 輸入兩組數據到網絡:一組圖片和每一個圖片的一組RoIs;

2.3 Fine-tuning for detection

爲什麼SPPnet不能更新金字塔池化之前的卷積池化的參數?論文中提到當每個訓練樣本(即RoI)來自不同的圖像時,通過SPP層的反向傳播非常低效。低效源於每個RoI可能具有非常大的感受野(接收區),通常包括整個輸入圖像。由於正向傳播必須處理整個感受野,訓練輸入是非常大(通常是整個圖像)。

我們提出了一種更加高效的訓練方法,它可以在訓練中共享特徵。在Fast R-CNN訓練中,一個minibatch的R個RoI來源於N張圖片,即從每張圖片中採樣R/N個RoIs,而來自同一張圖片的RoI在前向和反向傳播中可以貢獻計算和內存,通常N=2,R=128,這樣的訓練方案通常要比從128張不同圖片中採樣快64倍。

另外除了分層採樣,Fast R-CNN將分類、迴歸放在一個網絡中(loss合併),而不像原來那樣單獨訓練分類器、迴歸模型。

Multi-task loss

Fast R-CNN有兩個並列的輸出層,第一個輸出層的輸出的是(K+1)維度的向量,它是由最後一個全連接層的輸出再過一個softmax得到,p=(p0, p1,…,pk),分別代表該RoI屬於背景類、第一類、…、第k類的概率;第二個並列層的輸出邊框迴歸的偏移量,對每個類k都輸出四個偏移量:
在這裏插入圖片描述
對四個偏移量不瞭解參加我的博客:https://blog.csdn.net/h__ang/article/details/89071664

每個RoI都有一個ground-truth class u ( u 不是一個概率分佈,而是一個數字,爲0是代表是背景,爲1-20是代表所屬的類別)和一個ground-truth bounding-box 迴歸目標v。我們的多任務損失由分類損失Lcls和迴歸損失Lloc構成:
在這裏插入圖片描述
其中:
在這裏插入圖片描述
(1)式中的超參數 lamda用來控制兩種任務損失的平衡,我們會對ground-truth regression targets vi歸一化使之均值爲0,方差爲1的,實驗中所有的 lamda = 1.

Mini-batch sampling

每個minibatch包含128個RoIs,來源於兩張圖片(隨機抽取的),即從隨機抽取兩張圖片的同時從每張圖片各抽取64個RoIs。那麼對於每個候選框的類別標籤如何確定呢?如果一個候選框和這張圖片裏面所有的ground truth的IoU都小於0.1,那麼就捨棄掉這個候選框,不會用它作爲樣本(低於0.1的IoU作爲難例挖掘的啓發式);[0.1, 0.5)的作爲負樣本,類別標籤u=0;[0.5, 1]的作爲正樣本,u>=1(如果一個候選框和多個ground truth的IoU都大於等於0.5,那麼該框的類別與IoU最大的groud truth的類別一致)。我們一個minibatch中的128個RoIs有25%是正樣本,75%是負樣本。另外只採用隨機水平翻轉的方式增加數據集。

Back-propagation through RoI pooling layers

先貼一個CNN卷積層和池化層如何進行反向傳播的鏈接:https://blog.csdn.net/legend_hua/article/details/81590979

我們先來假定一些符號:xi表示RoI池化前的特徵圖上的像素點,yrj表示第r個RoI池化後的第j個的像素點,RoI的前向傳播是在做:
在這裏插入圖片描述
i*(r,j)的意思是如果第r個RoI的第j個像素點的來源,它是最大池化時選出的最大的那個點對應的座標;這裏類比到CNN中標準的最大池化層的反向傳播,那它就應該是:
在這裏插入圖片描述
但是由於在這裏,一個RoI池化前的像素點xi可能和多個不同的yrj有映射關係(因爲存在多個候選框,候選框之前可能有重疊),因此反向傳播過程的公式爲:
在這裏插入圖片描述
到了這裏,我想談一下我遇到的坑,前面說到過,迴歸部分的輸出是84個節點,也就是說對於每一個候選框會產生84個輸出,分別代表每一個類的偏移量(21*4=84),那麼就存在一個問題,迴歸時標籤是什麼?也是一個84維度的向量嗎?而這個向量又是如何構造的?這個問題有很多種理解方式,訓練時我們可以把迴歸的真實標籤看作是4維的向量(該候選框與同類的ground-truth之間的偏移和縮放量),而對於每個候選框會輸出一個84維度的向量,在計算迴歸部分的損失函數時,我們選擇性截取該類別的對應的84維向量中的四個值,使用上面的等式(2)計算損失(比如對於類別1我們截取84維向量中的3-7位置上的值);再換個角度理解,真實標籤也可以是84維的向量,可以將其餘80個位置上的量全部置0,而在計算損失函數時根據類別分別截取兩個84維向量中對應部分的值。

SGD超參數

  • 用於分類和迴歸的全連接層的權重按照0爲均值,標準差爲0.01和0.001初始化,偏置都初始化爲0;
  • 在PASCAL VOC 2007和2012訓練時,前30k次迭代全局學習率爲0.001,每層權重學習率爲1倍,偏置學習率爲2倍,後10k次迭代全局學習率更新爲0.0001;
  • 動量設置爲0.9,權重衰減設置爲0.0005;

2.4 尺度不變性

作者提出了使用兩種方式對規模不變的對象進行檢測:brute-force(單一尺度)和image pyramids(多尺度,圖像金字塔)。

單一尺度直接在訓練和測試階段將image預先固定好像素大小,直接輸入網絡訓練就好,然後期望在訓練過程中網絡自己能夠學習到尺度不變性scale-invariance;多尺度在訓練階段隨機從圖像金字塔【縮放圖片的scale得到,得到多尺度圖片,相當於擴充數據集】中採樣訓練,通過一個圖像金字塔向網絡提供一個近似的尺度不變,在測試階段圖像金字塔用來對每個object proposal近似尺度歸一化,訓練階段每次採樣一個圖像就隨機採樣一個金字塔尺度。

作者在5.2節對單一尺度和多尺度分別進行了實驗,不管哪種方式下都定義圖像短邊像素爲s,單一尺度下s=600【維持長寬比進行縮放】,長邊限制爲1000像素;多尺度s={480,576,688,864,1200}【維持長寬比進行縮放】,長邊限制爲2000像素,生成圖像金字塔進行訓練測試;實驗結果表明AlexNet【S for small】、VGG_CNN_M_1024【M for medium】下單一尺度比多尺度mAP差1.2%~1.5%,但測試時間上卻快不少,VGG-16【L for large】下僅單一尺度就達到了66.9%的mAP【由於GPU顯存限制多尺度無法實現】,該實驗證明了深度神經網絡善於直接學習尺度不變形,對目標的scale不敏感。

第2中方法的表現確實比1好,但是好的不算太多,大概是1個mAP左右,但是時間要慢不少,所以作者實際採用的是第一個策略,也就是single scale。

SVD分解

在這裏插入圖片描述圖像分類任務中,用於卷積層計算的時間比用於全連接層計算的時間多;而在目標檢測任務中,要處理的RoI數量比較多,幾乎有一半的前向計算時間被用於全連接層(Fig . 2)。就Fast R-CNN而言,RoI池化層後的全連接層需要進行約2k次(每個RoI都要計算),因此在Fast R-CNN中可以採用SVD分解加速全連接層計算;

實驗結果

在這裏插入圖片描述
參考文章:
https://blog.csdn.net/Wonder233/article/details/53671018
https://zhuanlan.zhihu.com/p/60968116
https://blog.csdn.net/u014380165/article/details/72851319

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章