RPN的作用在於較爲準確的選擇前300個推薦框,前2篇論(RCNN,Fast-RCNN)用的是Selective Search方法, 貪婪地合併基於低層次特徵的像素,產生2000個推薦框,效率低。本文主要講解RPN網絡層及其損失函數,遇到過的坑和疑惑的地方在這裏記錄一下,便於今後回顧。涉及到的內容過多,請參考:
Faster-RCNN論文地址
1、RPN模型
要點1:在每個滑動窗口的中心(經過3x3卷積得到的點,該卷積層不改變feature map的大小,只是將周圍的信息融合到中心點上,該中心點的可視野爲3x3大小的VGG/ZF特徵)預測9種不同尺度大小的錨框(anchors)。這裏用的是ZF的feature map 是256-d,而VGG的feature map 是512-d。
vgg_kernel = 512 #如何實現anysize input
f_map_tile = Input(shape=(None,None,512)) #out: 1x1x512
convolution_3x3 = Conv2D(
filters=512, #vgg 512, zf 256
kernel_size=(3, 3),
padding='same',
activation='relu',
name="3x3"
)(f_map_tile) #out: 1x1x512
output_deltas = Conv2D(
filters= 4 * k,
kernel_size=(1, 1), #1x1卷積的作用?
activation="linear",
kernel_initializer="uniform",
name="deltas1"
)(convolution_3x3) #out: 1x1x36
output_scores = Conv2D(
filters=2 * k, #能否換成1*k?
kernel_size=(1, 1),
activation="softmax",
kernel_initializer="uniform",
name="scores1"
)(convolution_3x3) #out: 1x1x18
model = Model(inputs=[feature_map_tile], outputs=[output_scores, output_deltas])
要點2:這裏有一個兩難的選擇,是將整個feature map放入,還是隻放入1x1的feature map。這裏要提一下,VGG是有5層池化層,故32倍下采樣。
1、如果放入整個feature map的話,那麼預測的是WHK個錨框,在這些錨框中,很多是無關錨框(既不是IOU>0.7的錨框,又不是<0.3的錨框),這些無關錨框也要喂入網絡,但是不參與損失計算。更麻煩的是,我無法控制前景和背景的比例及數量,通過調節IOU閾值來控制不是正確的方法,若要實現any size image 輸入,那麼就不能批量訓練了,得一張一張feature map喂。
2、如果只喂一部分feature map的話,我就很方便了,我只需選擇好前景和背景,然後將前景和背景按1:1的比例喂入網絡即可,這樣一個batch可以實現喂入多張圖像。我用VGG16得到下采樣32倍的feature map,這已經算是高級特徵了,由feature map 的特徵點產生9個錨框(這9個錨框得保證不能都存在前景和背景框,所以IOU閾值控制很重要),喂數據的時候,錨框和特徵點要對應起來。這樣做的話,3x3的卷積層就沒啥作用了,因爲1x1的feature map用3x3卷積核卷積的結果還是自己的信息。通過實驗,這個效果還行,缺點也是有的,因爲32倍下采樣了,小物體信息很容易丟失,小物體很難框到。
2、Loss
這裏就不翻譯了,還是原滋原味的好。
- i : the index of an anchor in a mini-batch
- pi : the predicted probability of anchor i being an object.
- p∗: the ground-truth label,1 if the anchor is positive, and is 0 if the anchor is negative.
- ti: a vector representing the 4 parameterized coordinates of the predicted bounding box, the predicted bounding box associated with a positive anchor
- t∗: the ground-truth box associated with a
positive anchor
要點3:分類損失很簡單,使用分類交叉(categorical_crossentropy)作爲損失函數即可。這裏主要探討一下回歸損失。看下圖,迴歸網絡的輸出不是座標值,而是相對於錨框(anchors)的偏移值,用偏移值更利於網絡的收斂,當迴歸損失趨近0時,意味着預測座標趨近於真實座標。
x: predicted box
xa: anchor box
x∗: ground truth box
原文:Variables x, xa, and x∗ are for the predicted box, anchor box, and ground-truth box respectively (likewise for y, w, h).
下圖的x=
總結
只看論文,不去復現,很難理解論文精髓和缺陷,需要兩者結合纔有更好的效果,矩陣運算很重要,不會操作矩陣,編程寸步難行。最新的實例分割(Parsing-rcnn),目標跟蹤(SiamRPN++)等算法都引用了RPN,RPN在faster-rcnn中首次提出,也使得faster-rcnn成爲了當時最好的目標檢測算法之一,但是yolo從V2版本就趕超了faster-rcnn,目前yolo已經發展到V4了,成了工業上默認的目標檢測算法,可見技術迭代之快。