NXP

在imx8qm上开心把玩Machine Learning

2019-07-12 11:23发布

在imx8qm上搭建ARM-NN+Compute-Library的软件开发环境

本篇,将带领大家进入imx8qm的世界,讲述如何在imx8qm上搭建机器学习开发环境,以其让AI在imx8qm上飞奔 OS:Linux-Ubuntu-16.04

ARM-NN与Compute-Library简介

ARM-NN是一套由ARM公司所提供的开源Linux软件和工具,以支持在嵌入式设备上运行机器学习算法。特别的,针对于ARM处理架构有着特别friendly的支持!桥接了几近所有的神经网络框架与高效能的Arm cortex CPUs ( cortex-mM or cortex-A )、Arm Mali GPU ( with openCL )或Arm机器学习处理器。如图所示,为ARM所提供的机器学习框架:
在这里插入图片描述
特别的,针对于Cortex-A系列处理器,其系统架构:
在这里插入图片描述
针对于广大的MCU群体,ARM-NN同样有所涉猎:
在这里插入图片描述
因此,可以这样理解,ARM-NN其实是ARM所提供的一套上层开发套件,通过他,即可进行ML的架设!可以称之为指挥官,那么问题来了,冲锋陷阵的战士在哪里呢?当然,这个时候就要轮到Compute-Library以及CMSIS-NN(将在下期为大家进行分解)登场了,顾名思义,Compute-Library指代了一系列的数学计算库,以Cortex-A CPU和Mali GPU等可编程内核为目标,尽可能的提高算法执行效率,其利用ARM指令级对ML操作进行汇编级的优化,同时利用openCL充分利用Mali GPU的优势,利用GPU对算法进行加速。
首次发布的ARM-NN版本提供了对于Caffe的支持,同时,ARM后续还会依次发布支持TensorFlow以及其他神经网络框架的版本。那么ARM-NN是如何实现机器学习的移植的呢:
首先,ARM-NN将神经网络框架中的网络转换为内部ARM-NN的格式,然后通过Compute-Library将它们高效地部署在Cortex-A CPU和Mali-G71及Mali-G72等Mali GPU上(当然,如果你确定使用了ARM的Mali-GPU的话)。
在这里插入图片描述

环境搭建

