FasterRCNN程式碼解讀1
之前的文章簡要介紹了Faster-RCNN等物體檢測的演算法,本文將從程式碼角度詳細分析介紹Faster-RCNN的實現。本文使用的程式碼參考了chenyuntc的實現,程式碼的位置看這裡。需要注意的是,本文使用的框架是Pytorch。
資料載入
資料載入部分的程式碼主要見./data/dataset.py
中的類Dataset
與TestDataset
。
資料載入部分的邏輯如下:
- 從VOC資料集中獲得
img, bbox, label
- 將
img, bbox
進行放縮(放縮的目的是讓圖片處於合適的大小,這樣預先指定錨框才有意義) - 將
img
進行標準化正則處理 - 如果是訓練階段,將
img
翻轉以增加訓練資料
網路結構
FasterRCNN的網路結構如下圖所示:
FasterRCNN結構的程式碼主要見./model.faster_rcnn.py
,其結構包含三大部分:
- 預訓練的CNN模型
decom_vgg16
- rpn網路
RegionProposalNetwork
- roi及以上網路
VGG16RoIHead
下面,將以放縮後大小為[1, 3, 600, 800]
的圖片為例針對每個部分分別介紹。影象類別共計21類(包含背景)。
預訓練的CNN模型
該部分程式碼見./model/vgg16.py
輸入:圖片,大小[1, 3, 600, 800]
輸出:特徵圖features
,大小[1, 512, 37, 50]
其邏輯如下:
- 載入預先訓練好的CNN模型VGG16。
- 將模型拆分為兩部分
extractor
,classifier
。其中,extractor
的引數固定。 - 圖片通過
extractor
可以得到特徵圖features
。根據extractor
中池化引數可知影象通過extractor
縮小了16倍。
rpn網路
該部分程式碼見./model/rpn.py
。
輸入:特徵圖features
,大小[1, 512, 37, 50]
輸出:
rpn_locs
[1, 16650, 4]
rpn_scores
:rpn判斷區域前景背景,大小[1, 16650, 2]
rois
:rpn篩選出的roi的位置,大小[300, 4]
roi_indices
:rpn篩選出的roi對應的圖片索引,大小[300]
anchor
:原影象的錨點,大小[16650, 4]
其中,16650是放縮後的影象所產生的所有錨點(37*50*9),每個錨點都對應了一個rp。通過 rpn_scores
以及nms可以得到篩選後的大小為300的roi。
其邏輯如下:
- 對特徵圖
features
以基準長度為16、選擇合適的ratios
和scales
取基準錨點anchor_base
。(選擇長度為16的原因是圖片大小為600*800左右,基準長度16對應的原圖區域是256*256,考慮放縮後的大小有128*128,512*512比較合適) - 根據
anchor_base
在原圖上獲得anchors
。 - 對特徵圖
features
採用卷積得到rpn_locs
和rpn_scores
- 根據
anchors
和rpn_locs
獲得修正後的rp
- 對
rp
進一步修正獲得rois
和roi_indices
,修正包括超出邊界的部分截斷、移除太小的、nms。
roi及以上網路
該部分程式碼見./model/roi_module.py
。
輸入:
features
:特徵圖,大小[1, 512, 37, 50]
rois
:rpn篩選出的roi的位置,大小[300, 4]
roi_indices
:rpn篩選出的roi對應的圖片索引,大小[300]
輸出:
roi_cls_locs
:roi
位置的修正,大小[300, 84]
roi_scores
:roi
各類的分數,大小[300, 21]
其邏輯如下:
- 通過
RoIPooling2D
將大小不同的roi
變成大小一致,得到pooling後的特徵,大小為[300, 512, 7, 7]
- 接入預訓練的CNN模型引入的
classifier
- 分別接入全連線得到
roi_cls_locs
、roi_scores
訓練
訓練部分的程式碼主要見./trainer/trainer.py
中的FasterRCNNTrainer
中的train_step
函式。
訓練部分的核心是loss如何求取。
loss求取前網路的步驟如下:
- 預訓練CNN特徵提取:輸入
img
到extractor
獲得features
- rpn網路得到roi:輸入
features
到rpn
獲得rpn_locs
,rpn_scores
,rois
,roi_indices
,anchor
- 抽樣roi:輸入
rois
,bbox
,label
到ProposalTargetCreator
獲得sample_roi
,gt_roi_loc
,gt_roi_label
。該步驟的含義是得到正負例比例和位置合適的roi
。 - head網路得到roi的位置修正與分數:輸入
features
,sample_roi
,sample_roi_index
得到roi_cls_loc
,roi_score
各個loss求取的方式如下:
rpn_loc_loss
:已知rpn_loc
,需要先根據anchor
和bbox
得到真實的gt_rpn_loc
和gt_rpn_label
。該處loss的計算只考慮前景,所以根據rpn_loc
,gt_rpn_loc
,gt_rpn_label
計算L1-LOSS即可。rpn_cls_loss
:根據rpn_score
和gt_rpn_label
計算二分類的交叉熵即可。roi_loc_loss
:已知roi_loc
,在sample roi的過程中已獲得gt_roi_loc
,gt_roi_label
。根據roi_loc
,gt_roi_loc
,gt_roi_label
計算L1-LOSS即可。roi_cls_loss
:根據roi_score
和gt_roi_label
計算多分類的交叉熵即可。
整體的loss為以上各loss相加求和。
測試
訓練部分的程式碼主要見./model/faster_rcnn.py
中的FasterRCNNTrainer
中的predict
函式。
其步驟如下:
- 圖片預處理
- 預訓練CNN特徵提取:輸入
img
到extractor
獲得features
- rpn網路得到roi:輸入
features
到rpn
獲得rpn_locs
,rpn_scores
,rois
,roi_indices
,anchor
- head網路得到roi的位置修正與分數:輸入
features
,rois
,roi_indices
得到roi_cls_loc
,roi_score
- 得到圖片預測的bbox:輸入
roi_cls_loc
、roi_score
、rois
,採用nms等方法得到預測的bbox
。
之前的文章簡要介紹了Faster-RCNN等物體檢測的演算法,本文將從程式碼角度詳細分析介紹Faster-RCNN的實現。本文使用的程式碼參考了chenyuntc的實現,程式碼的位置看這裡。需要注意的是,本文使用的框架是Pytorch。