R-FCN+ResNet-50 訓練模型

本文轉載自:

http://blog.csdn.net/sinat_30071459/article/details/53202977


說明:

本文假設你已經做好數據集,格式和VOC2007一致,並且Linux系統已經配置好caffe所需環境(博客裏教程很多),下面是訓練的一些修改。


py-R-FCN源碼下載地址:

https://github.com/Orpine/py-R-FCN

也有Matlab版本:

https://github.com/daijifeng001/R-FCN

本文用到的是Python版本。


本文主要參考https://github.com/Orpine/py-R-FCN


準備工作:

(1)配置caffe環境(網上找教程)

(2)安裝cythonpython-OpenCVeasydict

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. pip install cython  
  2. pip install easydict  
  3. apt-get install python-opencv  

然後,我們就可以開始配置R-FCN了。

1.下載py-R-FCN

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. git clone https://github.com/Orpine/py-R-FCN.git  

下面稱你的py-R-FCN路徑爲RFCN_ROOT.


2.下載caffe

注意,該caffe版本是微軟版本
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT  
  2. git clone https://github.com/Microsoft/caffe.git  
如果一切正常的話,python代碼會自動添加環境變量 $RFCN_ROOT/caffe/python,否則,你需要自己添加環境變量。

3.Build Cython

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT/lib  
  2. make  

4.Build caffe和pycaffe

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT/caffe  
  2. cp Makefile.config.example Makefile.config  
然後修改Makefile.config。caffe必須支持python層,所以WITH_PYTHON_LAYER := 1是必須的。其他配置可參考:Makefile.config

接着:
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT/caffe  
  2. make -j8 && make pycaffe  
如果沒有出錯,則:


5.測試Demo

經過上面的工作,我們可以測試一下是否可以正常運行。
我們需要下載作者訓練好的模型,地址:鏈接:http://pan.baidu.com/s/1kVGy8DL 密碼:pwwg
然後將模型放在$RFCN_ROOT/data。看起來是這樣的:
$RFCN_ROOT/data/rfcn_models/resnet50_rfcn_final.caffemodel
$RFCN_ROOT/data/rfcn_models/resnet101_rfcn_final.caffemodel
運行:
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT  
  2. ./tools/demo_rfcn.py --net ResNet-50  



6.用我們的數據集訓練

(1)拷貝數據集

假設我們已經做好數據集了,格式是和VOC2007一致,將你的數據集
拷貝到$RFCN_ROOT/data下。看起來是這樣的:
$VOCdevkit0712/                           # development kit
$VOCdevkit/VOCcode/                   # VOC utility code
$VOCdevkit/VOC0712                    # image sets, annotations, etc.
# ... and several other directories ...
如果你的文件夾名字不是VOCdevkit0712和VOC0712,修改成0712就行了。
(作者是用VOC2007和VOC2012訓練的,所以文件夾名字帶0712。也可以修改代碼,但是那樣比較麻煩一些,修改文件夾比較簡單)

(2)下載預訓練模型
本文以ResNet-50爲例,因此下載ResNet-50-model.caffemodel。下載地址:鏈接:http://pan.baidu.com/s/1slRHD0L 密碼:r3ki
然後將caffemodel放在$RFCN_ROOT/data/imagenet_models  (data下沒有該文件夾就新建一個)

(3)修改模型網絡

打開$RFCN_ROOT/models/pascal_voc/ResNet-50/rfcn_end2end  (以end2end爲例)

注意:下面的cls_num指的是你數據集的類別數+1(背景)。比如我有15類,+1類背景,cls_num=16.