下面将介绍如何进行软件开发环境的搭建,请切记一定要保证版本的一致!!!
  • 安装编译交叉编译器
    执行sh fsl-imx-xwayland-glibc-x86_64-fsl-image-qt5-aarch64-toolchain-4.9.51-mx8-beta.sh,安装路径选择默认,即/opt/文件夹下
  • 安装SCons
    使用linux自带的python进行安装,python版本2.7,路径为/usr/bin/python。若系统本身自带SCons3.0的版本,请卸载后安装:
    rm /usr/local/bin/scons*
    rm -r /usr/local/lib/scons*
    下载官方推荐版本SCons2.4.1,下载后解压,进入解压目录,执行sudo python setup.py install,成功结果如下图:
    在这里插入图片描述
  • 安装CMake
    官网下载cmake-3.11.1-Linux-x86_64.sh,然后直接执行sh cmake-3.11.1-Linux-x86_64.sh
  • 安装Boost
    官网下载boost-1.64.0版本源代码,解压进入文件夹,建议放在home文件夹下,运行sh bootstrap,运行结果如下:
    在这里插入图片描述
    此时对project-config.jam文件进行修改,将
    If ! gcc in [ feature.values ]
    {
    using gcc ;
    }
    修改为:
    If ! gcc in [ feature.values ]
    {
    using gcc : arm : aarch64-poky-linux-gcc ;
    }
    注意最后一个分号前的空格
    接着运行source /opt/fsl-imx-xwayland/4.9.51-mx8-beta/environment-setup-aarch64-poky-linux添加系统路径,随后执行./b2 link=static cxxflags="-fPIC --sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux" --with-filesystem --with-test --with-log --with-program_options,正确运行结果如下:
    在这里插入图片描述
    请格外注意所显示的编译器位数、工具链位数以及平台,64位平台应显示-32-bit : no -64-bit : yes、arm : yes
  • 安装caffe
    请参考链接https://blog.csdn.net/hjxu2016/article/details/70256147,在安装caffe之前请先编译protobuf,不采用交叉编译的方式,./configure无需添加参数,随后运行make,make install;INCLUDE_DIRS与LIBRARY_DIRS修改为
    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-
  • 编译Compute-Library
    执行git clone --recursive https://github.com/ARM-software/ComputeLibrary, 下载源码,进入目录执行source /opt/fsl-imx-xwayland/4.9.51-mx8-beta/environment-setup-aarch64-poky-linux添加系统路径,同时修改SConstruct文件中的
    if env[‘arch’] == ‘armv7a’:
    env.Append(CXXFLAGS = [’-march=armv7-a’, ‘-mthumb’, ‘-mfpu=neon’])
    if env[‘os’] == ‘linux’:
    prefix = “arm-linux-gnueabihf-”
    env.Append(CXXFLAGS = [’-mfloat-abi=hard’])
    修改为:
    if env[‘arch’] == ‘armv7a’:
    env.Append(CXXFLAGS = [’-march=armv7-a’, ‘-mthumb’, ‘-mfpu=neon’])
    if env[‘os’] == ‘linux’:
    prefix = “”
    env.Append(CXXFLAGS = [’-mfloat-abi=hard’])
    随后执行scons extra_cxx_flags="-fPIC --sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux" arch=arm64-v8a benchmark_tests=1 validation_tests=1 neon=1 opencl=1 -j7;
    如若出现错误:internal compile error:KIled (program cc1plus),即内存不足,执行:
    free
    dd if=dev/zero of=/var/swap.img bs=1024k count=1000
    mkswap /var/swap.img
    swapon /var/swap.img
    利用交换区实现内存扩展;
    编译结果如下:
    在这里插入图片描述
  • 交叉编译protobuf
    Protobuf官网下载所需源码protobuf-3.5.1,解压后建议放在home文件夹下,运行sh autogen.sh如出现错误autogen.sh: 50: autogen.sh: autoreconf: not found,解决方法是sudo apt install autoconf autogen;如果出现以下错误:
    Can’t exec “libtoolize”: No such file or directory at /usr/share/autoconf/Autom4te/FileUtils.pm line 345, line 6.
    autoreconf: failed to run libtoolize: No such file or directory
    autoreconf: libtoolize is needed because this package uses Libtool
    解决办法是:sudo apt install libtool
    正确运行sh autogen.sh结果如下:
    在这里插入图片描述
    随后执行source /opt/fsl-imx-xwayland/4.9.51-mx8-beta/environment-setup-aarch64-poky-linux添加系统路径,最后执行:./configure --host=aarch64-linux CC=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc CFLAGS="–sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux" CXX=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++ CXXFLAGS="–sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux" --with-protoc=/usr/local/bin/protoc --disable-static --enable-shared,运行结果如下:
    在这里插入图片描述
    执行make -7进行编译,结果见下图:
    在这里插入图片描述
    最后执行make install进行安装
  • 编译ARM-NN
    修改armnn的CMakelist.txt
    SET(CMAKE_SYSTEM_NAME Linux)
    #set(CMAKE_SYSTEM_PROCESSOR arm) #此句可有可无
