Table of Contents
环境:
系统:Ubuntu 16.0.4
GPU: NNIFIA GTX1080Ti
框架:caffe
语言:python
Faster RCNN源码:https://github.com/rbgirshick/py-faster-rcnn
一、PASCAL VOC 2007/2012格式数据集制作
PASCAL VOC 2007/2012数据集的制作:VOC2007格式数据集制作
将制作的数据集放在py-faster-rcnn-master\data下。最后完整的路径是py-faster-rcnn-master\data\VOCdevkit2007
二、训练自己的数据集
Faster RCNN默认有三种网络模型 ZF(小)、VGG_CNN_M_1024(中)、VGG16 (大)
每一个Faster RCNN模型都有两种训练方式:
- 一种是交替优化方法(alternating optimization),即训练两个网络,一个是rpn,一个是fast rcnn,总计两个stage,每个stage各训练一次rpn和fast rcnn。
- 另外一种训练方式为近似联合训练(approximate joint training),也称end to end的训练方式,训练过程中只训练一个权重网络,训练速度有可观的提升,而训练精度不变。
此处以VGG_CNN_M_1024的end2ent(也叫近似联合训练)为例。
- 修改模型配置文件
以vgg_cnn_m_1024为例,用end2end的方式训练。
(1) 打开py-faster-rcnn\models\pascal_voc\VGG_CNN_M_1024\faster_rcnn_end2end\train.prototxt修改4处
(2)打开py-faster-rcnn\models\pascal_voc\VGG_CNN_M_1024\faster_rcnn_end2end\ test.prototxt修改2处。 - 修改py-faster-rcnn\lib\datasets下的imdb.py文件
在使用自己的数据进行训练时,基本上都会报错:assert(boxes[:,2] >= boxes[:,0]).all() ,主要是因为自己的图片数据没有统一整理过而导致的,将该文件加入几行修改如下:
找到append_flipped_images这个函数 - 修改py-faster-rcnn\lib\fast_rcnn文件夹下的config.py
将训练和测试的proposals方法改为gt# Train using these proposals # __C.TRAIN.PROPOSAL_METHOD = 'selective_search' __C.TRAIN.PROPOSAL_METHOD = 'gt'
# Test using these proposals # __C.TEST.PROPOSAL_METHOD = 'selective_search' __C.TEST.PROPOSAL_METHOD = 'gt'
- 修改py-faster-rcnn\lib\datasets下的pascal_voc.py
在self.classes里,'__background__'是我们的背景类,不要动他。下面的改为你自己标签的内容。如下图:
为避免路径出错问题,如下图:
解决方案一:Evaluating detections Writing knife VOC results file Traceback (most recent call last): File "./tools/test_net.py", line 90, in <module> test_net(net, imdb, max_per_image=args.max_per_image, vis=args.vis) File "/home/root1/py-faster-rcnn/tools/../lib/fast_rcnn/test.py", line 295, in test_net imdb.evaluate_detections(all_boxes, output_dir) File "/home/root1/py-faster-rcnn/tools/../lib/datasets/pascal_voc.py", line 317, in evaluate_detections self._write_voc_results_file(all_boxes) File "/home/root1/py-faster-rcnn/tools/../lib/datasets/pascal_voc.py", line 244, in _write_voc_results_file with open(filename, 'wt') as f: IOError: [Errno 2] No such file or directory: '/home/root1/py-faster-rcnn/data/VOCdevkit2007/results/VOC2007/Main/comp4_f5c36aae-200c-4e8a-9eda-2d5a10a5acd7_det_test_knife.txt'
检查py-faster-rcnn\data\VOCdevkit2007目录下是否存在results\VOC2007\Main\,如果不存在,需要手动创建。形成py-faster-rcnn\data\VOCdevkit2007\results\VOC2007\Main\
三、end2end训练
- 删除缓存文件
(1) py-faster-rcnn/output文件夹删除,
(2)删除py-faster-rcnn/data/cache中的文件
(3)删除py-faster-rcnn/data/VOCdevkit2007/annotations_cache中的文件
- 开始训练
打开打开终端,去到py-faster-rcnn根目录下,运行以下的语句
出现以下这种界面,那就是训练成功了。./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc
-
训练中可测碰到的错误
错误一:I1116 20:28:35.41Loading pretrained model weights from data/imagenet_models/VGG_CNN_M_1024.v2.caffemodel
*** Check failure stack trace: ***
这是因为没有找到预训练的model
解决办法:下载imagenet_models.rar解压至py-faster-rcnn\data目录下
下载地址:https://dl.dropbox.com/s/gstw7122padlf0l/imagenet_models.tgz?dl=0
错误二:
TypeError: slice indices must be integers or None or have an __index__ method
解决办法:
在文件夹py-faster-rcnn\lib\roi_data_layer中找到minibatch.py第172行和proposal_target_layer.py第123行,修改代码。# 将_get_bbox_regression_labels函数和_get_bbox_regression_labels函数中的以下代码 for ind in inds: cls = clss[ind] start = 4 * cls end = start + 4 bbox_targets[ind, start:end] = bbox_target_data[ind, 1:] bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS # 修改为以下的代码 for ind in inds: ind = int(ind) cls = clss[ind] start = int(4 * cls) end = int(start + 4) bbox_targets[ind, start:end] = bbox_target_data[ind, 1:] bbox_inside_weights[ind, start:end] = cfg.TRAIN.BBOX_INSIDE_WEIGHTS
错误三:
TypeError: ‘numpy.float64’ object cannot be interpreted as an index
原因:这个问题是numpy版本导致的。不支持网上很多答案说的降低版本的方法,更稳妥的办法是修改工程代码。这里给出解决方案。
解决办法:参考:使用faster-rcnn训练数据集numpy相关问题
1、修改minibatch.py文件,如下图:
下面一处在错误二中也有修改,两者要综合起来
2、修改#lib/datasets/ds_utils.py文件
3、修改#lib/fast_rcnn/test.py文件
4、修改#lib/rpn/proposal_target_layer.py文件
四、测试
- 创建自己的demo.py
如果想方便的话,直接把已经有的demo.py复制一份,并把它的标签改为自己的标签,把模型改为自己的模型。这是我的demo,类别和模型部分,供参考
CLASSES = ('__background__', 'knife') # 第一个背景类不需要修改,其它修改为自己识别的类 NETS = {'vgg16': ('VGG16', 'VGG16_faster_rcnn_final.caffemodel'), 'vgg1024':('VGG_CNN_M_1024', # 在这里添加自己的训练出来的模型 'vgg_cnn_m_1024_faster_rcnn_iter_70000.caffemodel'), 'zf': ('ZF', 'ZF_faster_rcnn_final.caffemodel')}
def parse_args(): """Parse input arguments.""" parser = argparse.ArgumentParser(description='Faster R-CNN demo') parser.add_argument('--gpu', dest='gpu_id', help='GPU device id to use [0]', default=0, type=int) parser.add_argument('--cpu', dest='cpu_mode', help='Use CPU mode (overrides --gpu)', action='store_true') parser.add_argument('--net', dest='demo_net', help='Network to use [vgg16]', choices=NETS.keys(), default='vgg1024') # 将这里的默认改为vgg1024,因为我们使用的是vgg1024 args = parser.parse_args() return args
在这个部分,将你要测试的图片写在im_names里,并把图片放在data\demo这个文件夹下。
if __name__ == '__main__': cfg.TEST.HAS_RPN = True # Use RPN for proposals args = parse_args() prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0], 'faster_rcnn_end2end', 'test.prototxt') # 这里修改为自己的测试prototxt caffemodel = os.path.join(cfg.DATA_DIR, 'faster_rcnn_models', NETS[args.demo_net][1]) if not os.path.isfile(caffemodel): raise IOError(('{:s} not found.\nDid you run ./data/script/' 'fetch_faster_rcnn_models.sh?').format(caffemodel)) if args.cpu_mode: caffe.set_mode_cpu() else: caffe.set_mode_gpu() caffe.set_device(args.gpu_id) cfg.GPU_ID = args.gpu_id net = caffe.Net(prototxt, caffemodel, caffe.TEST) print '\n\nLoaded network {:s}'.format(caffemodel) # Warmup on a dummy image im = 128 * np.ones((300, 500, 3), dtype=np.uint8) for i in xrange(2): _, _= im_detect(net, im) im_names = ['000016.jpg','000024.jpg'] # 这里修改为自己需要识别的图片,并将其放入data/demo目录下 for im_name in im_names: print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' print 'Demo for data/demo/{}'.format(im_name) demo(net, im_name) plt.show()
-
输出的模型
训练好的模型在py-faster-rcnn\output\目录下
将output\里你刚刚训练好的caffemodel复制到data\faster_rcnn_models -
结果
在py-faster-rcnn/tools目录下,执行以下命令./demo.py
即可得到结果