caffe faster-rcnn 安装(CPU环境)

引言

这篇博客用于记录我安装faster-rcnn的过程,以及所遇到的坑。

faster-rcnn是给予caffe框架的,所以跟之前编译运行caffe类似。

需要opencv。

说明:

caffe我之前已经安装过来,说以caffe所需要的依赖包我已经安装,没有安装过caffe的同学,自行百度,这里就不在复述了,就几条命令的事。

1. 下载github上的py-faster-rcnn代码

git clone --recursive https://github.com/rbgirshick/py-faster-rcnn.git

2. 安装所需的Python模块

进入caffe-fast-rcnn/python,可以看到一个requirements.txt,这里面记录该项目必须的Python依赖。

requirements.txt文件内容 :

Cython>=0.19.2
numpy>=1.7.1
scipy>=0.13.2
scikit-image>=0.9.3
matplotlib>=1.3.1
ipython>=3.0.0
h5py>=2.2.0
leveldb>=0.191
networkx>=1.8.1
nose>=1.3.0
pandas>=0.12.0
python-dateutil>=1.4,<2
protobuf>=2.5.0
python-gflags>=2.0
pyyaml>=3.10
Pillow>=2.3.0
six>=1.1.0

可以使用下面命令进行安装所有依赖:

for req in $(cat requirements.txt);do sudo python2.7 -m pip install $req; done

注意:这里我把库安装到python2.7上,需要安装到其他python版本自行更改

3. 修改Makefile.config

进入py-faster-rcnn/caffe-fast-rcnn备份一个config文件

cd py-faster-rcnn/caffe-fast-rcnn
cp Makefile.config.example Makefile.config

修改Makefile.config文件:
① . 将CPU_ONLY := 1的注释打开;
②. 将WITH_PYTHON_LAYER := 1的注释打开;(python_layer)
③ . 在INCLUDE_DIRS和LIBRARY_DIRS后面分别加上/usr/include/hdf5/serial和/usr/lib/x86_64-linux-gnu/hdf5/serial

INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/x86_64-linux-gnu/hdf5/serial

4. 编译lib

进入py-faster-rcnn/lib,先修改setup.py的内容(忽略GPU环境),编译faster-rcnn的相关函数库。
(使用CPU)
将# ONLY CPU下一的代码注释,注释后的setup.py如下:

# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import os
from os.path import join as pjoin
from setuptools import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import subprocess
import numpy as np

def find_in_path(name, path):
    "Find a file in a search path"
    # Adapted fom
    # http://code.activestate.com/recipes/52224-find-a-file-given-a-search-path/
    for dir in path.split(os.pathsep):
        binpath = pjoin(dir, name)
        if os.path.exists(binpath):
            return os.path.abspath(binpath)
    return None


def locate_cuda():
    """Locate the CUDA environment on the system

    Returns a dict with keys 'home', 'nvcc', 'include', and 'lib64'
    and values giving the absolute path to each directory.

    Starts by looking for the CUDAHOME env variable. If not found, everything
    is based on finding 'nvcc' in the PATH.
    """

    # first check if the CUDAHOME env variable is in use
    if 'CUDAHOME' in os.environ:
        home = os.environ['CUDAHOME']
        nvcc = pjoin(home, 'bin', 'nvcc')
    else:
        # otherwise, search the PATH for NVCC
        default_path = pjoin(os.sep, 'usr', 'local', 'cuda', 'bin')
        nvcc = find_in_path('nvcc', os.environ['PATH'] + os.pathsep + default_path)
        if nvcc is None:
            raise EnvironmentError('The nvcc binary could not be '
                'located in your $PATH. Either add it to your path, or set $CUDAHOME')
        home = os.path.dirname(os.path.dirname(nvcc))

    cudaconfig = {'home':home, 'nvcc':nvcc,
                  'include': pjoin(home, 'include'),
                  'lib64': pjoin(home, 'lib64')}
    for k, v in cudaconfig.iteritems():
        if not os.path.exists(v):
            raise EnvironmentError('The CUDA %s path could not be located in %s' % (k, v))

    return cudaconfig
