[原创] 在树莓派3上使用微软ELL嵌入式学习库(1)

微软于2017年6月底发布了一个主要用于嵌入式系统(例如,树莓派,ARM Cortex-M0等)的机器学习库ELLEmbedded Learning Library嵌入式学习库)。由于嵌入式设备的计算能力较弱,因此在这些设备上执行一些机器学习的任务——例如实时图像分类——通常速度很慢,所以在这种应用场景下,一般的策略是把请求发送到计算能力强大的云端服务器上去执行,嵌入式设备只作为和用户交互的终端,并不执行关键的计算任务。而微软发布的这个ELL,目标在于把云端的计算任务转移到嵌入式设备上,从而可以使得设备无需联网也能执行这些任务。这个目标看起来很诱人,但它要求ELL的计算速度很快、很节省资源,否则耗时将是不可接受的。

我在树莓派3上试验过用Tensorflow来进行图像分类(看这里:链接1链接2链接3),结果是:速度很慢,推断一张图片的类别要花4秒多时间。当然,这个时间肯定可以通过优化缩短,并且它使用的是Inception-v3模型,而不是MobileNet之类专门为移动设备设计的模型。
微软的ELL就是为了解决这个痛点而生。
在ELL发布不久后,我很好奇它在树莓派3代上的表现会如何,是不是真的很“快”,能达到非常实用的程度呢?
于是,我开始了ELL试用之路。
文章来源:https://www.codelast.com/
首先需要说明的一点是,在开始写文本时,由于ELL刚发布不久,其开发团队对这个项目处于频繁的更新中,所以很多文档、代码可能修改得很快、前后版本相差很大,所以,如果本文陈述的某些内容与你看到的最新版ELL有所不同,请不要觉得奇怪。
此外,在整个测试过程中我遇到了很多坑,ELL文档上有很多没有写清楚、还有些错误的地方,直到后面某一步操作时触发了这些问题才暴露出来,我又不得不回头去看之前的哪一步需要fix问题,所以,如果你也想试一下ELL,那么先看到本文的话,可能会让你少走些弯路。

『1』拿ELL来做什么?
首先,我们要拿ELL来实现一个什么功能?
微软官方给出的一个指导文档是《Getting Started with Computer Vision》,也就是说我们要在嵌入式系统上用ELL实现一个机器视觉的应用,以微软官方提供的下面这个图片为例:

即:用树莓派的摄像头拍摄一个物体,运行在树莓派上的ELL程序可以识别出它“是什么”。
文章来源:https://www.codelast.com/
『2』软硬件准备

  • 树莓派3代(OS:Arch Linux ARM)
  • 用于树莓派的USB摄像头(也可以用和树莓派配套的那个专用摄像头,但价格比较贵,我手上没有)
  • 台式机(OS:Ubuntu 14.04 LTS)

『3』台式机上的准备工作
不要以为我们让模型跑在树莓派上,就没有台式机什么事了。实际上,我们需要先在台式机上做非常多的工作,然后才能在树莓派上跑ELL。
所以,本文讲的就是我们要在台式机上做的那些繁琐工作,切记:本文的所有操作,都是在台式机上运行的,跟树莓派没有关系

  • 下载ELL的代码

首先我们从Github上检出ELL的代码,尽管在网页上看ELL的文档更方便一些,但是后面我们是需要用到这份代码的,所以这一步肯定要做:

git clone https://github.com/Microsoft/ELL.git

  • 安装基础软件依赖

除此之外,编译ELL还对系统有很多软件依赖,例如cmake,llvm之类,具体请看这个ELL的文档。整个安装、解决问题的过程真的相当麻烦,要有充分的心理准备。
第1点注意:cmake要装3.3版的,ELL的文档里没有写,如果你用 apt-get install cmake 安装,那么装上去的版本可能不符合要求,最后一定会出问题,导致整个流程走不下去。
所以我是这样装的cmake:

apt-cache show cmake3
sudo apt-get install cmake3

第2点注意:ELL对gcc版本有要求,但ELL的doc里没写。具体请看这篇文章

文章来源:https://www.codelast.com/

  • 安装Python 3.6——通过miniconda

为什么要用Python 3.6?因为ELL的demo程序就是Python 3.6的。
根据ELL文档的建议,我们不应该“直接”在系统里安装Python 3.6,而是通过conda环境来安装,具体请看这篇文章

  • 在miniconda环境下安装必需的软件包

安装好 miniconda 之后,需要安装 curl,numpy 和 opencv(如果没有安装过的话):

conda install curl
conda install numpy

你一定感觉很奇怪:上面的命令并没有安装OpenCV啊?!没错,这是因为,按照ELL文档的做法(conda install -c conda-forge opencv)安装上的OpenCV是有问题的——至少在我的Ubuntu上不能用。如果你着急的话,可以直接看这篇文章的解决方案;如果你不急的话,可以暂时按ELL文档的说明去安装OpenCV,然后跟着本系列文章的节奏,一点点地发现问题、解决问题(没错,后面的章节还有讲到这个问题)。

  • 安装SWIG

下一步,你需要安装用于生成language binding(语言绑定)的SWIG软件(和conda环境无关)。比如我们要用Python来调用ELL,那么就需要Python binding,诸如此类。
在Ubuntu 14.04上,用 apt-get install swig3.0 安装上的SWIG是3.0.2版本,满足不了ELL要求的“version 3.0.12 or later”,所以,我们只能自己下载、编译SWIG了:

