近期由于项目需要开始接触Faster R-CNN,由于一直使用tensorflow,所以也延续习惯继续使用TF版的Faster R-CNN
网络原理来自paper Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks by Shaoqing Ren, Kaiming He, Ross Girshick, Jian Sun.
这里主要记录安装配置过程和一些坑
配置:I7-xxxx(12核),TITAN xp(12GB) *2,内存32GB
环境:ubuntu16.04,tensorflow1.4-gpu,python2.7
####################
在GitHub上找到了tf版的Faster R-CNN两个版本:
TFFRCNN:https://github.com/CharlesShang/TFFRCNN
Faster-RCNN_TF:https://github.com/smallcorgi/Faster-RCNN_TF
两个版本都下下来跑了,但后者的DEMO结果很奇怪,可能是我的操作有问题。我在第一个TFFRCNN顺利跑通了。下面记录基于前者的安装配置过程。
0、关于安装配置cpu/gpu版本的tensorflow过程不再赘述。另外建议使用python包管理容器,我使用的是Anaconda,安装各种包(比如numpy、opencv等等)非常方便,具体方法请百度。
1、首先以你方便的方式把TFFRCNN克隆或下载到本地,并且安装好README.md中要求的必须包cython
, python-opencv
, easydict
,如果你使用Anaconda,则使用:
conda install cython
conda install opencv
easydict需要使用pip安装:
pip install easydict
之后还缺什么的话就遇到什么安装什么。
2、接下来是,根据本机情况修改make.sh文件,此处要根据你的tensorflow和gcc版本修改,我把我的可用版贴出来,可以参考一下,具体怎么改网上资料很多:
#!/usr/bin/env bash
TF_INC=$(python -c 'import tensorflow as tf; print(tf.sysconfig.get_include())')
CUDA_PATH=/usr/local/cuda/
CXXFLAGS='-D_MWAITXINTRIN_H_INCLUDED'
cd roi_pooling_layer
if [ -d "$CUDA_PATH" ]; then
nvcc -std=c++11 -c -o roi_pooling_op.cu.o roi_pooling_op_gpu.cu.cc \
-I $TF_INC -D GOOGLE_CUDA=1 -x cu -Xcompiler -fPIC $CXXFLAGS \
-arch=sm_37
g++ -std=c++11 -shared -D_GLIBCXX_USE_CXX11_ABI=0 -o roi_pooling.so roi_pooling_op.cc \
roi_pooling_op.cu.o -I $TF_INC -D GOOGLE_CUDA=1 -fPIC $CXXFLAGS \
-lcudart -L $CUDA_PATH/lib64
fi
cd ..
# add building psroi_pooling layer
cd psroi_pooling_layer
nvcc -std=c++11 -c -o psroi_pooling_op.cu.o psroi_pooling_op_gpu.cu.cc \
-I $TF_INC -D GOOGLE_CUDA=1 -x cu -Xcompiler -fPIC $CXXFLAGS \
-arch=sm_52
g++ -std=c++11 -shared -D_GLIBCXX_USE_CXX11_ABI=0 -o psroi_pooling.so psroi_pooling_op.cc \
psroi_pooling_op.cu.o -I $TF_INC -D GOOGLE_CUDA=1 -fPIC -lcudart -L $CUDA_PATH/lib64
cd ..
CUDA_PATH=/usr/local/cuda/
CXXFLAGS='-D_MWAITXINTRIN_H_INCLUDED'
cd roi_pooling_layer
if [ -d "$CUDA_PATH" ]; then
nvcc -std=c++11 -c -o roi_pooling_op.cu.o roi_pooling_op_gpu.cu.cc \
-I $TF_INC -D GOOGLE_CUDA=1 -x cu -Xcompiler -fPIC $CXXFLAGS \
-arch=sm_37
g++ -std=c++11 -shared -D_GLIBCXX_USE_CXX11_ABI=0 -o roi_pooling.so roi_pooling_op.cc \
roi_pooling_op.cu.o -I $TF_INC -D GOOGLE_CUDA=1 -fPIC $CXXFLAGS \
-lcudart -L $CUDA_PATH/lib64
fi
cd ..
# add building psroi_pooling layer
cd psroi_pooling_layer
nvcc -std=c++11 -c -o psroi_pooling_op.cu.o psroi_pooling_op_gpu.cu.cc \
-I $TF_INC -D GOOGLE_CUDA=1 -x cu -Xcompiler -fPIC $CXXFLAGS \
-arch=sm_52
g++ -std=c++11 -shared -D_GLIBCXX_USE_CXX11_ABI=0 -o psroi_pooling.so psroi_pooling_op.cc \
psroi_pooling_op.cu.o -I $TF_INC -D GOOGLE_CUDA=1 -fPIC -lcudart -L $CUDA_PATH/lib64
cd ..
当在调试时候注意黑体部分,你可能需要自行加上他们,否则可能会出现诸如【error: roi_pooling_op.cu.o: 没有那个文件或目录】、【undefined symbol: _ZN10tensorflow7strings6StrCatB5cxx11ERKNS0_8AlphaNumES3_】这样的错误,是因为tensorflow版本升级造成的。
如果你能够在lib目录下成功运行sh make.sh,这时候就可以在lib目录下执行make命令在编译了。
之所以Faster R-CNN需要这个编译过程,是因为Faster R-CNN的网络结构中的roi pooling层的参数是动态根据每张图像调整的,Cython工具把python的解释性命令转化成C程序(扩展名为so,类似于win下的动态链接库),使得效率提高。
3、此时按照文档,我们可以测试demo.py了,但是按照文档的命令:
cd $FRCN_ROOT
python ./tools/demo.py --model model_path
可能会报这个错误: No module named lib.networks.factory
可以通过把demo.py移动到根目录来解决。
4、如果报类似于这样的错误:libcudart.so.9.1: cannot open shared object file: No such file or directory---
需要在执行demo.py前添加如下命令:
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64"
export CUDA_HOME=/usr/local/cuda
然后执行demo.py,注意需要下载已经训练好的网络来测试demo.py,官方文档提供了几个网络,但需要翻墙,这里分享一个上传了百度云的 VGGnet_fast_rcnn_iter_70000.ckpt
链接: https://pan.baidu.com/s/1eTcJjiU 密码: c4vq
下载后在根目录建立model文件夹,放进去,通过命令执行demo.py
python demo.py --model model/VGGnet_fast_rcnn_iter_150000.ckpt
5、如果你使用了第二个版本的代码,还可能会遇到如下问题:
No module named gpu_nms 可以通过注释相关代码解决,自行百度
undefined symbol: _ZN10tensorflow7strings6StrCatB5cxx11ERKNS0_8AlphaNumES3_ 也是tf版本改变带来的编译问题,通过修改make.sh解决。
6、我是在服务器上跑的程序,在demo.py最后的出图阶段会有问题,demo.py结尾做如下修改:
im_names = glob.glob(os.path.join(cfg.DATA_DIR, 'demo', '*.png')) + \
glob.glob(os.path.join(cfg.DATA_DIR, 'demo', '*.jpg'))
for im_name in im_names:
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
print 'Demo for {:s}'.format(im_name)
demo(sess, net, im_name)
plt.savefig(im_name) #加上这句
# plt.show() 注释掉这里
把结果图像保存下来,用你方便的方式查看。
最后,在配置过程中可能需要安装很多包,遇到就安装。不过有些import不成功的并不一定是什么包,还有可能是没有编译正确的文件,所以遇到不认识的包百度一下,因为它可能根本就不是包,多注意一下错误提示。