[置顶] py-faster-rcnn + ZF 实现自己的数据训练与检测(二)

时间:2022-04-14 15:18:43

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等文件夹删除,在我的实验中,所需要的完整结构如下所示。

[置顶]        py-faster-rcnn + ZF 实现自己的数据训练与检测(二)

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即可得到如下的训练结果

[置顶]        py-faster-rcnn + ZF 实现自己的数据训练与检测(二)