深度学习框架之caffe(一) —编译安装

摘要:本系列文章主要讲解caffe的整个使用流程,适合初级入门caffe,通过学习本篇文章,理清项目训练、测试流程。初级教程,高手请绕道。

目录
深度学习框架之caffe(一) —编译安装
深度学习框架之caffe(二) —模型训练和使用
深度学习框架之caffe(三) —通过NetSpec自定义网络
深度学习框架之caffe(四) —可视化与参数提取
深度学习框架之caffe(五) —模型转换至其他框架

caffe 主要特点

与其他框架的性能对比

caffe使用

以ubuntu16操作系统为例,windows等操作系统上的使用自行阅读

文档

官方文档
[windows 下配置] (http://blog.csdn.net/happynear/article/details/45372231)

下载源码

  1. 最原始版本:伯克利BVLC版【2月内有更新】
  2. for windows: 基础版, happynear【1月内有更新】
  3. 其他:贾杨清自己的版本【近3年没有维护】
  4. 最新版本:caffe2【一周内有更新】

编译

此后如无特殊声明,默认使用ubuntu16系统+BVLC版caffe源码,以CAFFE_ROOT表示caffe根目录

下载源码

打开BVLC版github项目主页,可使用下载或 git clone 将源码下载本地,推荐使用后者,这样如果后期你对caffe源码进行了较好的修改,可在修改过程中进行版本管理,甚至可以使用git merge request 向源码维护者发出请求,将你所做的改进合并到源码中,便于大家对开源代码的共同维护和升级。git clone 命令如下:

git clone https://github.com/BVLC/caffe.git

安装依赖库

caffe需要很多依赖库:详细参见官方安装说明文档
cuda: gpu模式必须
BLAS: 科学计算工具,可使用ATLAS, MKL或OpenBLAS
Boost:
protobuf, glog, gflags,hdf5等
其他可选: opencv, lmdb, leveldb, cudnn
python接口及其依赖库:python2.7 或python3.3+, numpy,boost.python
matlab接口: MATLAB环境及mex编译器

依赖库安装步骤如下:

$ sudo apt-get update 
$ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev  \
libopencv-dev  libhdf5-serial-dev  protobuf-compiler
$ sudo apt-get install --no-install-recommends libboost-all-dev
$ sudo apt-get install libatlas-base-dev

编译源码

  1. caffe默认编译方式(Makefile.config)
    Caffe 开发者提供了比较简单的编译方式,使得用户即使不清楚通用的编译方式,也能很快地完成对源码的编译,只需用户根据本机软硬件的环境,通过修改Makefile.config文件,对编译环境进行简单的配置即可。
    注:初次使用源码时,根目录下提供了一个配置样例文件(Makefile.config.example),用户需要进行一次文件拷贝才能产生Makefile.config文件,其部分内容如下,用户可根据本机环境进行适当的修改:
## Refer to http://caffe.berkeleyvision.org/installation.html
# Contributions simplifying and improving our build system are welcome!

# cuDNN acceleration switch (uncomment to build with cuDNN).
# USE_CUDNN := 1(caffe默认不使用cuda的cudnn模块,需要手动开启)

# CPU-only switch (uncomment to build without GPU support).
# CPU_ONLY := 1(默认gpu模式,无gpu时开启)

# uncomment to disable IO dependencies and corresponding data layers
# USE_OPENCV := 0
# USE_LEVELDB := 0
# USE_LMDB := 0

# uncomment to allow MDB_NOLOCK when reading LMDB files (only if necessary)
#   You should not set this flag if you will be reading LMDBs with any
#   possibility of simultaneous read and write
# ALLOW_LMDB_NOLOCK := 1

# Uncomment if you're using OpenCV 3
 OPENCV_VERSION := 3 #(采用opencv3)

# To customize your choice of compiler, uncomment and set the following.
# N.B. the default for Linux is g++ and the default for OSX is clang++
# CUSTOM_CXX := g++

# CUDA directory contains bin/ and lib/ directories that we need.
CUDA_DIR := /usr/local/cuda # cuda目录
# On Ubuntu 14.04, if cuda tools are installed via
# "sudo apt-get install nvidia-cuda-toolkit" then use this instead:
# CUDA_DIR := /usr


具体的编译过程如下:

cd $CAFFE_ROOT
cp Makefile.config.example Makefile.config
# 根据本机环境修改 Makefile.config 
make all -j8
make test -j8
make runtest
  1. cmake 通用编译方式
    大部分有开发经验的用户,都会对cmake编译方式有一定的了解,caffe也支持cmake的编译方式,该方式下,配置环境的设置可利用图形化工具cmake-gui进行相关参数(参数命名与Makefile.config中的命名基本一致)的配置,cmake经验丰富的,可直接修改根目录下的CMakeLists.txt文件,部分内容如下:
cmake_minimum_required(VERSION 2.8.7)
if(POLICY CMP0046)
  cmake_policy(SET CMP0046 NEW)
endif()
if(POLICY CMP0054)
  cmake_policy(SET CMP0054 NEW)
endif()

# ---[ Caffe project
project(Caffe C CXX)

# ---[ Caffe version【caffe版本号】
set(CAFFE_TARGET_VERSION "1.0.0" CACHE STRING "Caffe logical version")
set(CAFFE_TARGET_SOVERSION "1.0.0" CACHE STRING "Caffe soname version")
add_definitions(-DCAFFE_VERSION=${CAFFE_TARGET_VERSION})

# ---[ Using cmake scripts and modules
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)

