MacBook Pro安装Caffe过程记录(macOS Sierra 10.12.6)

1.在写安装过程之前

要说明的是此篇文章的最终结果参照的是用Google搜索出来的(翻墙)教程, 在这之前图省事没去翻墙(也是觉得就百度搜索的结果应该Ok), 结果百度出来的教程都没能在我的电脑中安装好Caffe(无GPU版本, 电脑用的是Intel Iris的显卡, 不能用NVIDIA的CUDA并行库).

更要吐槽的是, 虽然是Google搜索出来的此篇博文(wordpress), 但最终参考的是上述博文中的一篇知乎专栏文章(ref)的参考, 你这百度, 搜索国内的文章都这么费劲吗? (百度的结果全是Csdn等网站的(相似)文章)

2.安装的前提逻辑

首先, Caffe的安装大致是沿着官网的思路(link): 1.Caffe的C++依赖安装, 2.Caffe的Python接口的依赖安装, 3.Caffe源码编译.

1.依赖环境安装(Prerequisite): 包含Caffe的系统环境依赖(C++库, Mac中使用brew命令安装);

2.Caffe Python的环境依赖(Python接口的一些依赖库), Caffe也有Matlab接口, 但我不熟也用不来, 故不安装;

3.源码编译(Compilation, Caffe Source Code): 从Github上下载然后make install(用C++编译器编译出需要的二进制程序).

但是, 官网上的安装教程, 也不是完全一对一的(每个人的电脑总会不同), 针对我的情况来说, 有些细节, 官网多讲了, 有些细节, 官网没讲.

环境这事情, 具体情况具体分析吧, 这么说, 也都是血与泪的教训啊, 故将此次安装的总结成众多Caffe安装方法的其中一个版本.

3.安装的过程(From 安装依赖 To import caffe无报错):

由于我电脑上已经有了Xcode和brew了, 故没有在此安装, 然后进行Caffe官方的环境依赖安装:

解释brew: Mac上管理系统库的一种工具接口/体系, 类似于Python中的pip包管理工具.

以下, 通过brew安装如下库, 由于不同库之间有版本依赖关系, 今天的某库A(旧版本)到一年后变成了新版本的库A, 但别的对此库有依赖的库B(依赖A的旧版本), 却是不能使用新版本的A, 故在brew安装时, 要特别指定某个版本.

Caffe安装中通过brew安装的一些系统库:

snappy, leveldb, gflags, glog, szip, lmdb, openblas, hdf5, opencv, boost, boost-python,

以及protobuf,

其中, protobuf库有点特殊, 较新的版本(如3.6.1)还不是很稳定(不能正确编译), 故在此手动安装其它版本(使用make install编译安装3.5.1版本).

# 1.如果出现"Updating Homebrew.."且很慢的话(brew的自动更新, 可设置不自动更新), 可直接Ctrl+C中止更新;
brew install -vd snappy leveldb gflags glog szip lmdb
# 2.安装openblas;
brew install openblas
# 3.安装hdf5和opencv, 由于时间点的关系, 以下命令会安装最新opencv的4版本, 可以将'Makefile.configure'中的'OPENCV_VERSION'改成4, 或者使用'brew install opencv@3'命令(不保证, 没尝试);
brew install hdf5 opencv
# 4.安装指定版本的boost和boost-python, 因为这两个库的新版本可能与Python 2.7有兼容性问题:
# https://www.boost.org/doc/libs/1_67_0/libs/python/doc/html/rn.html;
brew install boost@1.59 boost-python@1.59
brew link boost@1.59 --force
brew link boost-python@1.59 --force
# 5.手动编译protobuf库;
cd ~/Desktop
wget https://github.com/protocolbuffers/protobuf/archive/v3.5.1.zip
unzip v3.5.1.zip 
cd protobuf-3.5.1/
./autogen.sh
./configure
make
make install

在此处执行make install命令时, 可能会遇到如下报错(我遇到了, 没有则更好了):

..(省略一些上下文(Context))
# 以下是报错信息:
/usr/local/bin/ginstall -c -m 644  google/protobuf/compiler/javanano/javanano_generator.h '/usr/local/include/google/protobuf/compiler/javanano'    # ginstall命令输入;
ginstall: cannot remove '/usr/local/include/google/protobuf/compiler/javanano/javanano_generator.h': Permission denied    # ginstall命令错误提示输出;
make[3]: *** [install-nobase_includeHEADERS] Error 1
make[2]: *** [install-am] Error 2
make[1]: *** [install] Error 2
make: *** [install-recursive] Error 1