#specify the cross compiler
SET(CMAKE_C_COMPILER /usr/bin/arm-linux-gnueabihf-gcc)
SET(CMAKE_CXX_COMPILER /usr/bin/arm-linux-gnueabihf-g++)
#configure Boost
SET(BOOST_ROOT /home/garylau/boost_1_64_0)
为:
set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -I /home/crist/protobuf-3.5.1_2/src/google/protobuf --sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux -std=c++11 -Wall -Werror -Wold-style-cast -Wno-missing-braces -Wconversion -Wsign-conversion -pthread”)
#this is required
SET(CMAKE_SYSTEM_NAME Linux)
#set(CMAKE_SYSTEM_PROCESSOR arm) #此句可有可无 #specify the cross compiler
SET(CMAKE_C_COMPILER /opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc)
SET(CMAKE_CXX_COMPILER /opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++)
#configure Boost
SET(BOOST_ROOT /your dir/boost_1_64_0) 执行: cmake -DARMCOMPUTE_ROOT=/home/crist/ComputeLibrary -DARMCOMPUTE_BUILD_DIR=/home/crist/ComputeLibrary/build -DBOOST_ROOT=/home/crist/boost_1_64_0 -DCAFFE_GENERATED_SOURCES=/opt/caffe/build/src -DBUILD_CAFFE_PARSER=1 -DARMCOMPUTENEON=1 -DPROTOBUF_INCLUDE_DIRS=/home/crist/protobuf-3.5.1_2/php/ext/google/protobuf -DPROTOBUF_LIBRARY_RELEASE=/home/crist/protobuf-3.5.1_2/src/.libs/libprotobuf.so -DPROTOBUF_LIBRARY_DEBUG=/home/crist/protobuf-3.5.1_2/src/.libs/libprotobuf.so将其中路径改为自己的安装路径,编译结果如下:
在这里插入图片描述
随后运行make -j7,结果如下,编译成功后可以运行UnitTests进行测试:
在这里插入图片描述
编译过程会遇到问题,you use new version protof, but found older version,解决办法是:
sudo cp -r /home/f/protobuf-ubuntu/protobuf-3.5.1/src/google/ /opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux/usr/include/
将交叉编译好的库文件拷贝到编译器的制定位置,路径根据实际情况进行修改
至此,已经完成了所有的准备工作,下面就是紧张的在线运行环节,大家期不期待,开不开心?好了,现在正式开始。

程序运行

  • GitHub下载ML-examples例程,进入文件夹armnn-mnist交叉编译测试程序
    执行source /opt/fsl-imx-xwayland/4.9.51-mx8-beta/environment-setup-aarch64-poky-linux添加系统路径:
    aarch64-poky-linux-g++ -O3 --sysroot=/opt/fsl-imx-xwayland/4.9.51-mx8-beta/sysroots/aarch64-poky-linux -std=c++14 -I/home/crist/armnn/include mnist.cpp -o mnist -L/home/crist/armnn -L/home/crist/protobuf-3.5.1_2/src/.libs -larmnn -larmnnCaffeParser -lprotobuf -lprotoc -lpthread, 路径根据实际情况进行修改;
  • 随后将依赖库拷贝进板子,执行
    scp /your lib location/libarmnn* root@10.207.203.59:/lib
  • 将程序拷贝进板子,执行:
    scp mnist_caffe root@10.207.203.59:/home/root
    在板子中运行程序观察运行结果
  • 拷贝armnn的测试程序Unitest:
    scp /your exe location/Unitest root@10.207.203.59:/home/root
    在板子上运行观察运行结果,出现no detect error即说明运行成功

总结

至此,忽忽悠悠的写完了。。。。掌声和泪水!
相信广大听众,已然被文中的概念/流程晃晕了,不过相信大家按照上面的步骤一定也可以在属于自己的那块imx8qm上成功搭建环境,并试跑例程,在这儿小小的打一个广告-》欢迎大家采购我司的imx8qm产品,性能强悍,价格公道,快来买呀!
正经总结来了。。。。我不是销售:本文向广大听友阐述了什么是ARM-NN以及Compute-Library以及如何将其交叉编译,以使得其能够成功奔跑在imx8qm上,这是一项壮举,好吧,只有我这么认为。。。毕竟我在安装的过程中,进过无数的坑,扫过无数的雷,大家给点掌声吧,谢谢了!
最后来点下期预告吧:下期将对MCU进行介绍,即如何构建CMSIS-NN软件环境,以在MCU上进行Machine Learning的移植,是的,当然还是我司的明星产品->imxRT105x and imxRT106x系列,还有,没错,我司就是兼顾MCU与MPU,全套解决方案,不好。。。又来打广告了,欢迎大家采购,,,,价格公道,我们的RT才3美金哦,快来买呀,可便宜可实惠了,高达600mhz的主频, 高达1Mb的片上ram,还有基于MPU的神奇外设,跨界MCU的鼻祖,欢迎大家抢购! 转载请注明出处