目標檢測之R-CNN系列
Object Detection,在給定的影象中,找到目標影象的位置,並標註出來。 或者是,影象中有那些目標,目標的位置在那。這個目標,是限定在資料集中包含的目標種類,比如資料集中有兩種目標:狗,貓。 就在影象找出來貓,狗的位置,並標註出來 是狗還是貓。
這就涉及到兩個問題:
- 目標識別,識別出來目標是貓還是狗,Image Classification解決了影象的識別問題。
- 定位,找出來貓狗的位置。
R-CNN
2012年AlexNet在ImageNet舉辦的ILSVRC中大放異彩,R-CNN作者受此啟發,嘗試將AlexNet在影象分類上的能力遷移到PASCAL VOC的目標檢測上。這就要解決兩個問題:
- 如何利用卷積網路去目標定位
- 如何在小規模的資料集上訓練出較好的網路模型。
對於問題,R-CNN利用候選區域的方法(Region Proposal),這也是該網路被稱為R-CNN的原因:Regions with CNN features。對於小規模資料集的問題,R-CNN使用了微調的方法,利用AlexNet在ImageNet上預訓練好的模型。
R-CNN目標檢測的思路:
- 給定一張圖片,從圖片中選出2000個獨立的候選區域(Region Proposal)
- 將每個候選區域輸入到預訓練好的AlexNet中,提取一個固定長度(4096)的特徵向量
- 對每個目標(類別)訓練一SVM分類器,識別該區域是否包含目標
- 訓練一個迴歸器,修正候選區域中目標的位置:對於每個類,訓練一個線性迴歸模型判斷當前框是不是很完美。
下圖給出了,R-CNN的目標檢測過程

