1、前言
目前在很多深度学习的模型都是使用python实现的,也都得到的不错的测试效果,这些过程都是python环境下实现的。但是,真正将训练完成的模型运用到实际中,大部分情况下都是需要在c++环境下实现,那么如何c++中调用深度学习模型呢?、
当前的深度学习框架主要包括pytorch、tensorflow/keras等两大主流,以及其他框架。tensorflow在开发时已经有c++的接口,所以我们只需要直接调用即可,但是在这之前需要配置环境。这里以tensorflow/keras框架,记录环境配置及将模型部署在多台电脑上的快速实现方法。(编译tensorf–cpu版本)
2、正文
2.1准备工作
环境:
ubuntu16.04 64位
cmake3.5.1
bazel
编译gpu版本时需要安装CUDA和cudnn,CPU时不需要
CUDA=9.0
CUDNN=8.0
版本:
tensorflow==1.8
keras==2.1
opencv==3.4
python==2.7或者3.5
首先使用anaconda建立虚拟环境,python==3.5(使用2.7会导致后面安装opencv3.4可能会有问题,使用3.5编译)。
conda create -n py27tf python=3.5(这里名字是py27_tf)
conda install tensorflow=1.8
pip install keras==2.1
安装opencv3.4(自行实现)
安装bazel(自行实现)
安装protobuf(见后面安装过程)
2.2 编译tensorflow
编译过程可以参考:
hh zz:tensorflow工程化(一)-在linux上编译lib
下载tensorflow源码,选择1.8版本
解压缩后,重命名为tensorflow_backup
cd tensorflow_backup
./configure
编译cpu版本时,有关gpu和cudnn直接选n,注意路径选择的地方,确定是否一致。
编译gpu版本时,选择gpu和cudnn的版本及路径。
一般cpu版本直接就能成功,gpu版本可能会出现错误,错误百度解决。完成后直接编译即可。
编译GPU版本
bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so
编译CPU版本
bazel build --config=opt //tensorflow:libtensorflow_cc.so
若没有报错就说明编译完成了,接下来就可以直接测试了。
编译依赖库(参考seniusen:编译 TensorFlow 的 C/C++ 接口)
进入 tensorflow/contrib/makefile 目录下,运行./build_all_linux.sh
这里包括protobuf
2.3测试
下载代码进行测试,参考教程https://blog.csdn.net/qq_25109263/article/details/81285952
修改路径。
测试完成后,说明编译通过而且库文件完整,可以进行下一步。
3、快速部署模型到多台电脑上
在上述完成编译后,如果我想将模型部署到多台电脑上,除了像上述过程一样,每台电脑重新编译tensoflow之外,有没有更快捷的办法呢?其实,这和window下是一样的,只要将工程的依赖库全部复制出来到其他电脑上,也是可以用的。这里我先安装了anconda。
3.1 准备文件
根据上述的cmakelist文件夹,可以确定依赖库的位置。
上述文件夹是编译完成tensorflow 的文件夹,可以看到里面有快捷方式文件夹。
需要将bazel-bin,bazel-genfiles内部的文件复制出来才可以完成对快捷方式文件夹的复制。
这里需要的文件如下:
这里的/usr/local/include 里面opencv、opencv2、google三个文件夹直接复制到新文件夹include。
将~/anaconda2/envs/py27_tf/lib 下的有关opencv的so文件全部复制到新文件夹lib下
将~/anaconda2/envs/py27_tf/下的share文件夹复制到新的路径下
将tensorflow_backup/bazel-bin/tensorflow下的libtensorflow_cc.so和libtensorflow_framework.so两个文件复制到新文件夹tflibs下。
完成上述文件的抽取后,形成的文件夹是如下图。
总文件夹submission
其中每个文件夹的内容如下:
子文件夹include
子文件夹lib
子文件夹share
子文件夹tf
子文件夹tflibs
需要特别注意的是,五个文件夹中lib文件夹和share文件夹的名字是不能变的,其他的可以随意修改。
3.2 测试
完成上述的文件准备工作后,将这个文件夹复制到新的电脑上即可。
此时在测试时,cmakelist内的路径是:
在编译时.so文件和.h文件优先在默认路径下寻找,(/usr/local/lib和/usr/local/include)。这里我们整理的上述的submission文件夹包括了c++调用keras模型的所有库文件和头文件,一次不需要从默认路径下寻找,为了说明这一点,我将/usr/local/lib和/usr/local/include两个文件夹全部删除了。(您自己最好不要这样做,可能会删除很多东西,影响其他软件的使用。)
删除lib文件夹和include文件夹
接下来就直接测试了。
测试结果
3.3可能出现的错误
错误1:cmake时候报错
一般是路径问题。
错误2:
warning: libjpeg.so.9, needed by /home/.../anaconda2/lib/libopencv_imgcodecs.so, not found
参考:
https://blog.csdn.net/akadiao/article/details/79834086 blog.csdn.net
错误3:
lib/libpng16.so.16: undefined reference to `inflateValidate@ZLIB_1.2.9'
参考:
https://blog.csdn.net/xiangxianghehe/article/details/79125155 blog.csdn.net
4后记
本文记录了在ubuntu下编译tensorflow-cpu的过程,其中也遇到很多错误,错误没有记录下来,一般错误百度都会有解决的办法。
至于最后的文件夹submission,我后续会上传至github或者百度云上。
如果您有什么问题,可以邮件与我联系:
chenyuan72530@gmail.com
github主页