# ONLY CPU
#CUDA = locate_cuda()


# Obtain the numpy include directory.  This logic works across numpy versions.
try:
    numpy_include = np.get_include()
except AttributeError:
    numpy_include = np.get_numpy_include()

def customize_compiler_for_nvcc(self):
    """inject deep into distutils to customize how the dispatch
    to gcc/nvcc works.

    If you subclass UnixCCompiler, it's not trivial to get your subclass
    injected in, and still have the right customizations (i.e.
    distutils.sysconfig.customize_compiler) run on it. So instead of going
    the OO route, I have this. Note, it's kindof like a wierd functional
    subclassing going on."""

    # tell the compiler it can processes .cu
    self.src_extensions.append('.cu')

    # save references to the default compiler_so and _comple methods
    default_compiler_so = self.compiler_so
    super = self._compile

    # now redefine the _compile method. This gets executed for each
    # object but distutils doesn't have the ability to change compilers
    # based on source extension: we add it.
    def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
        if os.path.splitext(src)[1] == '.cu':
            # use the cuda for .cu files
            # ONLY CPU
            #self.set_executable('compiler_so', CUDA['nvcc'])
            # use only a subset of the extra_postargs, which are 1-1 translated
            # from the extra_compile_args in the Extension class
            postargs = extra_postargs['nvcc']
        else:
            postargs = extra_postargs['gcc']

        super(obj, src, ext, cc_args, postargs, pp_opts)
        # reset the default compiler_so, which we might have changed for cuda
        self.compiler_so = default_compiler_so

    # inject our redefined _compile method into the class
    self._compile = _compile


# run the customize_compiler
class custom_build_ext(build_ext):
    def build_extensions(self):
        customize_compiler_for_nvcc(self.compiler)
        build_ext.build_extensions(self)


ext_modules = [
    Extension(
        "utils.cython_bbox",
        ["utils/bbox.pyx"],
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        include_dirs = [numpy_include]
    ),
    Extension(
        "nms.cpu_nms",
        ["nms/cpu_nms.pyx"],
        extra_compile_args={'gcc': ["-Wno-cpp", "-Wno-unused-function"]},
        include_dirs = [numpy_include]
    ),
    # ONLY CPU
    #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']]
    #),
    Extension(
        'pycocotools._mask',
        sources=['pycocotools/maskApi.c', 'pycocotools/_mask.pyx'],
        include_dirs = [numpy_include, 'pycocotools'],
        extra_compile_args={
            'gcc': ['-Wno-cpp', '-Wno-unused-function', '-std=c99']},
    ),
]

setup(
    name='fast_rcnn',
    ext_modules=ext_modules,
    # inject our custom trigger
    cmdclass={'build_ext': custom_build_ext},
)

修改完后make编译

make

5. 编译caffe

进入py-faster-rcnn/caffe-fast-rcnn,编译代码

make -j8 && make pycaffe

上述命令的意思是执行make后执行make pycaffe

6. 接下来修改几个文件

① . 修改 py-faster-rcnn/lib/fast_rcnn/config.py

__C.USE_GPU_NMS = False  

② . 将 py-faster-rcnn/tools/test_net.py和 py-faster-rcnn/tools/train_net.py的caffe.set_mode_gpu()修改为caffe.set_mode_cpu(), 为了训练的时候使用的是CPU。

③ . 将 py-faster-rcnn/lib/fast_rcnn/nms_wrapper.py 的 from nms.gpu_nms import gpu_nms 注释掉。
这个注释掉的话会发生下面异常:


Traceback (most recent call last):
File "./demo.py", line 18, in 
from fast_rcnn.test import im_detect
File ".../py-faster-rcnn-master/tools/../lib/fast_rcnn/test.py", line 17, in 
from fast_rcnn.nms_wrapper import nms
File ".../py-faster-rcnn-master/tools/../lib/fast_rcnn/nms_wrapper.py", line 11, in 
from nms.gpu_nms import gpu_nms
ImportError: No module named gpu_nms

