Tensorflow当前官网仅包含python、C、Java、Go的发布包,并无C++ release包,并且tensorflow官网也注明了并不保证除python以外库的稳定性,在功能方面python也是最完善的。众所周知,python在开发效率、易用性上有着巨大的优势,但作为一个解释性语言,在性能方面还是存在比较大的缺陷,在各类AI服务化过程中,采用python作为模型快速构建工具,使用高级语言(如C++,java)作为服务化程序实现是大势所趋。本文重点介绍tensorflow C++服务化过程中实现方式及遇到的各种问题。
对于tensorflow c++库的使用,有两种方法:
(1) 最佳方式当然是直接用C++构建graph,但是当前c++tensorflow库并不像python api那样full-featured。可参照builds a small graph in c++ here, C++ tensorflow api中还包含cpu和gpu的数字内核实现的类,可用以添加新的op。可参照https://www.tensorflow.org/extend/adding_an_op
(2) 常用的方式,c++调用python生成好的graph。本文主要介绍该方案。
(1) 编译tensorflow源码C++ so
(2) 模型训练输出结果
(3) 模型固化
(4) 模型加载及运行
(5) 运行问题
环境要求: 公司tlinux2.2版本, GCC版本 >= 4.8.5
安装组件: protobuf 3.3.0 bazel 0.5.0 python 2.7 java8
机器要求: 4GB内存
a. 安装java8
yum install java
b. 安装protobuf 3.3.0
下载 下载https://github.com/google/protobuf/archive/v3.3.0.zip
./configure && make && make install
c. 安装bazel
download https://github.com/bazelbuild/bazel/releases
sh bazel-0.5.0-installer-linux-x86_64.sh
d. 编译源码
最好采用最新release版本:https://github.com/tensorflow/tensorflow/releases
bazel build //tensorflow:libtensorflow_cc.so
编译过程中可能遇到的问题:
问题一: fatal error: unsupported/Eigen/CXX11/Tensor: No such file or directory
安装Eigen3.3或以上版本
问题二: java.io.IOException: Cannot run program "patch"
yum install patch
问题三: 内存不够

模型训练输出可参照改用例去实践https://blog.metaflow.fr/tensorflow-saving-restoring-and-mixing-multiple-models-c4c94d5d7125 , google上也很多,模型训练保存好得到下面文件:
模型固化方式有三种:
a. freeze_graph 工具
b. 利用freeze_graph.py工具
c. 利用tensorflow python
import os, argparseimport tensorflow as tffrom tensorflow.python.framework import graph_util
在具体实际项目,用方式一与方式二将生成的模型利用tensorflow c++ api加载,报以上错误,采用tensorflow python加载模型报同样错:
原因是模型中用到了BatchNorm,修复方式如上面c中给出的方案
构建输入输出
模型输入输出主要就是构造输入输出矩阵,相比python的numpy库,tensorflow提供的Tensor和Eigen::Tensor还是非常难用的,特别是动态矩阵创建,如果你的编译器支持C++14,可以用xTensor库,和numpy一样强大,并且用法机器类似。如果是C++11版本就好好看看eigen库和tensorflow::Tensor文档吧。例举集中简单的用法:
矩阵赋值:
SOFTMAX:
模型加载及session初始化:
运行:
0.10以上的tensorflow库是线程安全的,因此可多线程调用predict
问题一:运行告警
是因为在编译tensorflow so库的时候没有把这些CPU加速指令编译进去,因此可以在编译的时候加入加速指令,在没有GPU条件下,加入这些库实测可以将CPU计算提高10%左右。
需要注意的是并不是所有CPU都支持这些指令,一定要实机测试,以免abort。
问题二: C++ libtensorflow和python tensorflow混用
为验证C++加载模型调用的准确性,利用swig将c++ api封装成了python库供python调用,在同时import tensorflow as tf和import封装好的python swig接口时,core dump
该问题tensorflow官方并不打算解决
本文来自 全球人工智能 微信公众号