include(ExternalProject)
include(GNUInstallDirs)

include(cmake/Utils.cmake)
include(cmake/Targets.cmake)
include(cmake/Misc.cmake)
include(cmake/Summary.cmake)
include(cmake/ConfigGen.cmake)

# ---[ Options 【参数配置,与Makefile.config类似】
caffe_option(CPU_ONLY  "Build Caffe without CUDA support" OFF) # TODO: rename to USE_CUDA
caffe_option(USE_CUDNN "Build Caffe with cuDNN library support" ON IF NOT CPU_ONLY)
caffe_option(USE_NCCL "Build Caffe with NCCL library support" OFF)
caffe_option(BUILD_SHARED_LIBS "Build shared libraries" ON)
caffe_option(BUILD_python "Build Python wrapper" ON)
set(python_version "2" CACHE STRING "Specify which Python version to use")
caffe_option(BUILD_matlab "Build Matlab wrapper" OFF IF UNIX OR APPLE)
caffe_option(BUILD_docs   "Build documentation" ON IF UNIX OR APPLE)
caffe_option(BUILD_python_layer "Build the Caffe Python layer" ON)
caffe_option(USE_OPENCV "Build with OpenCV support" ON)
caffe_option(USE_LEVELDB "Build with levelDB" ON)
caffe_option(USE_LMDB "Build with lmdb" ON)
caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF)
caffe_option(USE_OPENMP "Link with OpenMP (when your BLAS wants OpenMP and you get linker errors)" OFF)

# ---[ Dependencies
include(cmake/Dependencies.cmake)

具体编译步骤:

cd $CAFFE_ROOT
mkdir build
cd build
# 编译
cmake .. # 按默认配置编译
# or 设置部分参数
cmake -DCMAKE_BUILD_TYPE=Release \
    -DBUILD_python=OFF \
    -DBUILD_python_layer=OFF \
    -DCMAKE_INSTALL_PREFIX=/usr/local \
   ..

# note:编译工程,可有需求地执行
make all -j8       # 编译所有
make caffe -j8     # 只编译caffe的C++库,生成libcaffe.so
make pycaffe -j8 #编译python接口
  1. 编译结果
    编译成功后,在build目录下可以看到如下图所示的子目录结构:


    image.png
    • lib 静态库和动态库目录,存放libcaffeproto.a libcaffe.so libcaffe.so.1.0.0等库文件
    • tools 可执行程序,包括训练,计算均值,提取特征,数据转换等可执行程序
    • examples 部分使用样例程序

踩过的坑

编译caffe源码失败的主要原因在于操作系统在不同的版本下某些库的路径会发生一定的变动。最初的caffe 源码中提供的Makefile.config.example是支持ubuntu12-14系统的,因此Makefile.config中对依赖库的路径设置(主要是python头文件和hdf5)都是在ubuntu12-14系统可行,而对于ubuntu16,python的包含目录和apt源提供的hdf5库有一定的改动,直接采用原来的Makefile.config编译会报错,需要进行相应的路径修改。但最新版本的caffe源码已经能够支持ubuntu16,仍需根据实际的ubuntu版本进行相应的修改。

  1. caffe.pb.h丢失问题:
    /home/ubuntu/caffe/include/caffe/blob.hpp:9:34: fatal error: caffe/proto/caffe.pb.h: No such file or directory
    问题分析: caffe使用protobuf进行数据传输(类似json数据格式),用户通过编辑 .proto文件确定数据协议,数据结构中存在哪些数据,数据类型是怎么样的,给C++调用时,需通过protoc命令将改文件转换成c++所需的头文件(.pb.h),caffe下.proto文件在src/caffe/proto/caffe.proto
    解决方法: 用protoc从caffe/src/caffe/proto/caffe.proto生成caffe.pb.h和caffe.pb.cc
cd CAFFE_ROOT
protoc ./src/caffe/proto/caffe.proto  --cpp_out=./include/caffe/
  1. ubuntu16下 python路径引起的问题:
    fatal error: numpy/arrayobject.h没有那个文件或目录
    问题分析: caffe的python接口需要python.h 和numpy支持,需要添加两种头文件的路径(Makefile.config Line66-67)
    ubuntu14下自带的python头文件在/usr/include/python2.7(python3.4)下,通过pip install numpy 命令安装的numpy头文件在/usr/local/lib/python2.7/dist-packages/numpy/core/include,Makefile.config中默认按该路径添加相关头文件路径
    而ubuntu16下通过pip安装的python的numpy库头文件在/usr/lib/python2.7/dist-packages/numpy/core/include,若不修改,头文件路径引用错误,依旧找不到相关头文件,因此报错。
    解决方法: 修改为正确的python头文件目录。若不熟悉ubuntu路径,可先通过find命令找到这两个头文件所在的路径(约Line66-67):