訓練
R-CNN進行目標檢測的訓練流程:
- 使用區域生成演算法,生成2000個候選區域,這裡使用的是Selective search.
- 對生成的2000個候選區域,使用預訓練好的AlexNet網路進行特徵提取。
- 將候選區域變換到網路需要的尺寸( \(227 \times 227\) )。 在進行變換的時候,在每個區域的邊緣新增 \(p\) 個畫素,也就是手工的添加個邊框,設定 \(p = 16\) 。
- 改造預訓練好的AlexNet網路,將其最後的全連線層去掉,並將類別設定為21(20個類別,另外一個類別代表背景).
這樣一個候選區域輸入到網路中,最終得到一個 \(4096 \times 21\) 的特徵。
- 利用上面提取到的候選區域的特徵,對每個類別訓練一個SVM分類器(而分類)來判斷,候選框裡物體的類別,是給類別就是positive,不是就是negative。比如,下圖針對狗的SVM分類器
狗的SVM分類器,就要能判斷出某個候選區域是不是包含狗,包含狗了那就是Positive;不包含就是Negative.這裡有個問題是,假如候選區域只是框出來了某個類的一部分,那要怎麼來標註這個區域呢。在R-CNN中,設定一個IOU的閾值,如果該區域與Ground truth的IOU低於該閾值,就將給區域設定為Negative。閾值設定為0.3。
- 對於面只是得到了每個候選框是不是包含某個目標,其得到的區域位置不是很準確。這裡需要再訓練一個線性迴歸模型判斷,候選區域框出的目標是不是完美。對於某個類別的SVM是Positive的候選區域,來判斷其框的目標區域是不是很完美。
測試
從一張圖片中提取2000個候選區域,將每個區域按照訓練時候的方式進行處理,輸入到SVM中進行正負樣本的識別,並使用候選框迴歸器,計算出每個候選區域的分數。
候選區域較多,有2000個,所有很多重疊的部分,就需要剔除掉重疊的部分。
針對每個類,通過計算IOU,採取非最大值抑制的方法,以最高分的區域為基礎,刪掉重疊的區域。
缺點
- 訓練分為多個步驟,比較繁瑣。 需要微調CNN網路提取特徵,訓練SVM進行正負樣本分類,訓練邊框迴歸器得到正確的預測位置。
- 訓練耗時,中間要保持候選區域的特徵,5000張的圖片會生成幾百G的特徵檔案。
- 速度慢
- SVM分類器和邊框迴歸器的訓練過程,和CNN提取特徵的過程是分開的,並不能進行特徵的學些更新。
Fast R-CNN
R-CNN雖然取得了不錯的成績,但是其缺點也很明顯。Ross Girshick在15年推出Fast RCNN,構思精巧,流程更為緊湊,大幅提升了目標檢測的速度。同樣使用最大規模的網路,Fast RCNN和RCNN相比,訓練時間從84小時減少為9.5小時,測試時間從47秒減少為0.32秒。在PASCAL VOC 2007上的準確率相差不大約在66%-67%之間。
Fast RCNN主要是解決RCNN的問題的
- 測試訓練速度慢,主要是提取候選區域的特徵慢
R-CNN首先從測試圖中提取2000個候選區域,然後將這2000個候選區域分別輸入到預訓練好的CNN中提取特徵。由於候選區域有大量的重疊,這種提取特徵的方法,就會重複的計算重疊區域的特徵。在Fast-RCNN中,將整張圖輸入到CNN中提取特徵,在鄰接時在對映到每一個候選區域,這樣只需要在末尾的少數層單獨的處理每個候選框。 - 訓練需要額外的空間儲存提取到的特徵資訊
RCNN中需要將提取到的特徵儲存下來,用於為每個類訓練單獨的SVM分類器和邊框迴歸器。在Fast-RCNN中,將類別判斷和邊框迴歸統一的使用CNN實現,不需要在額外的儲存特徵。
Fast R-CNN的結構
輸入是整幅影象和多個感興趣區域(ROI)的位置資訊,在前面的網路層中並不會處理ROI資訊,在後面的RoI pooling layer中,將每個RoI池化到固定大小的特徵圖中,然後通過全連線層提取特徵。最後通過將提取的每個RoI特徵輸入到SoftMax分類器已經邊框迴歸器中,完成目標定位的端到端的訓練。
Fast R-CNN網路將整個影象和一組候選框作為輸入。網路首先使用幾個卷積層(conv)和最大池化層來處理整個影象,以產生卷積特徵圖。然後,對於每個候選框,RoI池化層從特徵圖中提取固定長度的特徵向量。每個特徵向量被送入一系列全連線(fc)層中,其最終分支成兩個同級輸出層 :一個輸出個類別加上1個背景類別的Softmax概率估計,另一個為個類別的每一個類別輸出四個實數值。每組4個值表示個類別的一個類別的檢測框位置的修正。
ROI 池化層
ROI池化層前面的網路層是對整幅影象提取特徵得到多個Feature Map。ROI池化層的輸入就是這多個Feature Map以及多個ROI(候選區域),這裡的ROI是一個矩形框,由其左上角的座標以及寬高組成的四元組 \((r,c,h,w)\) 定義。
ROI池化層使用 最大池化 將輸入的Feature Map中的任意區域(ROI對應的區域)內的特徵轉化為固定的 \(H \times W\) 的特徵圖,其中 \(H\) 和 \(W\) 是超引數。 對於任意輸入的 \(h \times w\) 的ROI,將其分割為 \(H \times W\) 的子網格,每個子網格的大小為 \(\frac{h}{H} \times \frac{w}{W}\) 。如下,取得 \(2\times 2\) 的特徵圖
- 輸入的Feature Map
- ROI投影到Feature Map上的左上角的座標為 \((0,3)\) ,寬高為 \((7,5)\) ,在Feature Map上位置如下
- 對每個子網格做最大池化操作
ROI池化層的池化操作同標準的池化操作是一樣的,每個通道都單獨執行。
預訓練網路
通過ROI池化層可以從整幅影象的特徵圖中得到每個ROI的特徵圖(固定大小),而整幅影象的特徵圖則使用預訓練的網路提取得到。對於預訓練完成的網路要做如下的修改:
- 使用ROI池化層代替預訓練網路的最後的池化層,並將超參 \(H,W\) 設定為和網路第一個全連線相容的值,例如VGG16,設 \(H = W = 7\) 。
- 原網路的最後一個全連線層替換為兩個同級層: \(K + 1\) 個類別的SoftMax分類層和類別的邊框迴歸層。
- 網路的輸入修改為兩個:影象的列表以及相對應的ROI的列表
訓練微調
R-CNN中的特徵提取和檢測部分是分開進行的,使用檢測樣本進行訓練的時候無法更新特徵提取部分的引數。SPPnet也不能更新金字塔層前面的卷積層權重,這是因為當批量訓練的樣本來自不同的圖片時,,反向傳播通過SPP層時十分低效。Fast R-CNN則可以使用反向傳播的方法更新整個網路的引數。
Fast R-CNN提出一個高效的訓練方法,可以在訓練過程中發揮特徵共享的優勢。在Fast R-CNN訓練過程中隨機梯度下降(SGD)的mini-batch是分層取樣的,首先取 \(N\) 張影象,然後從每張圖片取樣 \(\frac{R}{N}\) 個RoI。來自同一張圖片的RoI在前向和後向傳播中共享計算和記憶體。這樣就可以減少mini-batch的計算量。例如 \(N=2,R=128\) ,這個訓練模式大概比從128個不同的影象取樣1個RoI(這就是R-CNN和SPPnet的訓練方式)要快64倍。
該策略一個問題是會導致收斂起來比較慢,因為來自同一張圖片的RoI是相關的。但它在實際中並沒有成為一個問題,我們的使用 \(N=2,R=128\) 達到了很好的成績,只用了比R-CNN還少的SGD迭代。
Multi-task Loss
Fast R-CNN有兩種輸出:
- 分類的Softmax輸出,對於每個RoI輸出一個概率, \(p = {p_0,p_1,\dots,p_k}\) , \(k + 1\) 個類,包括一個背景類別。
- 邊框迴歸: \(t^k = (t_x^k,t_y^k,t_w^k,t_h^k)\) 。 其中, \(k\) 類別的索引, \(t_x^k,t_y^k\) 是相對於候選區域尺度不變的平移, \(t_w^k,t_h^k\) 相對於候選區域對數空間的位移。
將上面的兩個任務的需要色損失函式放在一起
\[ L(p,u,t^u,v) = L_{cls}(p,u) + \lambda [u \ge 1]L_{Ioc}(t^u,v) \]
其中, \(L_{cls}(p,u)\) 是分類的損失函式, \(p_u\) 是class u的真實分類的概率。這裡,約定 \(u = 0\) 表示背景,不參與邊框迴歸的損失計算。
\[ L_{cls}(p,u) = -\log (p_u) \]
\(L_{Ioc}(t^u,v)\) 是邊框迴歸的損失函式,
\[ \begin{align*} L_{Ioc}(t^u,v) &= \sum_{i \in {x,y,w,h}}smooth_{L_1}(t_i^u - v) \end{align*} \]
其中, \(u\) 表示類別, \(t^u\) 表示預測邊框的偏移量(也就是預測邊框進行 \(t^u\) 偏移後,能夠和真實邊框最接近), \(v\) 表示預測邊框和實際邊框之間真正的偏移量
\[ smooth_{L_1}(x) = \left\{ \begin{array}{cc} 0.5 x^2 & if |x| < 1 \\ |x|-0.5 & otherwise\end{array}\right. \]
這裡 \(smooth_{L_1}(x)\) 中的 \(x\) 為真實值和預測值座標對應值的差值,該函式在 \((-1,1)\) 之間為二次函式,在其他位置為線性函式,Fast RCNN作者表示作者表示這種形式可以增強模型對異常資料的魯棒性。其函式曲線如下圖

關於邊框的修正後面單獨詳述。
Truncated SVD for faster detection
在進行目標檢測時,需要處理的RoI的個數較多,幾乎一半的時間花費在全連線層的計算上。就Fast R-CNN而言,RoI池化層後的全連線層需要進行約2k次,因此在Fast R-CNN中可以採用SVD分解加速全連線層計算。
設全連線層的輸入為 \(X\) ,權值矩陣為 \(W_{u\times v}\) ,輸出為 \(Y\) ,則全連線層的實際上的計算是一個矩陣的乘法
\[ Y = W \cdot X \]
可以將權值矩陣 \(W\) 進行奇異值分解(SVD分解),使用其前 \(t\) 個特徵值近似代替該矩陣
\[ W \approx U \Sigma_t V^T \]
其中, \(U\) 是 \(u \times t\) 的左奇異矩陣, \(\Sigma_t\) 是 \(t \times t\) 的對角矩陣, \(V\) 是 \(v \times t\) 的右奇異矩陣。
截斷SVD將引數量由原來的 \(u \times v\) 減少到 \(t \times (u + v)\) ,當 \(t\) 遠小於 \(min(u,v)\) 的時候降低了很大的計算量。
在實現時,相當於把一個全連線層拆分為兩個全連線層,第一個全連線層使用權值矩陣 \(\Sigma_t V^T\)(不含偏置),第二個全連線層使用矩陣
\(U\)
(含偏置).當RoI的數量大時,這種簡單的壓縮方法有很好的加速
Summary
Fast R-CNN是對R-CNN的一種改進
- 卷積不再是對每個region proposal進行,而是直接對整張影象,這樣減少了很多重複計算。原來RCNN是對每個region proposal分別做卷積,因為一張影象中有2000左右的region proposal,肯定相互之間的重疊率很高,因此產生重複計算。
- 用ROI pooling進行特徵的尺寸變換,因為全連線層的輸入要求尺寸大小一樣,因此不能直接把region proposal作為輸入
- 將regressor放進網路一起訓練,每個類別對應一個regressor,同時用softmax的全連線層代替原來的SVM分類器。
Faster R-CNN
在Fast R-CNN中使用的目標檢測識別網路,在速度和精度上都有了不錯的結果。不足的是,其候選區域提取方法耗時較長,而且和目標檢測網路是分離的,並不是end-to-end的。在Faster R-CNN中提出了區域檢測網路(Region Proposal Network,RPN),將候選區域的提取和Fast R-CNN中的目標檢測網路融合到一起,這樣可以在同一個網路中實現目標檢測。

Faster R-CNN的網路有4部分組成:
- Conv Layers 一組基礎的CNN層,由Conv + Relu + Pooling組成,用於提取輸入影象的Feature Map。通常可以選擇有5個卷積層的ZF網路或者有13個卷積層的VGG16。Conv Layers提取的Feature Map用於RNP網路生成候選區域以及用於分類和邊框迴歸的全連線層。
- RPN,區域檢測網路 輸入的是前面卷積層提取的Feature Map,輸出為一系列的候選區域。
- RoI池化層 輸入的是卷積層提取的Feature Map 和 RPN生成的候選區域RoI,其作用是將Feature Map 中每一個RoI對應的區域轉為為固定大小的 \(H \times W\) 的特徵圖,輸入到後面的分類和邊框迴歸的全連線層。
- 分類和邊框迴歸修正 輸入的是RoI池化後RoI的 \(H \times W\) 的特徵圖,通過SoftMax判斷每個RoI的類別,並對邊框進行修正。
其整個工作流程如下:
- 將樣本影象整個輸入到Conv Layers中,最後得到Feature Map。
- 將該Feature Map輸入到RPN網路中,提取到一系列的候選區域
- 然後由RoI池化層提取每個候選區域的特徵圖
- 將候選區域的特徵圖輸入到用於分類的Softmax層以及用於邊框迴歸全連線層。
Faster R-CNN的4個組成部分,其中Conv Layers,RoI池化層以及分類和邊框迴歸修正,和Fast R-CNN的區別不是很大,其重大改進就是使用RPN網路生成候選區域。
卷積層 Conv Layers
前面的卷積層用於提取輸入影象的特徵,生成Feature Map。這裡有VGG-16為例,Conv layers部分共有13個conv層,13個relu層,4個pooling層。在VGG中,
- 所有的卷積層都使用 \(3\times3\) 的卷積核,步長為1,並對邊緣做了填充 \(padding=1\) 。這樣對於輸入 \(W \times W\) 的影象,通過卷積後,其輸出尺寸為 \((W - 3 + 2 * padding) / 1 + 1 = W\) ,也就是通過卷積層影象的尺寸並不會變小。
- 池化層都是用 \(2 \times 2\) 的池化單元,步長為2。對於 \(W \times W\) 的影象,通過池化層後,其輸出的尺寸為 \((W - 2) / 2 + 1 = W / 2\) ,也就是通過一個池化層影象的尺寸會變為輸入前的$1 /2 $。
Conv Layers的13個conv層並不會改變影象的尺寸,而有4個池化層,每個池化層將輸入縮小為原來的 \(1/2\) ,則對於 \(W \times W\) 的輸入,Conv Layers輸出的Feature Map的寬和高為 \(W / 16 \times W /16\) ,也就是輸入尺寸的 \(1/16\) 。 有了這個Feature Map相對於原始輸入影象的寬高比例,就可以計算出Feature Map中的每個點對應於原圖的區域。
由於池化層的降取樣,Feature Map中的點映射回原圖上,對應的不是某個畫素點,而是矩形區域。
區域檢測網路 RPN
區域提議網路(RPN)以任意大小的影象作為輸入,輸出一組矩形的候選區域,並且給每個候選區域打上一個分數。如下圖

RPN輸入的是前面Conv Layers提取影象的Feature Map,輸出有兩部分:
- 候選區域的位置資訊(一個4維元組)
- 候選區域對應的類別(二分類,背景還是前景)。
為了得到上述的兩種輸出,要從輸入的Feature Map上得到兩種資訊:
- 候選區域在原始輸入影象的位置資訊
- 每個候選區域對應的Feature Map,用於分類。
Anchor
前面提到由於池化層的降取樣,Feature Map中的點映射回原圖上,對應的不是某個畫素點,而是矩形區域。很簡單的,可以將Feature Map中的每個點映射回原始影象,就可以得到一個候選區域,但是這樣得到的區域太過於粗糙,顯然是不行的。Faster R-CNN使用的是 將每個Feature Map中的點對映到原圖上,並以對映後的位置為中心,在原圖取不同形狀和不同面積的矩形區域,作為候選區域。 論文中提出了 Anchor 的概念來表示這種取候選區域的方法:一個 Anchor 就是Feature Map中的一個點,並有一個相關的尺度和縱橫比。說白了, Anchor 就是一個候選區域的引數化表示,有了中心點座標,知道尺寸資訊以及縱橫比,很容易通過縮放比例在原圖上找到對應的區域。
在論文中為每個Anchor設計了3種不同的尺度 \({128\times 128,256 \times 256,512 \times 512}\) ,3種形狀,也就是不同的長寬比 \(W:H = {1:1,1:2,2:1}\) ,這樣Feature Map中的點就可以組合出來9個不同形狀不同尺度的Anchor。下圖展示的是這9個Anchor對應的候選區域:

現假設輸入到Conv Layers的影象尺寸為 \(800 \times 600\) ,通過VGG16的下采樣縮小了16倍,則最終生成的Feature Map的尺寸為
\[ ceil(800/16) \times ceil(600 /16 ) = 50 \times 38 \]
有Feature Map的一個點
\((5,5)\)
,以該點為Anchro,生成不同的候選區域
- 首先將該點映射回原圖的座標為 \((5 \times 16,5 \times 16) = (90,90)\)
- 選擇一個形狀和麵積的組合,例如尺度為 \(128 \times 128\) ,形狀為 \(W:H = 1:1\)
- 在原圖上以 \((90,90)\) 為中心,計算符合上述形狀的區域的座標 \((x_1,y_1,x_2,y_2)=(36,36,154,154)\) :
\[ \begin{align*} x_1 &= 90 - 128 / 2 = 90 - 64 = 36 \\ x_2 &= 90 + 128 / 2 = 90 + 64 = 154 \\ y_1 &= 90 - 128 / 2 = 90 - 64 = 36 \\ y_2 &= 90 + 128 / 2 = 90 + 64 = 154 \end{align*} \]
上面就得到了位置為 \((5,5)\) ,尺度為 \(128 \times 128\) ,形狀為 \(W:H = 1:1\) 的Anchor在原圖上取得的候選區域。
只有區域資訊也不行啊,這些區域有可能是前景也有可能是背景,這就需要提取這些區域對應的特徵資訊,用於分類。對於VGG16,其最終生成的特徵圖有512個通道,也就是每個點都可以得到一個512維的特徵,將這個特徵作為該點為Anchor生成的區域特徵,用於分類。 論文中,是在特徵圖上做一個 \(3 \times 3\) 的卷積,融合了周圍的資訊。
設Feature Map的尺度為 \(W \times H\) ,每個點上生成k個Anchor( \(k = 9\) ),則總共可以得到 \(WHk\) 個Anchors。而每個Anchor即可能是前景也可能是背景,則需要Softmax層 \(cls = 2k\) scores;並且每個anchor對應的候選區域相對於真實的邊框有$(x,y,w,y) \(4個偏移量,這就需要邊框迴歸層\) reg = 4k$ coordinates。
訓練
每個anchor即可能包含目標區域,也可能沒有目標。 對於包含目標區域的anchor分為positive label,論文中規定,符合下面條件之一的即為positive樣本:
- 與任意GT區域的IoU大於0.7
- 與GT(Groud Truth)區域的IoU最大的anchor(也許不到0.7)
和任意GT的區域的IoU都小於0.3的anchor設為negative樣本,對於既不是正標籤也不是負標籤的anchor,以及跨越影象邊界的anchor就直接捨棄掉。
由於一張影象能夠得到 \(WHk\) 個Anchors,顯然不能將所有的anchor都用於訓練。在訓練的時候從一幅影象中隨機的選擇256個anchor用於訓練,其中positive樣本128個,negative樣本128個。
關於邊框迴歸的具體內容,由於本文內容過多,這裡不再說明,單獨另寫。
summary
本文就R-CNN的系列文章進行了一個大致的梳理,從R-CNN初次將CNN應用於目標檢測,到最終的Faster R-CNN通過一個CNN網路完成整個目標檢測的演變過程。下圖總結下三個網路

上表格引用自 Faster R-CNN論文筆記——FR