1 RCNN
1.1 訓練過程
(1) 訓練時采用fine-tune方式: 先用Imagenet(1000類)訓練,再用PASCAL VOC(21)類來fine-tune。使用這種方式訓練能夠提高8個百分點。
(2) 訓練時每個batch的組成: batch_size = 128 = 32P(正樣本) + 96(負樣本組成)。可以使用random crop實現。
1.2 Inference過程
(1) 測試過程使用Selective Search生成2000個建議框,對建議框進行剪裁並調整尺度為227x227,以此保證全連接層得到特征為4096的固定長度。
(2) 剪裁后的proposal進行resize可能會使建議框區域變為畸形區域(warped region),因為selective region生成的region box形狀長寬不一定相等。
(3) nms: 非極大值抑制: inference時,當某個小塊中存在多個相同類別時,先確定最高分者,再將與最高分者重疊的預測結果去掉。
(5) 在pool5時,每個fearture map為6x6的尺寸,特征圖中每個點可以感受到warped image中的195x195的區域。
1.3 RCNN缺點
(1) 多階段訓練: 預訓練(ImageNet) + Selective Search + CNN特征提取器(VOC) + 分類器(SVMs) + 邊界框回歸器(LR)。
(2) 從每個建議框中提取的特征向量(1x4096)存儲於硬盤,消耗大量時間空間成本。
(3) 每個warped region都需要重新送往CNN提取特征,多次重復卷積計算。
(4) Inference一張圖片耗時太長,GPU: 13 s/frame,CPU: 53 s/frame。
SPP-Net
2.1 Inference過程
任意尺寸圖像輸入CNN(ZF/Alex/Overfeat)中,使用CNN卷積層部分得到最后一層特征向量,使用EdegeBoxes計算特征圖中建議窗口(proposal wndows),使用SPP層將特征圖轉換為定長特征向量,該向量長度與SPP層參數及特征圖個數有關。將定長特征向量經過兩個全連接層后輸入分類器(Softmax/SVMs)及回歸器(BBox regressor)中。
2.2 SPP改進
(1) RCNN中對proposal region進行resize會使輸入變得畸形,影響檢測結果。而只有FC層才需要固定長度特征向量,因此,作者提出卷積層最后的池化層換為SPP層,使不同輸入圖像進入FC層之前能夠變為相同長度特征向量。
(2) 將原圖放入CNN中計算到Conv5再進行選擇proposal,然后SPP。這樣只用做一次卷積部分運算(卷積層很費時),共享卷積層計算,加快了前傳速度(24~102倍 x RCNN, 0.14s Vs 9.03s),這里有個很好的SPP與RCNN計算差別示意圖見SPP圖2,參考。
(3) 至於SPP-Net如何將EdegeBoxes/SelectiveSearch生成的建議框映射到特征圖中,文中最后附錄A也進行了說明,也可以參考里面的說明。其實,
x為原圖中坐標,x`為特征圖中的坐標,S為原圖與特征圖之間所有卷積或者池化層的核步長的乘積。
2.3 SPP訓練
(1) 使用fine-tune的對SPP的效果不大。
(2) 在訓練時每個epoch使用不同的輸入圖片尺寸(因為Caffe,cuda-convnet不支持變尺寸做為輸入進行訓練),這樣可以增加數據,並且增加網絡對目標尺寸的魯棒性。
2.4 SPP缺點
(1) 多階段訓練: 預訓練(ImageNet) + Selective Search + CNN特征提取器(VOC) + 分類器(SVMs) + 邊界框回歸器(LR)。與RCNN一樣,多階段分開訓練。
(2) 特征圖存儲硬盤,時空開銷大。
(3) 文中2.3節提到SPP-Net與RCNN都使用低效的更新參數方式,限制CNN網絡精度的提高。這可能是因為他們訓練過程都是多階段組合,每個階段都只能更新需要被fine-tune部分的參數。例如,在訓練SVMs分類器過程中,CNN部分參數並不能被更新。
3 Fast-RCNN
創新點: 合並CNN特征提取模塊與分類回歸模塊 + ROI pooling(SPP的特例)
3.1 Fast-RCNN 相比於SPP與RCNN的改進
(1) CNN特征提取模塊與分類回歸模塊三者合並,除(RP生成模塊)之外部分實現端到端訓練,並且使用回歸與分類之和的multi-loss監督網絡收斂。帶來以下好處:
- 加快測試速度:CNN特征提取模塊如果獨立,那么需要將提取的特征存儲於硬盤中,導致占用大量硬盤,並且訓練與Inference的速度都非常慢。
- 提高模型精度:CNN模塊、分類模塊、回歸模塊如果三者獨立,那么需要分三個階段對每個模塊進行finetune,在訓練每個模塊的過程其它模塊參數保持不變,使得反向傳播過程參數更新的不充分,限制最終模塊精度的提升。
(2) ROI池化取代SPP-net中SPP池化,好處是本來SPP池化生成的是定長特征向量,但ROI池化生成定尺寸特征圖,保留了特征的空間位置特征,這一步的作用在Faster-RCNN中才能體現。其實,ROI池化得到的只是SPP多尺度金字塔的其中一層。
(3) 訓練過程中,Fast-RCNN相對於SPP與RCNN每個Iteration更快並且反向傳播更充分,原因在於Fast-RCNN每個Iteration中128個樣本取自於兩個樣本圖像,而SPP與RCNN每個樣本取自於一張圖像。更快的原因:SPP雖然使用了共享卷積部分計算的機制,但是由於每個樣本取自於不同圖像,那么訓練過程的共享計算機制相當於無效,而RCNN沒有共享計算機制。反向傳播更充分的原因:每個ROI樣本在原圖中感受野很大幾乎接近於原圖大小,Iteraions中不同樣本取自於同一張圖,那么不同樣本之間的相關性很大,這樣的一個batch對於SGD的反向傳播有很大的益處。以上結論參考於Kaiming ICCV2015報告分享。
3.2 Fast-RCNN實驗結論
- 基於Imagenet預訓練模型 fine-tune的方法:
訓練數據輸入為圖片列表與每張圖片對應的ROI位置,替換最后一個pooling層為ROI pooling層,softmax分類器替換為一個分類+回歸的雙任務層。 - 實驗證明:對於Alexnet這種小網絡,從第三個卷積層開始fine-tune才有意義,第一個卷積層獨立於所做的任務,只是提取基於線條特征,第二層fine-tune與not fine-tune效果差距不大
- 實驗證明:對於分類任務,使用softmax與SVMs分類器效果差異不大,因此,沒有必要像RCNN一樣,fine-tune的時候來回切換不同的分類器。
3.3 Fast-RCNN中FC層加速
在分類任務中,卷積層部分與全連接層都只做一次,卷積層耗時巨大。但在檢測任務中,每圖卷積一次,但對每個建議框都要做一次全連接層計算,這時全連接層耗時相對變大,作者的加速方案為truncated SVD。
SVD加速全連接層的原理如下:
其中,\(dim(W) = u x v\), \(dim(U) = u * t\), \(dim(V) = t * v\),如果\(t<<min(u, v)\),那么計算三次內積的計算量\(t*(u+v+t)\)要小於計算一次內積的計算量\(u*v\)
加速前后效果圖如下:
4 Faster-RCNN
創新點: Fast-RCNN + RPN
本文主要提出了RPN,即建議框生成網絡,該網絡與Fast-RCNN網絡共享卷積層參數,從而低代價生成了更精准的建議框,並且將建議框生成算法與目標檢測算法統一於一個網絡
4.1 RPN探究
RPN測試過程
本文相對於之前的Region proposal系統的檢測算法的核心創新就是提出了RPN網絡從而低代價生成高召回率的建議框,但是RPN網絡到底長什么樣,如何實現的呢?以下內容對照Faster-RCNN圖2進行解釋:
RPN網絡是一個全卷積網絡,如圖中綠線部分所示,在末端卷積層使用3x3卷積核提取特征圖,再使用兩個1x1卷積分別得到2k(k為anchor個數)分類特征與4k的回歸邊界框位置,將2k的分類特征經過softmax將特征整合為概率值。最后proposal_layer將邊界框位置與概率經過非極大值抑制后,映射到末端卷積層之后就可以ROI池化,其余過程與Fast-RCNN一樣。整個過程參見Faster-RCNN圖2。
RPN訓練過程
看到這里有個困惑: 為什么經過1x1的卷積核就能生成所需要比例與尺寸的anchor?
仔細看了一遍整個測試過程的prototxt與源碼,卷積前后並沒有設置anchor的形狀與尺寸的參數,為什么經過兩個1x1的卷積核之后生成的就是所設計的9種anchor呢?
答案需要從訓練過程說起:
Faster-RCNN圖3為RPN網絡的訓練結構示意圖,與測試過程不同的是增加了GT標簽與loss函數。其中,pn-data層接收GT標簽數據,並且將輸出的結果和預測到邊界框位置及概率計算RPN損失函數,由anchor_target_layer.py文件實現。
layer {
name: 'rpn-data'
type: 'Python'
bottom: 'rpn_cls_score'
bottom: 'gt_boxes'
bottom: 'im_info'
bottom: 'data'
top: 'rpn_labels'
top: 'rpn_bbox_targets'
top: 'rpn_bbox_inside_weights'
top: 'rpn_bbox_outside_weights'
python_param {
module: 'rpn.anchor_target_layer'
layer: 'AnchorTargetLayer'
param_str: "'feat_stride': 16"
}
}
再看anchor_target_layer.py中,初始化過程中調用genertate_anchors函數生成九種anchor,前傳過程中前anchor轉換為真正的GT的anchor監督預測的結果。
class AnchorTargetLayer(caffe.Layer):
"""
Assign anchors to ground-truth targets. Produces anchor classification
labels and bounding-box regression targets.
"""
def setup(self, bottom, top):
layer_params = yaml.load(self.param_str_)
anchor_scales = layer_params.get('scales', (8, 16, 32))
self._anchors = generate_anchors(scales=np.array(anchor_scales))
self._num_anchors = self._anchors.shape[0]
self._feat_stride = layer_params['feat_stride']
。。。
def forward(self, bottom, top):
# Algorithm:
#
# for each (H, W) location i
# generate 9 anchor boxes centered on cell i
# apply predicted bbox deltas at cell i to each of the 9 anchors
# filter out-of-image anchors
# measure GT overlap
所謂種什么瓜,結什么果,因為訓練過程中每個特征圖上生成的(2k + 4k)個值是由GT的anchor位置與概率來監督產生loss的,那么模型收斂后自然預測的是參考9種anchor的預測結果。
4.2 Faster-RCNN訓練過程
(1) 交替訓練:
1). fine-tune RPN on Imagenet.
2). 用RPN生成的建議框來訓練Fast-RCNN.
3). RPN共享Fast-RCNN卷積層,fine-tune RPN網絡.
4). fine-tune Fast-RCNN
(2) 近似連接訓練:
直接按照一個合並的網絡訓練,但是Fast-RCNN反向傳播過程不傳向RPN網絡,依靠RPN網絡自身loss反向傳播
4.3 Inference過程
(1) 基礎網絡部分作者使用用ZF(17fps)與VGG(5 fps)
(2) 建議框NMS到300個就能達到很好效果。
(3) 生成建議框后,ROI池化是在末端卷積特征層上進行的。
4.4 缺點
基於region proposal系統方法通病,需要分別對每個ROI進行識別與精定位,相當於得到ROI之后,分別依次對每個ROI進行后續全連接層的處理。
Faster-RCNN比較明白的blog
還有一些細節可以參考