sudo find / -name Python.h
sudo find / -name arrayobject.h

然后在Makefile.config 中修改为正确的路径:

PYTHON_INCLUDE := /usr/include/python2.7 \
              /usr/lib/python2.7/dist-packages/numpy/core/include
  1. ubuntu16下HDF5安装路径引起的问题:
    “fatal error: hdf5.h: 没有那个文件或目录”
    问题分析: 首先确定是否正确安装hdf5库,防患未然,执行命令sudo apt-get install libhdf5-serial-dev安装hdf5,若提示已经安装,则有可能是hdf5库版本不同(有libhdf5-dev和libhdf5-serial-dev两种) hdf5-serial, 的头文件路径是/usr/include/hdf5/serial/,库文件名是hdf5_serial, 因此需要对Makefile.config进行相应的修改,将以下两行(约Line 94-95):
INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include
LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib

改成:

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

即在末尾添加hdf5头文件和库文件名,每台计算机的默认安装路径也可能不完全相同,可根据具体情况添加。

  1. ubuntu16下python3.5路径引起的问题:
    忘了,找到时再更新
  2. 使用anaconda python接口时anaconda自带的protobuf引起的问题:
    通过 sudo apt install libprotobuf-dev安装的protobuf版本一般相对较低,而anaconda自带的也有protobuf,所以在用anaconda中的python编译pycaffe的过程中,解决问题1时可能因为两个protobuf
  3. python下import caffe 出现的问题:
    ImportError: libcublas.so.8.0: cannot open shared object file: No such file or directory
    GPU版的_caffe.so 依赖libcublas.so.8.0库文件(so文件相当于Windows下的dll文件),ubuntu系统对依赖库文件的搜索路径是/usr/lib和环境变量$LD_LIBRARY_PATH,cuda安装默认路径是/usr/local, 安装完成后需进行环境变量的配置,以便其他依赖cuda的应用能够正常访问共享库文件(环境变量的配置详细参考帖子):
export PATH=/usr/local/cuda-8.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH

ImportError: No module named google.protobuf.internal
未安装python下的protobuf库。caffe依赖protobuf,python接口下调用caffe也需要protobuf第三方库。安装命令为:sudo pip install protobuf

注意事项

熟悉编译原理和可执行程序依赖库调用的人,可以不局限于本文提供的流程和方式,比如,

  • 将caffe编译后的目录添加到环境变量中,以供所有程序默认可访问:
# 让C++等程序默认可访问
export LD_LIBRARY_PATH=$CAFFE_ROOT/build/lib:LD_LIBRARY_PATH
# 让python默认访问
export PYTHONPATH=$CAFFE_ROOT/python:PYTHONPATH
# 可在任意目录下执行caffe训练命令
export PATH=$CAFFE_ROOT/build/tools:$PATH
  • 同一台主机上多个caffe库共存
    caffe默认编译目录是build,生成一些so文件(动态依赖库,类似Windows下的dll)。反复执行make all/pycaffe 时会覆盖上一次的编译结果。当python2和python3的接口都需要,或者同时需要cpu和gpu两个版本时,可以将第一次配置下生成的相关文件(build/lib下的so文件,build/tools下的可执行程序,python/caffe目录)拷贝到其他路径,这样修改配置参数后,可编译生成另一种配置下的caffe库,同时可进一步讲这些生成文件拷贝到一个新的路径下,或者添加到环境变量。如我的计算机可以有不同功用,版本的caffe库:
    /home/ubuntu/caffe_py2 (python2接口库)
    /home/ubuntu/caffe_py3 (python3 接口库)
    /home/ubuntu/caffe_fastrcnn_py2(python2下支持faster rcnn的 caffe库)
    有了这些不同版本,不同配置的caffe库,即使把CAFFE_ROOT下的源码删除,也一样能调用caffe相关库和命令

注: 采用cmake编译方式时也可直接通过参数-D-DCMAKE_INSTALL_PREFIX=path_to_install设置caffe的安装路径

  • 基于caffe的项目程序发布时对依赖库的整理
    通过命令ldd libcaffe.so 可查看caffe的依赖库,如下图(图中所列依赖库不完整,仅截取部分),
    image.png

当基于caffe的项目编译成可执行程序,并拷贝到其他电脑上时,只需将caffe的依赖库文件拷贝过去,同时将库文件所在的目录添加到环境变量$LD_LIBRARY_PATH中即可运行,而无需在目标主机上执行一遍编译过程。

推荐阅读更多精彩内容