Tensorflow C++库的编译和使用方法

#Tensorflow C++库的编译和使用方法

网上编译或者安装Tensorflow的教程大多数都是Python相关的,有少量C或者C++的,但版本又比较老不适合最新的Tensorflow教程,本博记录如何在Linux上从源码编译并使用Tensorflow库:

  • 准备工作
    • 选择ubuntu14.04或者16.04做开发机
      • 因为这是google支持的官方linux版本;选择其他linux版本也是可以的,但如果有坑(肯定有坑,tensorflow并不是一个成熟的开源产品),google可能不会给你解决,即使你自己解决了,google也不会合并到官方版中去,这样就意味着要么你必须自己维护fix。我就发现了其他版本上的好几个问题反馈给google,google都说非官方版本,有时间的时候再处理。
    • bazel安装
      • 最简单的方式是下载bazel代码自己编译,不然会遇到各种库和gcc的匹配问题,到bazel官网下载https://github.com/bazelbuild/bazel/releases,必须下载dist版本,不然不让编。。。
      • 下载后运行./compile.sh
      • 如果发现有gcc报rep指令出错,必须升级binutils到22以上版本;可能需要安装jdk1.8,到oracle官网下载安装
    • 升级binutils到22以上版本
  • 下载代码
    • 到github下载tensorflow源码
  • 编译
    • ./configure;
      • 可以一路回车。需要注意的就是是否需要GPU,需要的话就选上,不需要就不用选;另外一点就是根据你的产品CPU选择编译优化选项,默认是-march=native,如果你的编译机器和产品运行机器的CPU一样,则可以选,但如果CPU不一样,则要根据你的产品机器的CPU选择优化选项,我配置的是-march=core-avx2
    • 用bazel进行build
      • bazel build -c opt --verbose_failures //tensorflow:libtensorflow_cc.so,若编译c版本则为bazel build -c opt --verbose_failures //tensorflow:libtensorflow.so
      • –verbose_failures是为了当编译有错的时候,可以看到出错时的编译命令,方便查找原因或向google反馈
    • 用makefile进行编译
      • 到tensorflow/contrib/makefile目录下运行build_all_linux.sh,其他平台比如ios,android版本的编译脚本也在这个目录下,运行对应脚本即可
  • 测试
    • 如果是在ubuntu14.04和16.04上编译,基本上不会碰到什么问题,如果不是那问题很多,各种编译工具和库版本不匹配的问题,只能慢慢解决,还是建议用ubuntu。
    • 编译完以后,就可以测试了:
    • 用makefile编译的,可以在tensorflow/contrib/makefile/gen/bin/目录下,看到编译成功的测试程序,运行该程序,需要到tensorflow下载tensorflow_inception_graph.pb文件(https://github.com/martinwicke/tensorflow-tutorial/blob/master/tensorflow_inception_graph.pb),然后作为命令行参数输入:
      ./gen/bin/benchmark --graph=~/test_data/tensorflow_inception_graph.pb
    • 用bazel编译的可以在tensorflow/cc/example目录下,
      • 写一个BUILD文件和测试程序代码,如:
load("//tensorflow:tensorflow.bzl", "tf_cc_binary")

tf_cc_binary(
    name = "example",
    srcs = ["example.cc"],
    deps = [
        "//tensorflow/cc:cc_ops",
        "//tensorflow/cc:client_session",
        "//tensorflow/core:tensorflow",
    ],
)

 //tensorflow/cc/example/example.cc

#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"

int main() {
  using namespace tensorflow;
  using namespace tensorflow::ops;
  Scope root = Scope::NewRootScope();
  // Matrix A = [3 2; -1 0]
  auto A = Const(root, { {3.f, 2.f}, {-1.f, 0.f} });
  // Vector b = [3 5]
  auto b = Const(root, { {3.f, 5.f} });
  // v = Ab^T
  auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
  std::vector<Tensor> outputs;
  ClientSession session(root);
  // Run and fetch v
  TF_CHECK_OK(session.Run({v}, &outputs));
  // Expect outputs[0] == [19; -3]
  LOG(INFO) << outputs[0].matrix<float>();
  return 0;
}

编译成功后在tensorflow目录下,运行:
bazel run -c opt //tensorflow/cc/example:example

  • 把编译的c++库和头文件用到你自己的产品中
    • 自己去编译的目的肯定不是为了编译而编译,而是为了把google的tensorflow库或者你优化过的tensorflow库用到你的产品中,有两种方法:1是用google的bazel系统,把自己的项目放到bazel tensorflow里;2.是把编译好的库拿到自己产品的编译环境中。最好管理的就是第2种方法,但也是比较麻烦的。因为tensorflow在这方面可用性实在太差,没有一个统一的目录存放对外的头文件,没有一个统一的地方存放编译好的库。网上很多文章提到的头文件和库都已经过时,如果按照那些方法,都没法使用tensorflow的库。
    • 基于tensorflow的测试用例,我们有方法知道最完整的库和头文件的路径:
      • 修改tensorflow/contrib/makefile下的Makefile,用到你的项目中
      • 利用makefile编译时打印的命令行查看需要的头文件目录和库的名称,需要的编译选项,而且无论tensorflow的版本怎么变化,我们都能拿到最全的库和头文件。比如我在编译的时候,最后能看到这样的命令:
gcc --std=c++11 -DIS_SLIM_BUILD -fno-exceptions -DNDEBUG -O3 -march=native -fPIC -I. -I/home/yourpath/tensorflow/contrib/makefile/downloads/ -I/home/yourpath/tensorflow/contrib/makefile/downloads/eigen -I/home/yourpath/tensorflow/contrib/makefile/downloads/gemmlowp -I/home/yourpath/tensorflow/contrib/makefile/downloads/nsync/public -I/home/yourpath/tensorflow/contrib/makefile/downloads/fft2d -I/home/yourpath/tensorflow/contrib/makefile/downloads/double_conversion -I/home/yourpath/tensorflow/contrib/makefile/gen/proto/ -I/home/yourpath/tensorflow/contrib/makefile/gen/proto_text/ -I/home/yourpath/tensorflow/contrib/makefile/gen/protobuf-host/include -I/usr/local/include -o /home/yourpath/tensorflow/contrib/makefile/gen/bin/benchmark /home/yourpath/tensorflow/contrib/makefile/gen/obj/tensorflow/core/util/reporter.o /home/yourpath/tensorflow/contrib/makefile/gen/obj/tensorflow/tools/benchmark/benchmark_model.o /home/yourpath/tensorflow/contrib/makefile/gen/obj/tensorflow/tools/benchmark/benchmark_model_main.o  -L/home/yourpath/tensorflow/contrib/makefile/gen/protobuf-host/lib -Wl,--allow-multiple-definition -Wl,--whole-archive /home/yourpath/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a -Wl,--no-whole-archive tensorflow/contrib/makefile/downloads/nsync/builds/default.linux.c++11/nsync.a -lstdc++ -lprotobuf -lz -lm -ldl -lpthread
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值