7. 编译时遇到的坑

编译caffe的时候出现下面错误:

    .build_release/src/caffe/proto/caffe.pb.h:23:35: fatal error: google/protobuf/arena.h: 没有那个文件

解决办法:
之前我也安装过一个caffe(原版),这个faster-rcnn是这次装的。
出现这个的问题是因为安装anaconda之后导致的protoc版本不对:编译caffe需要其版本为protobuf-2.6.1。
通过protoc --version查看当前版本发现为protoc-3.5.1。
通过命令whereis protoc 发现系统中有两个版本的protoc,分别在usr/bin 和 $HOME/anaconda/bin里。
因此使用命令:gedit ~/.bashrc 注释掉anaconda的路径,然后source ~/.bashrc使环境变量生效。
打开新终端,protoc --version 查看版本是否更改成功。
重新编译caffe即可(记得make clean)。

最后,编译完成后取消.bashrc中的anaconda注释,否则python就用不了anaconda中的库了。
(这里需要注意一下在第4步是需要protoc-3.5.1的)

8. 运行demo

在py-faster-rcnn/caffe-fast-rcnn下运行脚本:

./data/scripts/fetch_faster_rcnn_models.sh

脚本自动下载并解压模型文件到data目录下。进入data目录,可以看到生成了一个faster_rcnn_models文件夹,里面有两个训练好的caffemodel,分别是VGG16_faster_rcnn_final.caffemodel 和 ZF_faster_rcnn_final.caffemodel 。

进入py-faster-rcnn/tools,运行

python2.7 demo.py --cpu

这里又遇到坑,报错如下:

Traceback (most recent call last):
  File "demo.py", line 18, in <module>
    from fast_rcnn.test import im_detect
  File "/home/pzs/husin/FasterRcnn/py-faster-rcnn/tools/../lib/fast_rcnn/test.py", line 17, in <module>
    from fast_rcnn.nms_wrapper import nms
  File "/home/pzs/husin/FasterRcnn/py-faster-rcnn/tools/../lib/fast_rcnn/nms_wrapper.py", line 10, in <module>
    from nms.cpu_nms import cpu_nms
ImportError: No module named cpu_nms

上网查了很多,各种办法都试过都不行,py-faster-rcnn/lib/nms下也确实没有cpu_nms.py文件,但是有py_cpu_nms.py文件,把nms_wrapper.py改一下,如下:

from fast_rcnn.config import cfg
#from nms.gpu_nms import gpu_nms
from nms.py_cpu_nms import py_cpu_nms


def nms(dets, thresh, force_cpu=False):
    """Dispatch to either CPU or GPU NMS implementations."""

    if dets.shape[0] == 0:
        return []
    #if cfg.USE_GPU_NMS and not force_cpu:
    #    return gpu_nms(dets, thresh, device_id=cfg.GPU_ID)
    else:
        return py_cpu_nms(dets, thresh)

运行python2.7 demo.py --cpu,好像问题解决了,但是有出现下面错误:

Check failed: ReadProtoFromBinaryFile(param_file, param) Failed to parse NetParameter file: /home/pzs/husin/FasterRcnn/py-faster-rcnn/data/faster_rcnn_models/VGG16_faster_rcnn_final.caffemodel
*** Check failure stack trace: ***
Aborted (core dumped)

解决办法:这个问题的原因是运行./data/scripts/fetch_faster_rcnn_models.sh脚本下载的caffemodel文件不完整,因为是外网,中途中断了,重新下载就好了。

我把caffemodel放到了csdn上,有需要的可以去下载,一共八个部分,下载好后放到同个文件夹下就可以解压了。
https://download.csdn.net/download/huxiny/10781802
CSDN上传太卡,陆续上传中,有需要的留言。

9. 运行结果

生成了多张图片,不同的检测目标下的检测结果,下面放上一张person检测:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/HUXINY/article/details/83990628
今日推荐