wget https://nchc.dl.sourceforge.net/project/swig/swig/swig-3.0.12/swig-3.0.12.tar.gz
tar zxf swig-3.0.12.tar.gz
cd swig-3.0.12
./configure --without-pcre && make && sudo make install

  • 编译ELL

下面可以开始编译ELL了。这里的编译过程不要在conda环境下执行。
回到之前检出的ELL代码的根目录下,执行下面的命令:

mkdir build
cd build
cmake ..
make

如果不出错,那表明你运气是真的好。
我记得我是编译到61%的时候挂掉的,错误信息如下:

[ 0%] Built target documentation
......
[ 61%] Linking CXX executable common_test
../math/libmath.a(BlasWrapper.cpp.o): In function ell::math::Blas::Copy(int, float const*, int, float*, int)': BlasWrapper.cpp:(.text+0x31): undefined reference tocblas_scopy'
......
../math/libmath.a(BlasWrapper.cpp.o): In function ell::math::Blas::Gemm(CBLAS_ORDER, CBLAS_TRANSPOSE, CBLAS_TRANSPOSE, int, int, int, double, double const*, int, double const*, int, double, double*, int)': BlasWrapper.cpp:(.text+0x471): undefined reference tocblas_dgemm'
collect2: error: ld returned 1 exit status
make[2]: *** [libraries/common/common_test] Error 1
make[1]: *** [libraries/common/CMakeFiles/common_test.dir/all] Error 2
make: *** [all] Error 2
这个问题的解决方法请看这篇文章
 
  • 生成Python binding

接下来,需要配置miniconda里的Python环境:

# Create the environment
conda create -n py36 anaconda python=3
# Activate the environment
source activate py36
# ELL requires gcc 5 and above for C++14. Upgrade anaconda's environment to support it.
conda install libgcc

注意:第二句命令是 source activate py36,而ELL的文档里是 activate py36,一执行就报错,会提示你要在前面加source。
这一步耗时较长,等它完成之后,我们就可以生成Python binding了。在同一个命令行窗口里(刚激活了py36环境),到之前检出的ELL代码的根目录下,执行下面的命令(其实前3行命令前面已经执行过了,如果没有删除build目录的话可以不再重新执行):

mkdir build
cd build
cmake ..
make _ELL_python 

如果不出错的话,Python binding就生成成功了,但是你如果在 cmake 那一步遇到这样的错误:

CMake Error at CMakeLists.txt:5 (cmake_minimum_required):
  CMake 3.3 or higher is required.  You are running version 2.8.12.2
-- Configuring incomplete, errors occurred!

这就是本文前面的章节说过的cmake版本过低导致的,前面已经说过了如何安装高版本的cmake,这里不再复述。
然后再重新执行cmake及其后步骤,OK的话,就可以测试一下Python binding是否能正常工作。回到ELL代码的根目录,然后:

(py36) [codelast@ ELL]$ cd build/interfaces/python/test
(py36) [codelast@ test]$ python test.py

注意:一定要cd到 build/interface/python/test/ 这个目录下跑test!之所以强调这一点,是因为在ELL代码根目录下,还有一个一模一样的 interfaces/python/test/ 目录,如果你弄错了,到这个目录下跑test,会发现console没有任何输出信息,很迷惑人。
正常的test输出信息类似于下面这样:

OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Nehalem kernels as a fallback, which may give poorer performance.
Testing HingeLoss.Evaluate(2, 1) ... Passed
Testing HingeLoss.Evaluate(-2, -1) ... Passed
(中间还有很多,此处省略)
Testing SquaredLoss.GetDerivative(4, 2) ... Passed
Testing SquaredLoss.GetDerivative(2, 4) ... Passed
functions_test passed
[1] One subgraph
    Subgraph Vertices Edges Cycles
    0        6        8     3    
[2] One subgraph
    Subgraph Vertices Edges Cycles
    0        6        6     1    
(中间还有很多,此处省略)
[tree_3] One subgraph
    Subgraph Vertices Edges Cycles
    0        101      126   26   
model_test passed
Model 1 size: 6
Model 2 size: 6
Model 3 size: 8
Tree 0 size: 17
Tree 1 size: 45
Tree 2 size: 73
Tree 3 size: 101
Loading file ../../../examples/data/model_1.model
Loading file ../../../examples/data/model_2.model
common_test passed
trainers_test.test -- TBD
trainers_test passed
predictors_test.test -- TBD
predictors_test passed
nodes_test.test -- TBD
nodes_test passed
linear_test.test -- TBD
linear_test passed
evaluators_test.test -- TBD
evaluators_test passed
Testing ModelBuilder ... Passed
modelbuilder_test passed

这说明Python binding可以正常工作了。
下面,我们将进入和模型相关的测试,请看后一篇文章
文章来源:https://www.codelast.com/
➤➤ 版权声明 ➤➤ 
转载需注明出处:codelast.com 
感谢关注我的微信公众号(微信扫一扫):

wechat qrcode of codelast

《[原创] 在树莓派3上使用微软ELL嵌入式学习库(1)》有1条评论

发表评论