写在前面
本期文章基本上在先讲一件事,放弃从source code compile吧,这时间上投入根本不值得。如果只想知道如何完成构建,可以忽略前面的“上集回顾”和“背景介绍”,直接跳转到后面的指南部分。
“背景介绍”
TensorFlow
TensorFlow 是什么呢?TensorFlow 是Google 商业化了的一种用于感知和语言理解人物的机器学习的开源软件库。我们可以通过访问 https://www.tensorflow.org/
的官方页面以及它在GitHub 上的 Repository https://github.com/tensorflow/tensorflow
来获取。
自从2010年以来Google为它旗下的产品线建立了一套专有的名叫DistBelief
的机器学习系统,以推动Google的业务发展。后来于是Google使用它原有的的DistBelief
代码库重构演进成了现在的TensorFlow
。首次发布的TensorFlow 与2016年发布,并且从原始的Linux/Unix 环境下逐步向IOS、Android、Windows系统演进。
Odroid XU4
Odroid 是由一家位于韩国名叫HardKernel 的公司设计制造的。该公司目前提供的single-board computers (单片机)和平板中不仅能够支持 Android 系统,也能运行常规的Linux 发行版。HardKernel 旗下拥有 Odroid-A4、Odroid-X、Odroid-Q、Odroid-U、XU3 等一系列的单片机。值得一提的是XU3、XU4两只单片机拥有Cortex-A15 + A7
的 4 + 4 (双核?) 2.0GHz + 1.5GHz 的 CPU组。虽然市场上戏称“胶水八核”,但是其强劲的单板工作主频和较低的功耗 ,甚至支持USB3的体质还是不得不让人侧目。与Raspberry Pi 3相比,Odroid
XU4能提供的运算能力绝对值回票价。
“上集回顾”
搞事情
尝试
由于业务原因,当目前公司提出的气象信息收集传感器已经无法承载现有的数据更新的时候,我们发现使用Odroid XU4 完成初步运算识别然后再发回公司主服务器,不失为一种新的解决方案。
然而Odroid XU4 的市场占有率并不高,网络上有的信息也并不完整。Tom Jacobs 虽然在他的Blog中发出过如何构建TensorFlow,然而他所指明的方向却是从0开始。 对,从source code 开始compile。
原文连接在此: https://hackernoon.com/running-yolo-on-odroid-yolodroid-5a89481ec141
为了验证他说明的方向是否正确,我在一个月中断断续续的遵循着他的思路从Bazel 开始编译,再到TensorFlow 的构建。然而,随着时间和精力的投入,我发现这个思路根本就是行!不!通!
按照Tom Jacobs 的文章走,一定会卡在两个地方。
- Bazel 的版本。
TensorFlow 对应的Bazel Build 的版本是有特别限制的,我们可以在
https://www.tensorflow.org/install/source
最下面的页面 中 或者我在这里抄过来的列表中看出。
Version | Python version | Compiler | Build tools |
---|---|---|---|
tensorflow-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.11.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.10.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.15.0 |
tensorflow-1.9.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.11.0 |
tensorflow-1.8.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
tensorflow-1.7.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.10.0 |
tensorflow-1.6.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.9.0 |
tensorflow-1.5.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.8.0 |
tensorflow-1.4.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.5.4 |
tensorflow-1.3.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
tensorflow-1.2.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.5 |
tensorflow-1.1.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
tensorflow-1.0.0 | 2.7, 3.3-3.6 | GCC 4.8 | Bazel 0.4.2 |
这简直是无理无情,还在无理取闹。在编译Bazel 中还有另外一个智障问题,那就是 locale 问题。在对Bazel 0.5.4 编译时会出现JAVA无法调取locale 的问题,然后就真的是“编!不!下!去!了!”。虽然后续版本已经解决,但是这也导致与其对应TensorFlow 1.4版本是不可能完成的任务了
- TensorFlow 的编译错误。
在TensorFlow 的编译中我们还能遇到二个智障问题,那就是Bazel在编译TensorFlow 的过程中占用太多内存,导致GCC停止编译。另外一个问题就是 编译时必须加入--conlyopt=-std=gnu99
让GCC得以明白应该是使用C99 代码式来编译C。
于是在经历了痛苦的折磨以后,一道灵光划过。真相可能不止一个。
既然Odroid用的是ARMV7的CPU,那么它就应该就是个大号、加量、大碗版本的Raspberry Pi! 那么TensorFlow其实已经有人趟过RaspberryPi 和 TensorFlow 兼容地雷了,为什么我们还要继续走雷区?另外,虽然 Odroid XU4 4 CPU 已经很强悍了。但是和家用电脑比起来,依然是鶸。每一次的调试编译都会以半小时起步,而且上不封顶。这样的花还不如直接使用x86/amd64 架构的主机CPU来给Respberry Pi 编译封包呢。这部分已经实验成功,想看的同学,我会在以后得文章里写出。
于是,感谢 Leonardo lontra 在他的项目 https://github.com/lhelontra/tensorflow-on-arm/releases 中创造了宝贵的财产---> 已经编译过,并且适用于ARM CPU 使用的 TensorFlow!!
正牌的操作指南
好了,看到这里我想有的同学应该是要打退堂鼓了。 也有另外的同学知道我想做什么了。没关系,本文已经把潜在地雷已经排除。安心跟我上路吧。
- 准备好Ubuntu 16.04 的镜像,并刷入SD卡。我们所需要的镜像可以在官方给出的WIKI中找到。
https://wiki.odroid.com/odroid-xu4/os_images/linux/ubuntu_4.14/ubuntu_4.14
- 环境构建, TensorFlow 我们需要大量的库文件和Python来推动它的正常运作。因此,请准备以下代码 来安装必要的组件和库文件
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get install -y pkg-config zip g++ zlib1g-dev unzip wget curl -y
sudo apt-get install -y gcc-4.8 g++-4.8 -y
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 100
apt-get install -y libstdc++6
sudo apt-get install -y libhdf5-serial-dev hdf5-tools
- 安装Python, Python 现在有2.7和3.5 两个不同的版本请根据自己的需要酌情安装
(当然你也可以“我全都要”)
Python2.7
sudo apt-get install python-pip python-numpy swig python-dev
Python3.5
sudo apt-get install python3-pip python3-numpy swig python3-dev
并且升级PIP 到最新,否则是无法安装的。
Python 2.7
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
Python 3
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
- 当升级完成以后我们还必须安装Python的库文件
Python2.7
pip2 install h5py six numpy wheel mock
Python3.5
pip3 install h5py six numpy wheel mock
- 下载并安装 TensorFlow
https://github.com/lhelontra/tensorflow-on-arm/releases
Python2.7
wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v1.11.0/tensorflow-1.11.0-cp27-none-linux_armv7l.whl
pip2 install ./tensorflow-1.11.0-cp27-none-linux_armv7l.whl
Python3.5
wget https://github.com/lhelontra/tensorflow-on-arm/releases/download/v1.11.0/tensorflow-1.11.0-cp35-none-linux_armv7l.whl
pip3 install ./tensorflow-1.11.0-cp35-none-linux_armv7l.whl
注意Python2.7 和3.5 版本的TensorFlow 是不能互用的。
- 等待。。。。。。。。。。漫长的等待
等待永远是漫长的,看不到时间,看不清即将到来,在等着,等到焦灼。甚至有时自己都会恍惚,是在等即将到来,还是等到来时的那一刻欣喜,这份欣喜里藏着那不言而喻的激动与渴望。 等待是不可思议的艺术。
- 在经过漫长的等待以后,我们可以使用命令来验证TensorFlow 是否正确安装,并且能被调用
Python 2
python -c 'import tensorflow as tf; print(tf.__version__)'
Python 3
python3 -c 'import tensorflow as tf; print(tf.__version__)'
如果能正常显示版本号,比如这个版本的是1.11.0. 那么恭喜你已经完成了TensorFlow 的安装。可以愉快的开始搞事情啦
共享资源
当然你要是嫌弃自己操作不来,那么我还有我自己已经构建好的Docker image 。参考https://docs.docker.com/install/
后安装Docker,然后就可以从我的Docker库拉下来并且直接使用。
Enjoy!
Docker File:https://github.com/infinitysky/Odroid_Tensorflow_Docker/tree/Dev
(还在验证和开发中)
Docker hub :https://hub.docker.com/r/infinitysky/odroidtensorflow/
常见错误
- 在使用PIP安装 h5py 是出现下列错误
In file included from /usr/lib/python2.7/dist-packages/numpy/core/include/numpy/ndarraytypes.h:1777:0,
from /usr/lib/python2.7/dist-packages/numpy/core/include/numpy/ndarrayobject.h:18,
from /usr/lib/python2.7/dist-packages/numpy/core/include/numpy/arrayobject.h:4,
from /tmp/pip-install-U0QZSk/h5py/h5py/api_compat.h:26,
from /tmp/pip-install-U0QZSk/h5py/h5py/defs.c:654:
/usr/lib/python2.7/dist-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: warning: #warning "Using deprecated NumPy API, disable it by " "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
#warning "Using deprecated NumPy API, disable it by " \
^
In file included from /tmp/pip-install-U0QZSk/h5py/h5py/defs.c:654:0:
/tmp/pip-install-U0QZSk/h5py/h5py/api_compat.h:27:18: fatal error: hdf5.h: No such file or directory
compilation terminated.
error: command 'arm-linux-gnueabihf-gcc' failed with exit status 1
Failed building wheel for h5py
Running setup.py clean for h5py
这个问题是由于没有安装对应h5py的库文件造成的
使用 sudo apt-get install libhdf5-serial-dev hdf5-tools
安装确实的库文件后再次安装即可
- TensorFlow 已经安装完毕,但是无法调用或者调用出错怎么办?
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/tensorflow/init.py", line 22, in <module>
from tensorflow.python import pywrap_tensorflow # pylint: disable=unused-import
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/init.py", line 49, in <module>
from tensorflow.python import pywrap_tensorflow
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/pywrap_tensorflow.py", line 74, in <module>
raise ImportError(msg)
ImportError: Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/pywrap_tensorflow.py", line 58, in <module>
from tensorflow.python.pywrap_tensorflow_internal import *
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 28, in <module>
_pywrap_tensorflow_internal = swig_import_helper()
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/pywrap_tensorflow_internal.py", line 24, in swig_import_helper
_mod = imp.load_module('_pywrap_tensorflow_internal', fp, pathname, description)
ImportError: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow_internal.so)
这个就是明显没仔细看我一开始要求安装的库文件咯~
使用下列命令可破
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get -y upgrade
apt-get install -y libstdc++6