本文安装python版本的faster-rcnn项目。
matlab版本请移步:https://github.com/ShaoqingRen/faster_rcnn
python版本项目主页:https://github.com/rbgirshick/py-faster-rcnn
下面分两部分来讲解,第一部分为py-faster-rcnn及caffe框架安装。第二部分讲解如何修改相关文件,训练自己的数据集。
把项目代码clone下来, 注意是递归下载,里面包含项目自带的caffe,跟原版的caffe略有不同,一定要注意:
git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git
安装python包cython, 使用pip安装:
sudo pip install cython
编译cython
cd /py-faster-rcnn/lib
修改setup.py文件,注释掉GPU相关代码,如下:
#CUDA = locate_cuda()
#self.set_executable('compiler_so', CUDA['nvcc'])
# Extension('nms.gpu_nms',
['nms/nms_kernel.cu', 'nms/gpu_nms.pyx'],
library_dirs=[CUDA['lib64']],
libraries=['cudart'],
language='c++',
runtime_library_dirs=[CUDA['lib64']],
# this syntax is specific to this build system
# we're only going to use certain compiler args with nvcc and not with
# gcc the implementation of this trick is in customize_compiler() below extra_compile_args={'gcc': ["-Wno-unused-function"],
'nvcc': ['-arch=sm_35','--ptxas-options=-v','-c','--compiler-options',"'-fPIC'"]},
include_dirs = [numpy_include, CUDA['include']]
),
setup.py修改完成后,执行make
编译caffe(项目自带的caffe-fast-rcnn)
具体安装方法,详见我的另一篇博客,地址:http://blog.csdn.net/zhang_shuai12/article/details/52289825
注意执行完make, 别忘了make pycaffe
到这里, 我们就完成了所得的安装。
首先,我们先运行一下项目自身的demo
下载论文中提到的pascal voc 2007 数据集,pascal voc 2012数据集类似可下载:
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtrainval_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCtest_06-Nov-2007.tar
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2007/VOCdevkit_08-Jun-2007.tar
下载完成后,解压缩:
tar xvf VOCtrainval_06-Nov-2007.tar
tar xvf VOCtest_06-Nov-2007.tar
tar xvf VOCdevkit_08-Jun-2007.tar
解压缩完成后,会形成如下的目录结构:
$VOCdevkit/
$VOCdevkit/VOCcode/
$VOCdevkit/VOC2007
我们对pascal voc2007 数据集做一个链接:
cd py-faster-rcnn/data
ln -s /path/to/VOCdevkit VOCdevkit2007
现在,在data目录下会出现VOCdevkit2007文件夹, 结构与VOCdevkit相同。
训练数据集, 论文提供几种训练方式, 具体参数可看代码做相应设置:
cd py-fatser-rcnn
./experiments/scripts/faster_rcnn_alt_opt.sh [NET] [--set ...]
or
./experiments/scripts/faster_rcnn_end2end.sh [NET] [--set ...]
或者我们也可以运行下面命令进行训练:
./tools/train_net.py --cpu --solver path/to/solver.prototxt --weights path/to/pretrain_model --imdb voc_2007_trainval --iters 100000 --cfgs experiments/cfgs/faster_rcnn_end2end.yml
测试可使用如下命令行:
./tools/test_net.py --cpu --def path/to/test.prototxt --net path/to/your/final.model --imdb voc_2007_test --cfgs experiments/cfgs/faster_rcnn_end2end.yml
论文作者已经预训练好几种模型, 我们下载即可:
cd py-faster-rcnn
./data/scripts/fetch_faster_rcnn_models.sh
./data/scripts/fetch_imagenet_models.sh
./data/scripts/fetch_selective_search_data.sh
下载完成后, 解压缩模型,然后运行:
./tools/demo.py
会看到图像识别结果。
ok, 下面我们试着修改文件,换成自己的数据集,进行训练和测试。替换过程中,我们依然保持文件夹名称不变,只置换里面的数据。
我们下载解压后的数据集存储在:
/data/VOCdevkit2007/VOC2007
VOC2007下有三个文件夹:
VOC2007/Annotations
VOC2007/ImageSets
VOC2007/JPEGImages
Annotations: 存储与图片对应的xml文件,每个xml文件包含object的bbox,name等
ImageSets: 存储切分好的数据集,包括train,val,test等文件;
JPEGImages: 存储所有的图片;
我们把自己的训练集替换掉原始的文件,放到相应的上述三个目录下即可。
另外, 在标注数据的过程中, 发现一个非常方便的标注软件labelImg, 在图片上画出框之后,会自动生成训练所需格式的xml文件。
github项目主页地址:https://github.com/tzutalin/labelImg
感兴趣的可以自行下载安装使用。
数据集替换问题解决了,接下来,我们一步步的修改文件:
cd /lib/datasets
首先,修改pascal_voc.py,
self.CLASS = (
‘background‘, #保留这个类别
。。。
)
改成你自己要识别的object 类别,比如我要识别people,只需把people类别加进去即可。
然后修改模型参数, 以训练faster_rcnn_end2end模型为例:
cd /models/pascal_voc/VGG16/faster_rcnn_end2end
包括三个prototxt文件,分别修改如下:
对于solver.prototxt, 模型参数初始化,一般不需要修改;
对于train.prototxt, 修改如下几个地方:
①num_classes : 设置为你的识别类别数, 比如说我只识别people这一类, 则为2(1 + 背景类)
②cls_score 层, inner_product_param参数, num_output :也设置为2(1 + 背景类)
③bbox_pred层, inner_product_param参数, num_output:设置为(1 + 背景类) ×4
对于test.prototxt文件, 修改如下:
①cls_score层, inner_product_param参数, num_output: 设置为2(1 + 背景类)
到这里,我们针对自己的数据集,要修改的都已经改完了。训练的命令行再上面已经给出,这里不在写出。接下来就是耐心的等待训练结果啦。
训练完成后, 可以运行demo.py 来查看识别结果。注意,别忘了修改 CLASS的类别。另外,demo.py每次识别一张图片,若包含多个不同的类别,识别结果不能显示在同一张图片上, 可略做修改即可。
例如可以把demo.py里的demo函数和vis_detections函数写成一个函数:
def vis_detections(im, net, image_name, thresh=0.5):
"""Draw detected bounding boxes."""
scores, boxes = im_detect(net, im)
print ('Detection took {:.3f}s for '
'{:d} object proposals').format(timer.total_time, boxes.shape[0])
NMS_THRESH = 0.3
for cls_ind, cls in enumerate(CLASSES[1:]):
cls_ind += 1 # because we skipped background
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, :]
inds = np.where(dets[:, -1] >= thresh)[0]
# print inds
if len(inds) > 0:
for i in inds:
bbox = dets[i, :4]
score = dets[i, -1]
cv2.rectangle(im, (bbox[0], bbox[1]),(bbox[2], bbox[3]),(0,255,0),3)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(im, '{:s} {:.3f}'.format(cls, score), (bbox[0], bbox[1]), font, 0.5, (0,0,255),1)
# detection result path
cv2.imwrite(result_dir + '/' + image_name + '.jpg', im)
参考:
【1】https://github.com/rbgirshick/py-faster-rcnn
【2】Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks by Shaoqing Ren, Kaiming He, Ross Girshick, Jian Sun NIPS 2015
【3】https://github.com/tzutalin/labelImg
【4】http://caffe.berkeleyvision.org/installation.html#compilation