<1>修改class-aware/train_ohem.prototxt
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.   name: 'input-data'  
  3.   type: 'Python'  
  4.   top: 'data'  
  5.   top: 'im_info'  
  6.   top: 'gt_boxes'  
  7.   python_param {  
  8.     module: 'roi_data_layer.layer'  
  9.     layer: 'RoIDataLayer'  
  10.     param_str: "'num_classes': 16" #cls_num  
  11.   }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.   name: 'roi-data'  
  3.   type: 'Python'  
  4.   bottom: 'rpn_rois'  
  5.   bottom: 'gt_boxes'  
  6.   top: 'rois'  
  7.   top: 'labels'  
  8.   top: 'bbox_targets'  
  9.   top: 'bbox_inside_weights'  
  10.   top: 'bbox_outside_weights'  
  11.   python_param {  
  12.     module: 'rpn.proposal_target_layer'  
  13.     layer: 'ProposalTargetLayer'  
  14.     param_str: "'num_classes': 16" #cls_num  
  15.   }  
  16. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_cls"  
  4.     name: "rfcn_cls"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 784 #cls_num*(score_maps_size^2)  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_bbox"  
  4.     name: "rfcn_bbox"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 3136 #4*cls_num*(score_maps_size^2)  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_cls"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_cls_rois"  
  5.     name: "psroipooled_cls_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 16  #cls_num  
  10.         group_size: 7  
  11.     }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_bbox"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_loc_rois"  
  5.     name: "psroipooled_loc_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 64 #4*cls_num  
  10.         group_size: 7  
  11.     }  
  12. }  


<2>修改class-aware/test.prototxt

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_cls"  
  4.     name: "rfcn_cls"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 784 #cls_num*(score_maps_size^2)  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_bbox"  
  4.     name: "rfcn_bbox"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 3136 #4*cls_num*(score_maps_size^2)  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_cls"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_cls_rois"  
  5.     name: "psroipooled_cls_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 16  #cls_num  
  10.         group_size: 7  
  11.     }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_bbox"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_loc_rois"  
  5.     name: "psroipooled_loc_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 64  #4*cls_num  
  10.         group_size: 7  
  11.     }  
  12. }  
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     name: "cls_prob_reshape"  
  3.     type: "Reshape"  
  4.     bottom: "cls_prob_pre"  
  5.     top: "cls_prob"  
  6.     reshape_param {  
  7.         shape {  
  8.             dim: -1  
  9.             dim: 16  #cls_num  
  10.         }  
  11.     }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     name: "bbox_pred_reshape"  
  3.     type: "Reshape"  
  4.     bottom: "bbox_pred_pre"  
  5.     top: "bbox_pred"  
  6.     reshape_param {  
  7.         shape {  
  8.             dim: -1  
  9.             dim: 64  #4*cls_num  
  10.         }  
  11.     }  
  12. }  

<3>修改train_agnostic.prototxt

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.   name: 'input-data'  
  3.   type: 'Python'  
  4.   top: 'data'  
  5.   top: 'im_info'  
  6.   top: 'gt_boxes'  
  7.   python_param {  
  8.     module: 'roi_data_layer.layer'  
  9.     layer: 'RoIDataLayer'  
  10.     param_str: "'num_classes': 16"  #cls_num  
  11.   }  
  12. }  
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_cls"  
  4.     name: "rfcn_cls"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 784 #cls_num*(score_maps_size^2)   ###  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_cls"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_cls_rois"  
  5.     name: "psroipooled_cls_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 16 #cls_num   ###  
  10.         group_size: 7  
  11.     }  
  12. }  

<4>修改train_agnostic_ohem.prototxt

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.   name: 'input-data'  
  3.   type: 'Python'  
  4.   top: 'data'  
  5.   top: 'im_info'  
  6.   top: 'gt_boxes'  
  7.   python_param {  
  8.     module: 'roi_data_layer.layer'  
  9.     layer: 'RoIDataLayer'  
  10.     param_str: "'num_classes': 16" #cls_num ###  
  11.   }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_cls"  
  4.     name: "rfcn_cls"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 784 #cls_num*(score_maps_size^2)   ###  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_cls"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_cls_rois"  
  5.     name: "psroipooled_cls_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 16 #cls_num   ###  
  10.         group_size: 7  
  11.     }  
  12. }  

