1. 程式人生 > >FasterRCNN程式碼解讀1

FasterRCNN程式碼解讀1

之前的文章簡要介紹了Faster-RCNN等物體檢測的演算法,本文將從程式碼角度詳細分析介紹Faster-RCNN的實現。本文使用的程式碼參考了chenyuntc的實現,程式碼的位置看這裡。需要注意的是,本文使用的框架是Pytorch。

圖片名稱

資料載入

資料載入部分的程式碼主要見./data/dataset.py中的類DatasetTestDataset

資料載入部分的邏輯如下:

  1. 從VOC資料集中獲得img, bbox, label
  2. img, bbox進行放縮(放縮的目的是讓圖片處於合適的大小,這樣預先指定錨框才有意義)
  3. img進行標準化正則處理
  4. 如果是訓練階段,將img翻轉以增加訓練資料

網路結構

FasterRCNN的網路結構如下圖所示:

這裡寫圖片描述

FasterRCNN結構的程式碼主要見./model.faster_rcnn.py,其結構包含三大部分:

  1. 預訓練的CNN模型 decom_vgg16
  2. rpn網路RegionProposalNetwork
  3. roi及以上網路VGG16RoIHead

下面,將以放縮後大小為[1, 3, 600, 800]的圖片為例針對每個部分分別介紹。影象類別共計21類(包含背景)。

預訓練的CNN模型

該部分程式碼見./model/vgg16.py

輸入:圖片,大小[1, 3, 600, 800]
輸出:特徵圖features,大小[1, 512, 37, 50]


其邏輯如下:

  1. 載入預先訓練好的CNN模型VGG16。
  2. 將模型拆分為兩部分extractor, classifier。其中,extractor的引數固定。
  3. 圖片通過extractor可以得到特徵圖features。根據extractor中池化引數可知影象通過extractor縮小了16倍。

rpn網路

該部分程式碼見./model/rpn.py

輸入:特徵圖features,大小[1, 512, 37, 50]
輸出:

  • rpn_locs
    :rpn對位置的修正,大小[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。


其邏輯如下:

  1. 對特徵圖features以基準長度為16、選擇合適的ratiosscales取基準錨點anchor_base。(選擇長度為16的原因是圖片大小為600*800左右,基準長度16對應的原圖區域是256*256,考慮放縮後的大小有128*128,512*512比較合適)
  2. 根據anchor_base在原圖上獲得anchors
  3. 對特徵圖features採用卷積得到rpn_locsrpn_scores
  4. 根據anchorsrpn_locs獲得修正後的rp
  5. rp進一步修正獲得roisroi_indices,修正包括超出邊界的部分截斷、移除太小的、nms。

roi及以上網路

該部分程式碼見./model/roi_module.py

輸入:

  • features:特徵圖,大小[1, 512, 37, 50]
  • rois:rpn篩選出的roi的位置,大小[300, 4]
  • roi_indices:rpn篩選出的roi對應的圖片索引,大小[300]

輸出:

  • roi_cls_locsroi位置的修正,大小[300, 84]
  • roi_scoresroi各類的分數,大小[300, 21]

其邏輯如下:

  1. 通過RoIPooling2D將大小不同的roi變成大小一致,得到pooling後的特徵,大小為[300, 512, 7, 7]
  2. 接入預訓練的CNN模型引入的classifier
  3. 分別接入全連線得到roi_cls_locsroi_scores

訓練

訓練部分的程式碼主要見./trainer/trainer.py中的FasterRCNNTrainer中的train_step函式。

訓練部分的核心是loss如何求取。

loss求取前網路的步驟如下:

  1. 預訓練CNN特徵提取:輸入imgextractor獲得features
  2. rpn網路得到roi:輸入featuresrpn獲得rpn_locs, rpn_scores, rois, roi_indices, anchor
  3. 抽樣roi:輸入roisbboxlabelProposalTargetCreator獲得sample_roi, gt_roi_loc, gt_roi_label。該步驟的含義是得到正負例比例和位置合適的roi
  4. head網路得到roi的位置修正與分數:輸入features,sample_roi,sample_roi_index得到roi_cls_loc, roi_score

各個loss求取的方式如下:

  1. rpn_loc_loss:已知rpn_loc,需要先根據anchorbbox得到真實的gt_rpn_locgt_rpn_label。該處loss的計算只考慮前景,所以根據rpn_loc,gt_rpn_loc,gt_rpn_label計算L1-LOSS即可。
  2. rpn_cls_loss:根據rpn_scoregt_rpn_label計算二分類的交叉熵即可。
  3. roi_loc_loss:已知roi_loc,在sample roi的過程中已獲得gt_roi_loc, gt_roi_label。根據roi_loc,gt_roi_loc,gt_roi_label計算L1-LOSS即可。
  4. roi_cls_loss:根據roi_scoregt_roi_label計算多分類的交叉熵即可。

整體的loss為以上各loss相加求和。

測試

訓練部分的程式碼主要見./model/faster_rcnn.py中的FasterRCNNTrainer中的predict函式。

其步驟如下:

  1. 圖片預處理
  2. 預訓練CNN特徵提取:輸入imgextractor獲得features
  3. rpn網路得到roi:輸入featuresrpn獲得rpn_locs, rpn_scores, rois, roi_indices, anchor
  4. head網路得到roi的位置修正與分數:輸入features,rois,roi_indices得到roi_cls_loc, roi_score
  5. 得到圖片預測的bbox:輸入roi_cls_locroi_scorerois,採用nms等方法得到預測的bbox

之前的文章簡要介紹了Faster-RCNN等物體檢測的演算法,本文將從程式碼角度詳細分析介紹Faster-RCNN的實現。本文使用的程式碼參考了chenyuntc的實現,程式碼的位置看這裡。需要注意的是,本文使用的框架是Pytorch。