简单说来, 上述错误是由于ginstall命令没有删除javanano_generator.h文件的权限, 只要将该文件的权限改成可读/可写(可以没有执行权限, 无论手动修改还是命令行修改都可以), 修改文件后再次执行命令, 没有报错. (额外分析见"附录-讲解A")

至此, Caffe的"C++/系统依赖"安装完了, 可以开始安装(编译)Caffe源码了(附带Python环境/依赖安装).

由于安装的是Python接口的Caffe, 则要选择某一版本的Python进行安装, 这里我选了2.7版本的Python(据说Python3和Caffe的匹配容易出问题和bug), 首先, 在anaconda中新建一个python2.7的envs:

# 6.Python 2.7环境安装(此环境在我电脑的"~/miniconda3"中).
conda create --name py27 python=2.7
source activate py27
pip install numpy scipy scikit-image

以上安装无报错后, 真正开始安装/编译Caffe:

# 7.下载并修改Caffe的一些编译选项;
cd ~/Desktop
git clone https://github.com/BVLC/caffe.git
cd caffe
cp Makefile.config.example Makefile.config

根据官方的建议, 在进行build时, 需要对make的"配方"(recipe, 即Makefile.config文件)进行修改, 具体的, 此次安装的修改如下:

# 8.修改'Makefile.configure'配置文件, 共8个修改点;
1.取消CPU_ONLY前面的注释
2.取消USE_OPENCV前面的注释
3.取消USE_HDF5前面的注释,并改成1
4.取消OPENCV_VERSION前面的注释, 并改成4 # 在brew install opencv时, 由于时间点的关系会安装最新的版本4;
5.注释掉CUDA_DIR那一行  # 解释: 无GPU版本并没有安装CUDA;
6.将BLAS改成open  # 使用的的是openblas库: brew install openblas;
7.设置blas的路径,取消下面这两行的注释('>'):
	# Homebrew puts openblas in a directory that is not on the standard search path
> BLAS_INCLUDE := $(shell brew --prefix openblas)/include
> BLAS_LIB := $(shell brew --prefix openblas)/lib
8.设置python的路径, 因为我使用的是miniconda3并创建了一个名叫py27的python=2.7的子环境, 然后设置如下:
	# Anaconda Python distribution is quite popular. Include path:
	# Verify anaconda location, sometimes it's in root.