<5>修改test_agnostic.prototxt

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "conv_new_1"  
  3.     top: "rfcn_cls"  
  4.     name: "rfcn_cls"  
  5.     type: "Convolution"  
  6.     convolution_param {  
  7.         num_output: 784 #cls_num*(score_maps_size^2) ###  
  8.         kernel_size: 1  
  9.         pad: 0  
  10.         weight_filler {  
  11.             type: "gaussian"  
  12.             std: 0.01  
  13.         }  
  14.         bias_filler {  
  15.             type: "constant"  
  16.             value: 0  
  17.         }  
  18.     }  
  19.     param {  
  20.         lr_mult: 1.0  
  21.     }  
  22.     param {  
  23.         lr_mult: 2.0  
  24.     }  
  25. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     bottom: "rfcn_cls"  
  3.     bottom: "rois"  
  4.     top: "psroipooled_cls_rois"  
  5.     name: "psroipooled_cls_rois"  
  6.     type: "PSROIPooling"  
  7.     psroi_pooling_param {  
  8.         spatial_scale: 0.0625  
  9.         output_dim: 16 #cls_num   ###  
  10.         group_size: 7  
  11.     }  
  12. }  

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. layer {  
  2.     name: "cls_prob_reshape"  
  3.     type: "Reshape"  
  4.     bottom: "cls_prob_pre"  
  5.     top: "cls_prob"  
  6.     reshape_param {  
  7.         shape {  
  8.             dim: -1  
  9.             dim: 16 #cls_num   ###  
  10.         }  
  11.     }  
  12. }  

(4)修改代碼

<1>$RFCN/lib/datasets/pascal_voc.py

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. class pascal_voc(imdb):  
  2.     def __init__(self, image_set, year, devkit_path=None):  
  3.         imdb.__init__(self, 'voc_' + year + '_' + image_set)  
  4.         self._year = year  
  5.         self._image_set = image_set  
  6.         self._devkit_path = self._get_default_path() if devkit_path is None \  
  7.                             else devkit_path  
  8.         self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year)  
  9.         self._classes = ('__background__', # always index 0  
  10.                          '你的標籤1','你的標籤2',你的標籤3','你的標籤4'  
  11.                       )  
改成你的數據集標籤。

<2>$RFCN_ROOT/lib/datasets/imdb.py

主要是assert (boxes[:, 2] >= boxes[:, 0]).all()可能出現AssertionError,具體解決辦法參考:


PS:
上面將有無ohem的prototxt都改了,但是這裏訓練用的是ohem。
另外,默認的迭代次數很大,可以修改$RFCN\experiments\scripts\rfcn_end2end_ohem.sh:
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. case $DATASET in  
  2.   pascal_voc)  
  3.     TRAIN_IMDB="voc_0712_trainval"  
  4.     TEST_IMDB="voc_0712_test"  
  5.     PT_DIR="pascal_voc"  
  6.     ITERS=110000  

修改ITERS爲你想要的迭代次數即可。


(5)開始訓練

[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT  
  2. ./experiments/scripts/rfcn_end2end_ohem.sh 0 ResNet-50 pascal_voc  

正常的話,就開始迭代了:



$RFCN_ROOT/experiments/scripts裏還有一些其他的訓練方法,也可以測試一下(經過上面的修改,無ohem的end2end訓練也改好了,其他訓練方法修改的過程差不多)。

(6)結果

將訓練得到的模型($RFCN_ROOT/output/rfcn_end2end_ohem/voc_0712_trainval裏最後的caffemodel)拷貝到$RFCN_ROOT/data/rfcn_models下,然後打開$RFCN_ROOT/tools/demo_rfcn.py,將CLASSES修改成你的標籤,NETS修改成你的model,im_names修改成你的測試圖片(放在data/demo下),最後:
[plain] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. cd $RFCN_ROOT  
  2. ./tools/demo_rfcn.py --net ResNet-50  

我將顯示的標籤改爲了中文,修改方法參考:http://blog.csdn.net/sinat_30071459/article/details/51694037

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章