0.前言
在前面的一篇博客中,介绍了如何实现py-faster-rcnn的配置以及在PASCAL VOC 2007上面的训练,本节,来讲诉如何制作并训练自己的数据集。如果自己使用的是matlab版本的faster rcnn的话,请移步这里:http://blog.csdn.net/sinat_30071459/article/details/50546891
1.制作自己的数据集
训练模型最头疼的估计就是数据集的整理与标记了,本例中我以人脸识别为例来说明数据集的安排。首先,这里为了方便,我没有更改VOC2007的任何格式,只是将data/VOCdevkit2007/VOC2007/Annotations和ImageSets以及JPEGImages文件夹的内容进行了替换。假设你的数据集已经进行了标记,所做的标记框已经输出到txt文档中,如下所示。
0001.jpg f 67 55 195 201
0001.jpg f 339 49 479 206
从左到右依次是图片名称,打框的标签和框的4个坐标
然后是将文档中的数据写入xml文件,如何制作数据可以参考这篇文章http://blog.csdn.net/liumaolincycle/article/details/50540487,这里不在赘述。不过和它不同的是,我为了方便,依然使用原有的数据集名称,只是对相应的文件进行了替换。最后是生成4个txt文档,分别为train.txt trainval.txt test.txt 和 val.txt。据我发现,在实验时好像只用到了trainval.txt和test.txt,他们两个构成完整的一个数据集。最后,可以将原有的一些SegmenttationClass和SegmentationObject等文件夹删除,在我的实验中,所需要的完整结构如下所示。
2.训练自己的数据
自己的数据集制作完成之后,就可以着手对文件进行修改以便训练了
(1)prototxt配置文件
file1:models/pascal_voc/ZF/faster_rcnn_alt_opt/stage1_rpn_train.pt
file2:models/pascal_voc/ZF/faster_rcnn_alt_opt/stage1_fast_rcnn_train.pt
file3:models/pascal_voc/ZF/faster_rcnn_alt_opt/stage2_rpn_train.pt
file4:models/pascal_voc/ZF/faster_rcnn_alt_opt/stage2_fast_rcnn_train.pt
file5:models/pascal_voc/ZF/faster_rcnn_alt_opt/fast_rcnn_test.pt修改上面5个pt文件,将类别数量改成自己的类别数量+1(检测时,背景也要作为1类),比如我的是人脸检测,就一个类别,就要将pt文件中的类别改为2,再将bbox预测层改为8(2*4),以stage1_fast_rcnn_train.pt为例
name: "ZF" layer { name: 'data' type: 'Python' top: 'data' top: 'rois' top: 'labels' top: 'bbox_targets' top: 'bbox_inside_weights' top: 'bbox_outside_weights' python_param { module: 'roi_data_layer.layer' layer: 'RoIDataLayer' param_str: "'num_classes': 2" } } ...... layer { name: "cls_score" type: "InnerProduct" bottom: "fc7" top: "cls_score" param { lr_mult: 1.0 } param { lr_mult: 2.0 } inner_product_param { num_output: 2 weight_filler { type: "gaussian" std: 0.01 } bias_filler { type: "constant" value: 0 } } } layer { name: "bbox_pred" type: "InnerProduct" bottom: "fc7" top: "bbox_pred" param { lr_mult: 1.0 } param { lr_mult: 2.0 } inner_product_param { num_output: 8 weight_filler { type: "gaussian" std: 0.001 } bias_filler { type: "constant" value: 0 } } }(2)修改lib/datasets/pascal_voc.py,将类别改成自己的类别
self._data_path = os.path.join(self._devkit_path, 'VOC' + self._year) self._classes = ('__background__', # always index 0 'face')(3) 修改py-faster-rcnn/lib/datasets/imdb.py
在使用自己的数据进行训练时,基本上都会报错:assert(boxes[:,2] >= boxes[:,0]).all() ,主要是因为自己的图片数据没有统一整理过而导致的,将该文件加入几行修改如下:
def append_flipped_images(self): num_images = self.num_images widths = self._get_widths() 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 boxes[:, 2] = widths[i] - oldx1 - 1 for b in range(len(boxes)): if boxes[b][2] < boxes[b][0]: boxes[b][0] = 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
如果是在报错之后再修改这个文件的话,记得在修改之后将data/cache/里面的pki文件删除后再重新运行
修改到这里时,训练前的准备工作已经完成了,现在可以直接进行训练。
cd py-faster-rcnn
./experiments/scripts/faster_rcnn_alt_opt.sh 0 ZF pascal_voc
训练完成之后,将output中的最终模型拷贝到data/faster_rcnn_models中,接下来测试训练完成的模型。
3.测试结果
修改./tools/demo.py
和上面的pascal_voc.py一样,将类别改成自己的类别,然后将加载的模型改为自己训练出来的模型。以我的为例
NETS = {'vgg16': ('VGG16', 'VGG16_faster_rcnn_final.caffemodel'), 'zf': ('ZF', 'ZF_faster_rcnn_final.caffemodel'), 'myzf': ('ZF', 'ZF_faster_rcnn_final_4000.caffemodel') }
执行./tools/demo.py --net myzf即可得到如下的训练结果