如何才能将faster rcnn 训练参数-cnn训练起来

深度学习实践经验:用Faster R-CNN训练Caltech数据集——训练检测
前面已经介绍了如何准备数据集,以及如何修改数据集读写接口来操作数据集,接下来我来说明一下怎么来训练网络和之后的检测过程。
修改模型文件
faster rcnn有两种各种训练方式:
Alternative training(alt-opt)
Approximate joint training(end-to-end)
两种方法有什么不同,可以参考我,推荐使用第二种,因为第二种使用的显存更小,而且训练会更快,同时准确率差不多,两种方式需要修改的代码是不一样的,同时faster rcnn提供了三种训练模型,小型的ZF model,中型的VGG_CNN_M_1024和大型的VGG16,论文中说VGG16效果比其他两个好,但是同时占用更大的GPU显存(~11GB)
我使用的是VGG model + alternative training,需要检测的类别只有一类,加上背景所以总共是两类(background + person)。
下面修改模型文件:
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage1_fast_rcnn_train.pt
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" #按训练集类别改,该值为类别数+1
name: "cls_score"
type: "InnerProduct"
bottom: "fc7"
top: "cls_score"
lr_mult: 1.0
lr_mult: 2.0
num_output: 2 #按训练集类别改,该值为类别数+1
weight_filler {
type: "gaussian"
type: "constant"
name: "bbox_pred"
type: "InnerProduct"
bottom: "fc7"
top: "bbox_pred"
lr_mult: 1.0
lr_mult: 2.0
num_output: 8 #按训练集类别改,该值为(类别数+1)*4,四个顶点坐标
weight_filler {
type: "gaussian"
std: 0.001
type: "constant"
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage1_rpn_train.pt
name: 'input-data'
type: 'Python'
top: 'data'
top: 'im_info'
top: 'gt_boxes'
python_param {
module: 'roi_data_layer.layer'
layer: 'RoIDataLayer'
param_str: "'num_classes': 2" #按训练集类别改,该值为类别数+1
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage2_fast_rcnn_train.pt
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" #按训练集类别改,该值为类别数+1
name: "cls_score"
type: "InnerProduct"
bottom: "fc7"
top: "cls_score"
lr_mult: 1.0
lr_mult: 2.0
num_output: 2 #按训练集类别改,该值为类别数+1
weight_filler {
type: "gaussian"
type: "constant"
name: "bbox_pred"
type: "InnerProduct"
bottom: "fc7"
top: "bbox_pred"
lr_mult: 1.0
lr_mult: 2.0
num_output: 8 #按训练集类别改,该值为(类别数+1)*4,四个顶点坐标
weight_filler {
type: "gaussian"
std: 0.001
type: "constant"
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage2_rpn_train.pt
name: 'input-data'
type: 'Python'
top: 'data'
top: 'im_info'
top: 'gt_boxes'
python_param {
module: 'roi_data_layer.layer'
layer: 'RoIDataLayer'
param_str: "'num_classes': 2" #按训练集类别改,该值为类别数+1
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/faster_rcnn_test.pt
name: "cls_score"
type: "InnerProduct"
bottom: "fc7"
top: "cls_score"
inner_product_param {
num_output: 2 #按训练集类别改,该值为类别数+1
name: "bbox_pred"
type: "InnerProduct"
bottom: "fc7"
top: "bbox_pred"
inner_product_param {
num_output: 84 #按训练集类别改,该值为(类别数+1)*4,四个顶点坐标
训练前还需要注意几个地方:
cache问题:
假如你之前训练了官方的VOC2007的数据集或其他的数据集,是会产生cache的问题的,建议在重新训练新的数据之前将其删除。
py-faster-rcnn/output
py-faster-rcnn/data/cache
参数放在如下文件:
py-faster-rcnn/models/pascal_voc/VGG16/faster_rcnn_alt_opt/stage_fast_rcnn_solver*.pt
base_lr: 0.001
lr_policy: 'step'
step_size: 30000
display: 20
迭代次数在文件py-faster-rcnn/tools/train_faster_rcnn_alt_opt.py中进行修改:
max_iters = [8, 8]
分别对应rpn第1阶段,fast rcnn第1阶段,rpn第2阶段,fast rcnn第2阶段的迭代次数,自己修改即可,不过注意这里的值不要小于上面的solver里面的step_size的大小,大家自己修改吧
首先修改experiments/scripts/faster_rcnn_alt_opt.sh成如下,修改地方已标注:
#!/bin/bash
export PYTHONUNBUFFERED="True"
NET_lc=${NET,,}
DATASET=$3
array=( $@ )
len=${#array[@]}
EXTRA_ARGS=${array[@]:3:$len}
EXTRA_ARGS_SLUG=${EXTRA_ARGS// /_}
case $DATASET in
TRAIN_IMDB="caltech_train"
TEST_IMDB="caltech_test"
PT_DIR="caltech"
ITERS=40000
echo "Not implemented: use experiments/scripts/faster_rcnn_end2end.sh for coco"
echo "No dataset given"
LOG="experiments/logs/faster_rcnn_alt_opt_${NET}_${EXTRA_ARGS_SLUG}.txt.`date +'%Y-%m-%d_%H-%M-%S'`"
exec && &(tee -a "$LOG")
echo Logging output to "$LOG"
time ./tools/train_faster_rcnn_alt_opt.py --gpu ${GPU_ID} \
--net_name ${NET} \
--weights data/imagenet_models/${NET}.v2.caffemodel \
--imdb ${TRAIN_IMDB} \
--cfg experiments/cfgs/faster_rcnn_alt_opt.yml \
${EXTRA_ARGS}
NET_FINAL=`grep "Final model:" ${LOG} | awk '{print $3}'`
time ./tools/test_net.py --gpu ${GPU_ID} \
--def models/${PT_DIR}/${NET}/faster_rcnn_alt_opt/faster_rcnn_test.pt \
--net ${NET_FINAL} \
--imdb ${TEST_IMDB} \
--cfg experiments/cfgs/faster_rcnn_alt_opt.yml \
${EXTRA_ARGS}
调用如下命令进行训练及测试,从上面代码可以看出,该shell文件在训练完后会接着进行测试,但是我的测试集没有标注,所以测试的时候会报错,但是由于Caltech数据集的测试结果有专门的评估代码,所以我不用faster r-cnn提供的代码进行测试,而是直接进行检测生成坐标,用专门的评估代码进行检测。
cd py-faster-rcnn
./experiments/scripts/faster_rcnn_alt_opt.sh 0 VGG16 caltech
参数1:指定gpu_id。
参数2:指定网络模型参数。
参数3:数据集名称,目前只能为pascal_voc。
在训练过程中,会调用py_faster_rcnn/tools/train_faster_rcnn_alt_opt.py文件开始训练网络。
可能会出现的Bugs
AssertionError: assert (boxes[:, 2] &= boxes[:, 0]).all()
在训练过程中可能会出现如下报错:
File "/py-faster-rcnn/tools/../lib/datasets/imdb.py", line 108, in
append_flipped_images
assert (boxes[:, 2] &= boxes[:, 0]).all()
AssertionError
检查自己数据发现,左上角坐标 (x, y) 可能为0,或标定区域溢出图片(即坐标为负数),而faster rcnn会对Xmin,Ymin,Xmax,Ymax进行减一操作,如果Xmin为0,减一后变为65535,从而在左右翻转图片时导致如上错误发生。
修改lib/datasets/imdb.py中的append_flipped_images()函数:
数据整理,在一行代码为 boxes[:, 2] = widths[i] - oldx1 - 1下加入代码:
for b in range(len(boxes)):
if boxes[b][2]& boxes[b][0]:
boxes[b][0] = 0
修改lib/datasets/caltech.py,_load_pascal_annotation()函数,将对Xmin,Ymin,Xmax,Ymax减一去掉,变为:
for ix, obj in enumerate(objs):
bbox = obj.find('bndbox')
x1 = float(bbox.find('xmin').text)
y1 = float(bbox.find('ymin').text)
x2 = float(bbox.find('xmax').text)
y2 = float(bbox.find('ymax').text)
cls = self._class_to_ind[obj.find('name').text.lower().strip()]
boxes[ix, :] = [x1, y1, x2, y2]
gt_classes[ix] = cls
overlaps[ix, cls] = 1.0
seg_areas[ix] = (x2 - x1 + 1) * (y2 - y1 + 1)
(可选)如果1和2可以解决问题,就没必要用方法3。修改lib/fast_rcnn/config.py,不使图片实现翻转,如下改为:
# Use horizontally-flipped images during training?
__C.TRAIN.USE_FLIPPED = False
如果如上三种方法都无法解决该问题,那么肯定是你的数据集坐标出现小于等于0的数,你应该一一排查。
训练fast rcnn时出现loss=nan的情况。
这是由于模型不收敛,导致loss迅速增长。
而我出现以上现象的原因主要是因为我在出现AssertionError的时候直接使用了第三种方法导致的。也就是禁用图片翻转。
启用图片翻转。
训练后的模型放在output/faster_rcnn_alt_opt/train/VGG16_faster_rcnn_final.caffemodel,该模型可以用于之后的检测。
经过以上训练后,就可以用得到的模型来进行检测了。检测所参考的代码是tools/demo.py,具体步骤如下:
将output/faster_rcnn_alt_opt/train/VGG16_faster_rcnn_final.caffemodel,拷贝到data/faster_rcnn_models下,命名为VGG16_Caltech_faster_rcnn__final.caffemodel
进入tools/文件夹中,拷贝demo.py为demo_caltech.py。
修改demo_caltech.py代码如下:
import matplotlib
matplotlib.use('Agg');
Demo script showing detections in sample images.
See README.md for installation instructions before running.
import _init_paths
from fast_rcnn.config import cfg
from fast_rcnn.test import im_detect
from fast_rcnn.nms_wrapper import nms
from utils.timer import Timer
import matplotlib.pyplot as plt
import numpy as np
import scipy.io as sio
import caffe, os, sys, cv2
import argparse
CLASSES = ('__background__',
NETS = {'vgg16': ('VGG16',
'VGG16_Caltech_faster_rcnn_final.caffemodel'),
'zf': ('ZF',
'ZF_Caltech_faster_rcnn_final.caffemodel')}
def vis_detections(im, image_name, class_name, dets, thresh=0.5):
"""Draw detected bounding boxes."""
inds = np.where(dets[:, -1] &= thresh)[0]
if len(inds) == 0:
im = im[:, :, (2, 1, 0)]
fig, ax = plt.subplots(figsize=(12, 12))
ax.imshow(im, aspect='equal')
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1]
ax.add_patch(
plt.Rectangle((bbox[0], bbox[1]),
bbox[2] - bbox[0],
bbox[3] - bbox[1], fill=False,
edgecolor='red', linewidth=3.5)
ax.text(bbox[0], bbox[1] - 2,
'{:s} {:.3f}'.format(class_name, score),
bbox=dict(facecolor='blue', alpha=0.5),
fontsize=14, color='white')
ax.set_title(('{} detections with '
'p({} | box) &= {:.1f}').format(class_name, class_name,
fontsize=14)
plt.axis('off')
plt.tight_layout()
plt.draw()
plt.savefig('/home/jk/py-faster-rcnn/output/faster_rcnn_alt_opt/test/'+image_name)
def demo(net, image_name):
"""Detect object classes in an image using pre-computed object proposals."""
im_file = os.path.join(cfg.DATA_DIR, 'VOCdevkit/Caltech/JPEGImages', image_name)
im = cv2.imread(im_file)
timer = Timer()
timer.tic()
scores, boxes = im_detect(net, im)
timer.toc()
print ('Detection took {:.3f}s for '
'{:d} object proposals').format(timer.total_time, boxes.shape[0])
CONF_THRESH = 0.85
NMS_THRESH = 0.3
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1
cls_boxes = boxes[:, 4*cls_ind:4*(cls_ind + 1)]
cls_scores = scores[:, cls_ind]
dets = np.hstack((cls_boxes,
cls_scores[:, np.newaxis])).astype(np.float32)
keep = nms(dets, NMS_THRESH)
dets = dets[keep, :]
vis_detections(im, image_name, cls, dets, thresh=CONF_THRESH)
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='vgg16')
args = parser.parse_args()
return args
if __name__ == '__main__':
cfg.TEST.HAS_RPN = True
args = parse_args()
prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
'faster_rcnn_alt_opt', 'faster_rcnn_test.pt')
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()
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)
im = 128 * np.ones((300, 500, 3), dtype=np.uint8)
for i in xrange(2):
_, _= im_detect(net, im)
testfile_path = '/home/jk/py-faster-rcnn/data/VOCdevkit/Caltech/ImageSets/Main/test.txt'
with open(testfile_path) as f:
im_names = [x.strip()+'.jpg' for x in f.readlines()]
for im_name in im_names:
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
print 'Demo for data/demo/{}'.format(im_name)
demo(net, im_name)
plt.show()
在命令行中输入一下命令进行检测:
python tools/demo_caltech.py
放几张检测后的结果图,感觉检测效果并不是很好,很多把背景当成行人的错误:
看过本文的人也看了:
我要留言技术领域:
取消收藏确定要取消收藏吗?
删除图谱提示你保存在该图谱下的知识内容也会被删除,建议你先将内容移到其他图谱中。你确定要删除知识图谱及其内容吗?
删除节点提示无法删除该知识节点,因该节点下仍保存有相关知识内容!
删除节点提示你确定要删除该知识节点吗?5128人阅读
caffe实践(7)
深度学习(4)
人脸识别(5)
在前面的一篇博客中,介绍了如何实现py-faster-rcnn的配置以及在PASCAL VOC 2007上面的训练,本节,来讲诉如何制作并训练自己的数据集。如果自己使用的是matlab版本的faster rcnn的话,请移步这里:http://blog.csdn.net/sinat_/article/details/
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/,这里不在赘述。不过和它不同的是,我为了方便,依然使用原有的数据集名称,只是对相应的文件进行了替换。最后是生成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.ptfile3: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.ptfile5: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&
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
    }
  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即可得到如下的训练结果
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:58351次
排名:千里之外
原创:21篇
评论:117条2321人阅读
Linux系统(35)
深度学习(45)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 跑个demo累的半死
前后不同时间不同电脑跑了三次,所有问题应该都碰到过了。
Faster R-CNN教程
本教程主要基于python版本的,因为python layer的使用,这个版本会比的版本速度慢10%,但是准确率应该是差不多的。
目前已经实现的有两种方式:
Alternative trainingApproximate joint training
推荐使用第二种,因为第二种使用的显存更小,而且训练会更快,同时准确率差不多甚至略高一点。
配置环境安装步骤Demo建立自己的数据集训练和检测
1配置python layers
WITH_PYTHON_LAYER := 1
USE_CUDNN := 1
2安装几个依赖cython, python-opencv, easydict
sudo apt-get install python-opencv
sudo pip install cython easydict
& 注:有时候不能加sudo, 多试
git clone --recursive https:
2编译Cython模块
cd $FRCN_ROOT/lib
3编译caffe和pycaffe
cd $FRCN_ROOT/caffe-fast-rcnn
make -j8 && make pycaffe
安装步骤完成后,就可以运行一下demo了。
cd $FRCN_ROOT
./tools/demo.py
&注:有时候报错:permission denied
如果sudo不行,用下面一句:
&chmod 777 ./tools/demo.py
&&& 这是执行以上步骤遇到的其中两个问题百度到的解决方案,python-yaml 安装,我的unbuntu14.04直接用
sudo apt-get install python-yaml,如图:
问题二:显卡不行
将demo.py 的net 改为default=ZF((不对!!!是小写zf!!!细心!!)
<span style="font-size:24 color:#ff.11.02 第二次跑多出现几个错误 折腾!!!:
ImportError:can not find module skimage.io
ImportError: No module named google.protobuf
此时只要按照以下命令操作即可:
$ sudo apt-get install python-numpy python-scipy python-matplotlib python-sklearn python-skimage python-h5py python-protobuf python-leveldb python-networkx python-nose python-pandas python-gflags
Cython ipython
pip install protobuf
在caffe-master目录下:
$ make pycaffe
cd $FRCN_ROOT
./tools/demo.py
报错:permission denied
方法一:chmod a&#43;x tools/demo.py
方法二:&& python ./tools/demo.py
方法二解决问题,但是有新的错误:
&& from nms.cpu_nms import cpu_nms
ImportError: /media/jing/000A9C/py-faster-rcnn/tools/../lib/nms/cpu_nms.so: undefined symbol: PyFPE_jbuf
在博客/justinzhang/p/5386837.html找到解决方法:在根目录下的lib/fast_rcnn里找到nms_wrapper.py:注释一句话from nms.cpu_nms import cpu_nms,如图:
& python ./tools/demo.py
大功告成:
第二次换了图片:
我的安装主要参考以下三个博客:
/wangxiaocvpr/p/5717018.html
/CarryPotMan/p/5390336.html
http://blog.csdn.net/helloeveryon/article/details/
我跑的结果::
一直纠结这么犀利的cnn怎么会有误报?可能模型不够好,
解决方法:
将cudnn 打开, 可以恢复 default= vgg16 这样误报没啦!!!cudnn配置见
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:136244次
积分:2548
积分:2548
排名:第14283名
原创:115篇
转载:61篇
评论:41条
(6)(6)(2)(2)(4)(12)(12)(9)(9)(47)(47)(21)deep learning(3)
Caffe学习系列——6使用Faster-RCNN进行目标检测
由于要实现服装的目标检测,所以一直在研究Faster-RCNN 。讲到目标检测,不得不提到rbg大神的深度神经网络检测算法系列RCNN、Fast-RCNN、Faster-RCNN,其还在github上开源了自己的代码,造福广大码农。这是rbg大神的主页
,以及本篇博文会用到的Faster-RCNN的github源码地址
,欢迎前去膜拜学习。对于RCNN、Fast-RCNN、Faster-RCNN的介绍就不在这里赘述了,可以看看我的上一篇博文 。该github源码是Faster-RCNN python版本的实现,并使用caffe。除了python版本,rbg大神还提供了matlab代码。这两种实现方式有些许的不同,主要体现在以下几点:
由于使用了python layer,python版本的在测试时间上会比matlab版本的慢10%左右,但是准确率差不多甚至略高一点。由于在实现方式上有一点点不同,所以使用MATLAB代码训练的模型与Python版本的不兼容目前已经实现的方式有两种:Alternative training和Approximate join training。推荐使用第二种,因为第二种使用的显存更小,而且训练会更快。
本篇博文主要分为两部分,第一部分讲如何配置py-faster-rcnn并训练PASCALVOC2007,运行demo。第二部分讲如何对代码和数据集进行修改实现自己数据的训练与检测。
配置与运行Demo
这个过程主要是跟着github上的说明: 走了一遍用以熟悉用Faster-RCNN进行目标检测的过程。
1.配置、编译与安装环境
在进行这一步之前,需已经在自己的机器上配置好caffe环境以及各种依赖项的安装,在配置之前,需确保已经安装以下几个python包:cython、easydict和python-opencv。安装命令如下:
pip install cython pip install easydict apt-get install python-opencv
从github上clone项目,注意!一定要在clone时加入–recursive参数,不然会很麻烦,也不要直接下载,在机器上装个git来clone,这样会省去很多时间。
git clone –recursive
Cython模块编译
cd $FRCN_ROOT /lib
caffe和pycaffe的编译
在编译之前,需要复制$FRCN_ROOT/caffe-fast-rcnn 的Makefile.config.example,然后重命名为Makefile.config。
需要注意的是里面有几个配置需要添加
打开USE_CUDNN=1,这个选项默认情况下是关闭的,需要打开让CUDA支持DNN
打开WITH_PYTHON_LAYER=1,默认关闭,需打开,因为FasterRCNN需要支持Python接口。
执行以下命令进行编译
cd $FRCN_ROOT/caffe-fast-rcnn
make -j8 && make pycaffe
2.运行demo
下载训练好的模型,下载后这个faster_rcnn_models文件夹在$FRCN_ROOT/data下面,可以从data/README.md中查看关于这个的详细介绍。这些模型是在VOC 2007 上训练的。
cd $FRCN_ROOT
./data/scripts/fetch_faster_rcnn_models.sh
这里有个小建议,就是下载模型时,直接去脚本文件中复制URL使用迅雷下载更快。
cd $FRCN_ROOT
./tools/demo.py
这个demo展示了使用在PASCAL VOC 2007上训练的VGG16网络来进行目标检测。运行结果如下图所示:
3.训练PASCAL VOC 2007的数据集
下载训练、验证以及测试集和VOCdevkit
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.ta
解压后的文件结构如下
$VOCdevkit/
# 开发工具包$VOCdevkit/VOCcode/
# VOC实用代码$VOCdevkit/VOC2007# 图片集, 注释, 等等# 一些其他的目录
将VOCdevkit改名为VOCdevkit2007,然后放到data文件夹下,亦可以使用软连接的方式,
cd $FRCN_ROOT/data
ln -s $VOCdevkit VOCdevkit2007
下载预训练的ImageNet模型
cd $FRCN_ROOT
./data/scripts/fetch_imagenet_models.sh
VGG16来自,ZF是由MSRA训练的结构
(1) 使用交替优化(alternating optimization)算法来训练和测试Faster R-CNN
cd $FRCN_ROOT./experiments/scripts/faster_rcnn_alt_opt.sh [GPU_ID] [NET] [--set ...]# GPU_ID是你想要训练的GPUID# 你可以选择如下的网络之一进行训练:ZF, VGG_CNN_M_1024, VGG16# --set ... 运行你自定义fast_rcnn.config参数,例如.#
--set EXP_DIR seed_rng1701 RNG_SEED 1701#例如命令./experiments/scripts/faster_rcnn_alt_opt.sh 0 ZF pascal_voc
输出的结果在 $FRCN_ROOT/output下。训练过程截图:
(2) 使用近&#20284;联合训练( approximate joint training)
cd $FRCN_ROOT
./experiments/scripts/faster_rcnn_end2end.sh [GPU_ID] [NET] [--set ...]
这个方法是联合RPN模型和Fast R-CNN网络训练。而不是交替训练。用此种方法比交替优化快1.5倍,但是准确率相近。所以推荐使用这种方法
训练Fast R-CNN网络的结果保存在这个目录下:
output/&experiment directory&/&dataset name&/
测试保存在这个目录下:
output/&experiment directory&/&dataset name&/&network snapshot name&/
4.遇到的问题
TypeError: ‘numpy.float64’ object cannot be interpreted as an index
这个错误是$FRCN_ROOT/lib/roi_data_layer下的minibatch.py中的npr.choice引起的,所以需要改成ruxia所示
if fg_inds.size & 0:
for i in range(0,len(fg_inds)):
fg_inds[i] = int(fg_inds[i])
fg_inds = npr.choice(fg_inds, size=int(fg_rois_per_this_image), replace=False)
注意有两个npr.choice,所以两个地方都按照如上来改。
labels[fg_rois_per_this_image:] = 0
TypeError: slice indices must be integers or None or have an index method
这个错误是由numpy的版本引起的,只要将fg_rois_per_this_image强制转换为int型就可以了
labels[int(fg_rois_per_this_image):] = 0
使用Faster-RCNN训练自己的数据集
1.工程目录简介
由于需要训练自己的数据集,所以需要对这个工程各个目录的作用有所了解
caffe-fast-rcnn:caffe框架目录data:用来存放pretrained模型以及读取文件的cache缓存,还有一些下载模型的脚本experiments:存放配置文件以及运行的log文件,另外这个目录下有scripts,里面存放end2end和alt_opt两种训练方式的脚本lib:用来存放一些python接口文件,如其下的datasets主要负责数据库读取,config负责一些训练的配置选项models:里面存放了三个模型文件,小型网络ZF,中型网络VGG_CNN_M_1024以及大型网络VGG16,根据你的硬件条件来选择使用哪种网络,ZF和VGG_CNN_M_1024需要至少3G内存,VGG16需要更多的内存,但不会超过11G。output:这里存放的是训练完成后的输出目录,这是运行了训练后才会出现的目录tools:里面存放的是训练和测试的Python文件
2.创建数据集
我个人觉得训练模型最头疼的是数据集的准备,本文我以服装的识别为例来说明如何用自己的数据集进行目标检测。在准备数据集的时候,假如你是第一次用自己的数据集进行训练,那么最好是参照上一章节跑的demo中的VOC2007数据集的&#26684;式来准备,这样,关于后续训练过程会涉及到的配置更改会较为简单,比较容易成功。在本次的训练过程中,我使用的是由香港中文大学提供的服装标记相关的数据集,在此特别感谢一下他们愿意将数据集公开。想要获取他们的数据集只需要发邮件申请即可。基于上述已标记的数据集,可将数据集整理得到如下所示的&#26684;式:
0000001.jpg Blouse 72 79 232 273
0000002.jpg Shorts 67 59 155 161
如果一张图片有多个目标,则&#26684;式如下:(比如两个目标)
000002.jpg dog 44 28 132 121
000002.jpg car 50 27 140 110
将上述的txt转成xml,可参考如下matlab代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
%%%该代码可以做voc2007数据集中的xml文件,%txt文件每行&#26684;式为:0000001.jpg Tee 44 28 132 121%即每行由图片名、目标类型、包围框坐标组成,空&#26684;隔开%包围框坐标为左上角和右下角%@author:bealin%%%注意修改下面四个变量imgpath='/home/linbiyuan/py-faster-rcnn/data/VOCdevkit2007/VOC2007/JPEGImages/';%图像存放文件夹txtpath='/home/linbiyuan/py-faster-rcnn/data/VOCdevkit2007/VOC2007/alldata.txt';%txt文件xmlpath_new='/home/linbiyuan/py-faster-rcnn/data/VOCdevkit2007/VOC2007/Annotations/';%修改后的xml保存文件夹foldername='VOC2007';%xml的folder字段名fidin=fopen(txtpath,'r');while ~feof(fidin)
tline=fgetl(fidin);
str = regexp(tline, ' ','split');
filepath=[imgpath,str{1}];
img=imread(filepath);
[h,w,d]=size(img);
rectangle('Position',[str2double(str{3}),str2double(str{4}),str2double(str{5})-str2double(str{3}),str2double(str{6})-str2double(str{4})],'LineWidth',4,'EdgeColor','r');
Createnode=com.mathworks.xml.XMLUtils.createDocument('annotation');
Root=Createnode.getDocumentE%根节点
node=Createnode.createElement('folder');
node.appendChild(Createnode.createTextNode(sprintf('%s',foldername)));
Root.appendChild(node);
node=Createnode.createElement('filename');
node.appendChild(Createnode.createTextNode(sprintf('%s',str{1})));
Root.appendChild(node);
source_node=Createnode.createElement('source');
Root.appendChild(source_node);
node=Createnode.createElement('database');
node.appendChild(Createnode.createTextNode(sprintf('My Database')));
source_node.appendChild(node);
node=Createnode.createElement('annotation');
node.appendChild(Createnode.createTextNode(sprintf('VOC2007')));
source_node.appendChild(node);
node=Createnode.createElement('image');
node.appendChild(Createnode.createTextNode(sprintf('flickr')));
source_node.appendChild(node);
node=Createnode.createElement('flickrid');
node.appendChild(Createnode.createTextNode(sprintf('NULL')));
source_node.appendChild(node);
owner_node=Createnode.createElement('owner');
Root.appendChild(owner_node);
node=Createnode.createElement('flickrid');
node.appendChild(Createnode.createTextNode(sprintf('NULL')));
owner_node.appendChild(node);
node=Createnode.createElement('name');
node.appendChild(Createnode.createTextNode(sprintf('lby')));
owner_node.appendChild(node);
size_node=Createnode.createElement('size');
Root.appendChild(size_node);
node=Createnode.createElement('width');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(w))));
size_node.appendChild(node);
node=Createnode.createElement('height');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(h))));
size_node.appendChild(node);
node=Createnode.createElement('depth');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(d))));
size_node.appendChild(node);
node=Createnode.createElement('segmented');
node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
Root.appendChild(node);
object_node=Createnode.createElement('object');
Root.appendChild(object_node);
node=Createnode.createElement('name');
node.appendChild(Createnode.createTextNode(sprintf('%s',str{2})));
object_node.appendChild(node);
node=Createnode.createElement('pose');
node.appendChild(Createnode.createTextNode(sprintf('%s','Unspecified')));
object_node.appendChild(node);
node=Createnode.createElement('truncated');
node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
object_node.appendChild(node);
node=Createnode.createElement('difficult');
node.appendChild(Createnode.createTextNode(sprintf('%s','0')));
object_node.appendChild(node);
bndbox_node=Createnode.createElement('bndbox');
object_node.appendChild(bndbox_node);
node=Createnode.createElement('xmin');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{3}))));
bndbox_node.appendChild(node);
node=Createnode.createElement('ymin');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{4}))));
bndbox_node.appendChild(node);
node=Createnode.createElement('xmax');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{5}))));
bndbox_node.appendChild(node);
node=Createnode.createElement('ymax');
node.appendChild(Createnode.createTextNode(sprintf('%s',num2str(str{6}))));
bndbox_node.appendChild(node);
lastname=str{1};
tempname=strrep(lastname,'.jpg','.xml');
xmlwrite(tempname,Createnode);
fprintf('%s\n',tempname);endfclose(fidin);
由于我的数据集是单标签的,所以这份代码是针对单标签来生成xml。假如你的数据集是多标签的,txt的&#26684;式可前所示,而相应的matlab代码做出一点修改即可。生成的xml&#26684;式如下
这份代码运行生成的xml文件是在当前目录下的,所以还需要将所有的xml放到VOC2007下的Annotations中,可参考如下linux命令:
for xml in *.do mv $xml Annotations/;done
将所有的训练图片放到JPEGImages文件夹中,生成ImageSet\Main里的四个txt文件,分别是:trainval.txt(训练和验证集总和)、train.txt(训练集)、val.txt(验证集)、test.txt(测试集),trainval集占整个数据集的70%,train集占trainval集的70%,val集占trainval集的30%,test集占整个数据集的30%。可参考以下代码进行数据集的划分:
123456789101112131415161718192021222324252627282930313233343536373839
%%%该代码根据已生成的xml,制作VOC2007数据集中的trainval.train.test.txt和val.txt%trainval占总数据集的70%,test占总数据集的30%;train占trainval的70%,val占trainval的30%;%上面所占百分比可根据自己的数据集修改%注意修改下面两个路径xmlfilepath='/home/linbiyuan/py-faster-rcnn/data/VOCdevkit2007/VOC2007/Annotations';txtsavepath='/home/linbiyuan/py-faster-rcnn/data/VOCdevkit2007/VOC2007/ImageSets/Main/';xmlfile=dir(xmlfilepath);numOfxml=length(xmlfile)-2;%减去.和..
总的数据集大小trainval=sort(randperm(numOfxml,floor(numOfxml*0.7)));%trainval为数据集的50%test=sort(setdiff(1:numOfxml,trainval));%test为剩余50%trainvalsize=length(trainval);%trainval的大小train=sort(trainval(randperm(trainvalsize,floor(trainvalsize*0.7))));val=sort(setdiff(trainval,train));ftrainval=fopen([txtsavepath 'trainval.txt'],'w');ftest=fopen([txtsavepath 'test.txt'],'w');ftrain=fopen([txtsavepath 'train.txt'],'w');fval=fopen([txtsavepath 'val.txt'],'w');for i=1:numOfxml
if ismember(i,trainval)
fprintf(ftrainval,'%s\n',xmlfile(i&#43;2).name(1:end-4));
if ismember(i,train)
fprintf(ftrain,'%s\n',xmlfile(i&#43;2).name(1:end-4));
fprintf(fval,'%s\n',xmlfile(i&#43;2).name(1:end-4));
fprintf(ftest,'%s\n',xmlfile(i&#43;2).name(1:end-4));
endendfclose(ftrainval);fclose(ftrain);fclose(fval);fclose(ftest);
至此,数据集的构建就完成啦,你可以新建一个文件夹,将上述三个文件夹放到里面去,也可将上述三个文件夹分贝替换VOC2007数据集中的Annotations、ImageSets和JPEGImages,这样可免去一些训练的修改。本文选择的是替换~
3.训练自己的数据
1. 修改prototxt配置文件
这些配置文件都在models下的pascal_voc下。里面有三种网络结构:ZF、VGG16、VGG_CNN_M_1024,本文选择的是VGG_CNN_M_1024 。每个网络结构中都有三个文件夹,分别是faster_rcnn_end2end、faster_rcnn_alt_opt、faster_rcnn。使用近&#20284;联合训练,比交替优化快1.5倍,但是准确率相近,所以推荐使用这种方法。更改faster_rcnn_end2end文件夹下的train.prototxt和test.prototxt,train中需要更改的地方有三处,
第一处是input-data层,将原先的21改成:你的实际类别数&#43;1(背景),我目标检测一共有46类,所以加上背景这一类,一共47类。
第二处是cls_score层
第三处是bbox_pred,这里需将原来的84改成(你的类别数&#43;1)4,即(46&#43;1)4=188
test.prototxt中没有input-data层,所以只需按照train中的修改cls_score层以及bbox_pred层即可
2. 修改lib/datasets/pascal_voc.py,将类别改成自己的类别
这里有一个注意点就是,这里的类别以及你之前的类别名称最好是全部小写,假如是大写的话,则会报keyError的错误,这时只需要在pascal_voc。py中第218行的lower去掉即可
datasets目录下主要有三个文件,分别是
(1) factory.py:这是一个工厂类,用类生成imdb类并且返回数据库供网络训练和测试使用;
(2) imdb.py:是数据库读写类的基类,封装了许多db的操作;
(3) pascl_voc.pyRoss用这个类来操作
3. 修改py-faster-rcnn/lib/datasets/imdb.py
在使用自己的数据进行训练时,假如你的数据集中的图片没有统一整理过就会报 assert(boxes[:,2] &= boxes[:,0]).all() 这个错误,故需在imdb.py中加入如下几行
4. 开始训练
cd py-faster-rcnn
./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc
由于训练过程太长,可以将训练过程产生的输出定向输入到log文件中,这样可方便查看。只需在上述命令中加入定向输入的命令即可,如下:
./experiments/scripts/faster_rcnn_end2end.sh 0 VGG_CNN_M_1024 pascal_voc & /home/lby/log/clothdirector.log 2&&1
!!!训练前需要将cache中的pki文件以及VOCdevkit2007中annotations_cache的缓存删掉。
训练过程中会遇到的问题
roidb[i][‘image’] = imdb.image_path_at(i)
IndexError: list index out of range
解决方法:删除data/cache里面的pki文件
注意:不管在训练过程中遇到什么问题,修正过后,重新训练之前都需要将cache中的pki文件删除之后再重新运行,R = [obj for obj in recs[imagename] if obj[‘name’] == classname]
KeyError: ‘0000001’
这是在测试时出现错误,删掉VOCdevkit2007中annotations_cache的缓存
4.测试结果
训练完成之后,将output中的最终模型拷贝到data/faster_rcnn_models,修改tools下的demo.py,我是使用VGG_CNN_M_1024这个中型网络,不是默认的ZF,所以要改的地方挺多
1. 修改class
123456789101112
CLASSES = ('__background__',
'Blouse', 'Sweatpants', 'Cardigan', 'Button-Down',
'Cutoffs', 'Chinos', 'Top', 'Anorak', 'Kimono',
'Tank', 'Robe', 'Parka', 'Jodhpurs',
'Halter', 'Shorts', 'Caftan','Turtleneck',
'Leggings', 'Joggers', 'Hoodie', 'Culottes',
'Sweater', 'Flannel', 'Jeggings', 'Blazer',
'Onesie', 'Coat', 'Henley', 'Jacket',
'Trunks', 'Gauchos', 'Sweatshorts', 'Romper',
'Jersey', 'Bomber', 'Sarong', 'Dress','Jeans',
'Tee', 'Coverup', 'Capris', 'Kaftan','Peacoat',
'Poncho', 'Skirt', 'Jumpsuit')
2. 增加你自己训练的模型
NETS = {'vgg16': ('VGG16',
'VGG16_faster_rcnn_final.caffemodel'),
'zf': ('ZF',
'ZF_faster_rcnn_final.caffemodel'),
'myvgg1024':('VGG_CNN_M_1024','vgg_cnn_m_1024_faster_rcnn_iter_70000.caffemodel')}
3. 修改prototxt,如果你用的是ZF,就不用改了
prototxt = os.path.join(cfg.MODELS_DIR, NETS[args.demo_net][0],
'faster_rcnn_end2end', 'test.prototxt')
4. 开始检测
执行 ./tools/demo.py –net myvgg1024
假如不想那么麻烦输入参数,可以在demo的parse_args()里修改默认参数
parser.add_argument(‘–net’, dest=’demo_net’, help=’Network to use [myvgg1024]’,
choices=NETS.keys(), default=’myvgg1024’)
这样只需要输入 ./tools/demo.py 就可以了
检测结果:
遇到的问题
Cannot copy param 0 weights from layer“”:已放弃(核心已转储)
没有修改prototxt,详情请见第3步
Makefile:2: recipe for target ‘all’ failed
Traceback (most recent call last):
File “setup.py”, line 59, in
CUDA = locate_cuda()
File “setup.py”, line 56, in locate_cuda
raise EnvironmentError(‘The CUDA %s path could not be located in %s’ % (k, v))
EnvironmentError: The CUDA lib64 path could not be located in /usr/lib64
Makefile:2: recipe for target ‘all’ failed
解决方法:打开 setup.py,把lib64改为lib
cudaconfig = {‘home’:home, ‘nvcc’:nvcc,
'include': pjoin(home, 'include'),
'lib64': pjoin(home, 'lib')}
make error:command ‘/usr/local/bin/nvcc’ failed with exit status 1
添加 export PATH=/usr/local/cuda/bin:”$PATH” 到你的 ~/.bashrc
Please enable JavaScript to view the &a href=&///?ref_noscript&&comments powered by duoshuo.&/a&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1199次
排名:千里之外

我要回帖

更多关于 faster rcnn 训练参数 的文章

 

随机推荐