Faster R-CNN的原理就不多说了,在做课题过程中需要重新训练车辆检测模型,因此本文记录一下操作的过程,以备日后复现。
环境
我是用的环境是Ubuntu 14.04 + Titan Xp(12Gb) + cuda 8.0
编译
从github上把Faster RCNN项目的code给clone下来
1
git clone –recursive https://github.com/rbgirshick/py-faster-rcnn.git
编译lib
1
2cd $FRCN_ROOT/lib
make编译caffe和pycaffe
1
2cd $FRCN_ROOT/caffe-fast-rcnn
cp Makefile.config.examplem Makefile.config
修改Makefile.config1
2WITH_PYTHON_LAYER := 1
USE_CUDNN := 1
然后编译1
2
3
4mkdir build
cd build
cmake ..
make -j12 && make pycaffe
等待编译完成即可。
用demo.py测试代码是否正常
下载与训练好的模型,并运行demo程序。
1 | cd $FRCN_ROOT |
如果正常出图,并且做好了物体检测,则代码正常。
训练自己的数据集
Faster RCNN是在PASCAL VOC 2007的数据集上进行训练的,默认的数据集结构包含
JPEGImages:存放用来训练的原始图像
Annotations:存放原始图像中的目标坐标信息,xml格式
ImageSets/Main:指定train、trainval、test、val的图片编号,txt格式
如果使用其他数据集的话,如KITTI,则需要对数据集进行转换。这里提供两个实测非常方便的python脚本,用来合并目标类,生成xml文件。
1 | # modify_annotations_txt.py |
1 | # txt_to_xml.py |
代码修改
我使用的是faster_rcnn_end2end.sh进行训练。需要调整的文件有:
./lib/datasets/pascal_voc.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23# line 30
self._classes = ('__background__', 'car') # always index 0
#'aeroplane', 'bicycle', 'bird', 'boat',
#'bottle', 'bus', 'car', 'cat', 'chair',
#'cow', 'diningtable', 'dog', 'horse',
#'motorbike', 'person', 'pottedplant',
#'sheep', 'sofa', 'train', 'tvmonitor')
# line 188-195 全部注释掉
#if not self.config['use_diff']:
# Exclude the samples labeled as difficult
# non_diff_objs = [
# obj for obj in objs if int(obj.find('difficult').text) == 0]
# if len(non_diff_objs) != len(objs):
# print 'Removed {} difficult objects'.format(
# len(objs) - len(non_diff_objs))
# objs = non_diff_objs
# line 208
x1 = float(bbox.find('xmin').text) #- 1
y1 = float(bbox.find('ymin').text) #- 1
x2 = float(bbox.find('xmax').text) #- 1
y2 = float(bbox.find('ymax').text) #- 1./lib/datasets/imdb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# line 102
def append_flipped_images(self): #modfied
num_images = self.num_images
#widths = self._get_widths()
widths = [PIL.Image.open(self.image_path_at(i)).size[0] for i in xrange(num_images)]
for i in xrange(num_images):
boxes = self.roidb[i]['boxes'].copy()
oldx1 = boxes[:, 0].copy()
oldx2 = boxes[:, 2].copy()
boxes[:, 0] = widths[i] - oldx2 - 1
print boxes[:, 0]
boxes[:, 2] = widths[i] - oldx1 - 1
print boxes[:, 0]
assert (boxes[:, 2] >= boxes[:, 0]).all()
entry = {'boxes' : boxes,
'gt_overlaps' : self.roidb[i]['gt_overlaps'],
'gt_classes' : self.roidb[i]['gt_classes'],
'flipped' : True}
self.roidb.append(entry)
self._image_index = self._image_index * 2./models/pascal_voc/VGG_CNN_M_1024/faster_rcnn_end2end/train.protxt
修改类别为你需要检测类别数目,例如我检测车辆和背景,则将类别数21改为2- ./models/pascal_voc/VGG_CNN_M_1024/faster_rcnn_end2end/test.protxt
修改类别为你需要检测类别数目,例如我检测车辆和背景,则将类别数21改为2 - ./experiments/scripts/faster_rcnn_end2end.sh
修改line 53的finetune模型
开始训练
所有准备工作就绪,可以开始训练了1
./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc
训练结果在./output文件夹中,可直接使用。