一直不知道7×7的網格到底是幹什麼的,不就是結果預測7×7×2個框嗎,這跟把原圖分成7×7有什麼關係?不分成7×7就不能預測7×7×2個框嗎?
之前跟一個朋友討論,他說7×7的網格是作爲迴歸框的初始位置,我後來的很長一段時間一直這麼認爲,後來想想不對啊,bbox的初始位置不是根據各層的權重得到的嗎?各層權重是隨機初始化的,7×7的grid怎麼能作爲bbox的初始位置?我腦子被驢踢了麼,竟然一直這麼認爲。
看了源碼之後又看了faster-rcnn的論文中關於rpn的介紹,又看了rpn的代碼,然後豁然開朗,我們來分析一下
一、YOLO
首先你應該看完YOLO源碼詳解(三)- 前向傳播(forward),之後問題就簡單了,只有一句話:grid和anchor的唯一作用就是爲了計算IOU,從而來確定正負樣本。在YOLO中,計算完IOU後確定loss function中的1obji,1objij,λcoord,λnocoord的值。
二、RPN的anchors
YOLO中的理解了,我們再來看一下PRN中的anchors,如下圖所示:
假設原始圖像尺寸是1000×600,最左邊的一層就是VGG的第5層卷積層,下一層是rpn_conv/3*3層,千萬不要被他迷惑了,說是rpn_conv/3×3其實還是普通的卷積層,也就是說這裏跟普通的卷積層沒有任何區別,這裏的輸出是64×39×512,在這裏,每個feature map一共有64×39個點,這裏每個點對應到原始圖像上是16×16的區域(注意這裏並不是感受野),16×16怎麼算出來的呢?ceil(1000/64)×ceil(600/39),爲什麼向上取整呢?因爲有padding啊~
假設每個點要搞到9個anchors,也就是原始圖像上每隔16×16的區域就搞9個網格,因爲這9個網格大小不一樣,就取名叫anchors,這裏是不是跟YOLO一樣了?只不過YOLO整副圖就搞了7×7個網格。到這裏是不是豁然開朗了,兩種算法有異曲同工之妙。
繼續往下走,rpn_cls_score層,這裏輸出39×64×18,每個位置有9個anchors,預測每個anchor是否是物體,所以是2×9=18,繼續到了rpn-data層(就是AnchorTargetLayer層,層的結構如下prototxt),這一層就是要算IOU的,也就是體現了:grid和anchor的唯一作用就是爲了計算IOU,從而來確定正負樣本。你理解了嗎?
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"
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
(END)
----------------------------------------------分割------------------------------------------------------
個人理解:Faster R-CNN裏的RPN,是對RCNN和Fast R-CNN的region proposals獲取的改進,把這個步驟併入網絡,所以anchors某種意義上也算是一種region proposals。在Faster RCNN中anchors確實是在確定正負樣本時會用到,因爲要計算IOU的值,但是在訓練時也要用anchors的座標值來計算其與Ground Truth的偏移量,在測試時也是需要anchors的座標值和偏移量來計算預測框的位置。
而YOLO中的grid,按7*7來分,其實就是得到98個bounding boxes,對這個98個boxes進行迴歸和分類預測,某種意義上也算是一種anchor,作用也基本相同。