> ANACONDA_HOME := $(HOME)/miniconda3/envs/py27
> PYTHON_INCLUDE := $(ANACONDA_HOME)/include \
> 	  	$(ANACONDA_HOME)/include/python2.7 \
> 	  	$(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include
	
	# Uncomment to use Python 3 (default is Python 2)
	# PYTHON_LIBRARIES := boost_python3 python3.5m
	# PYTHON_INCLUDE := /usr/include/python3.5m \
	#                 /usr/lib/python3.5/dist-packages/numpy/core/include

	# We need to be able to find libpythonX.X.so or .dylib.
	# PYTHON_LIB := /usr/lib
> PYTHON_LIB := $(ANACONDA_HOME)/lib
	
	# Uncomment to support layers written in Python (will link against Python libs)
> WITH_PYTHON_LAYER := 1

修改好Makefile.configure之后, 可以进行源码编译了, make命令会从Makefile的第3行(CONFIG_FILE := Makefile.config)读取配置(即: 我们的修改):

# 9.Caffe编译, part 1;
make all
make test
make runtest
make pycaffe
# source activate py27

上述几个步骤(part 1)如果没有报错, 则可以继续part 2的步骤, 但由于到现在我们没有安装caffe源码文件夹中python/requirements.txt的Python依赖, 在执行python -c "import caffe"时应该会有如下报错: ImportError: No module named google.protobuf.internal.

刚看到这个报错时也是一脸懵逼(不知所措): **1.**之前没用过这个依赖(不知道其为何物), **2.**因不知其为何物而产生的一种"恐惧", **3.**不熟悉Caffe的内部引用结构(就不主动将google.protobuf.internalimport caffe关联起来), 4.因第3点的原因而没有意识到少安装了一些依赖(python/requirements.txt).

发觉是没有安装依赖后, 开始安装依赖(使用如下命令), 但需将requirements.txt做如下修改(状况迭出):

# 修改: 第12行, 去掉行末的',<2';
python-dateutil>=1.4,<2 修改成 python-dateutil>=1.4
# 分析: 如果不修改, 会有版本报错:
>	ERROR: pandas 0.24.2 has requirement python-dateutil>=2.5.0, but you'll have python-dateutil 1.5 which is incompatible.
>	ERROR: matplotlib 2.2.4 has requirement python-dateutil>=2.1, but you'll have python-dateutil 1.5 which is incompatible.
# 原因: 上述包中(pandas和matplotlib)依赖的'dateutil'版本不能是<2的, 而该文件明确将dateutil的版本规定到'<2'的版本, 这肯定要报错了; 然而, 我只是将',<2'去掉, 它实际安装的是'1.5'版本(因为满足要求'>=1.4'), 却不报错了, 这很是费解:
# "~/miniconda3/envs/py27/lib/python2.7/site-packages/dateutil/__init__.py" => __version__="1.5"
# 既然不报错, 那就先这样吧: 只要bug不出现, 就是没bug..;

修改requirements.txt完成后, 执行import caffe所需的Python依赖的安装:

# 10.如果'py27'环境中缺少'import caffe'所需的依赖, 则执行以下依赖安装:
pip install -r python/requirements.txt

安装无误后, 检查是否可以使用caffe:

# 11.Caffe编译, part 2;
python -c "import caffe"

此时, 没有报错.

4.安装小结

至此, 我的Mac无GPU版本的caffe算是安装完成了, 弄了几天, 之前试了几种方法, 走了几遍安装流程, 换来了这一次的成功, 不过更大的意义在于: 1.之前几天的过程, 2.这篇思路梳理和总结的文章.

(如果有写的不对的地方, 欢迎指正, 亦欢迎交流)


5.附录

讲解A: 错误详解

其实对于这种提示, 若不是要安装Caffe, 则可能是不会遇到的.

看一下ginstall命令(g代表是Google的命令, 避免与系统命令名重合)的命令输入, 发现其是.../ginstall -c -m 644 .../javanano_generator.h这样的命令格式,

而之后的报错提示则是ginstall: cannot remove '.../javanano_generator.h': permission denied, 合理推测应该是ginstall在寻求删除上述文件时(程序内部有申请删除文件这种系统调用), 遇到了权限不够的问题: 此时并没有用sudo命令执行make install, 故ginstall并不属于该文件644权限中的6(可读与可写不可执行, owner权限), 而是4(可读不可写不可执行, group权限), 而remove(删除)是属于写权限范围的, 系统内核拒绝了ginstall的删除文件这个请求, 于是make命令出现了install Error的状态.

在手动(鼠标右键-显示简介-共享与权限)将上述文件的权限修改成664之后, 再次make install, 则不再出现Permission denied的错误了.

上面这个错误产生的系统原因:

关于权限/Permission: 虽然每次打开电脑登陆操作系统都是用某个用户名登录的(即owner/group/guest中的owner), 但在终端中如果没有在命令前加上sudosu, 则命令的默认执行权限应该是group这一档次的(如执行make install这样的命令拥有的是group这一档上的权限).

举例: 如果group档上的权限是4(只读), 则在进行rm(删除)操作时, 就会出现Permission denied报错.

讲解B: 关于编译/Compile:

make根据Makefile中的一系列shell命令, 执行相应的编译工作(诸如g++这样的二进制文件承担了此类功能).

引申开去, 由于可执行的二进制文件的根基是C语言和UNIX这个体系的, 此类二进制文件中也包含了对应于C/C++语言的main()函数的入口.

从宏观上理解, 整个make install命令做的就是通过Makefile规定好的编译规则, 将Caffe的C++源码编译成系统中各种可使用的各种二进制(可执行)文件及相应的动态/静态库(在相应的目录中).

编译期间遇到的各种WarningError, 则是C/C++编译器的一种"规则违反提示", 如缺源码文件/缺引用库/变量未定义(引用版本不对)/删除权限不足(系统环境问题), 这些"异常", 在C/C++编译器的设计时就设定好了.

6.参考资料

[1] Install Caffe and MatCaffe CPU-Only on MacOS 10.14.3: link (Accessed on 2019-10-05).

[2] 在Mac OS Mojave(10.14)上安装 caffe: link (Accessed on: 2019-10-06).

[3] Caffe官方: link (Accessed on: 2019-10-03).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值