linux下深度学习框架tensorflow2.0的编译和C++接口使用

谷歌发布了tensorflow2.0后带来全新的使用体验和深度学习实践模式,这里基于新版本进行编译,并使用其C++接口编写示例。

环境

本文只针对linux系统(windows下尝试过多次后未成功,放弃)

  • ubuntu14.04
  • gcc4.8.5
  • cmake3.10.2

编译

目的是编译出tensorflow的动态链接库以及准备好tensorflow第三方依赖库

安装bazel

tensorflow是谷歌官方项目,用的是自家的bazel构建的

官网下载bazel安装:https://bazel.build

推荐使用sh脚本一键安装

编译tensorflow动态库

下载源码,切换到r2.0分支,编译

git clone https://github.com/tensorflow/tensorflow
cd tensorflow
git checkout -b r2.0 remotes/origin/r2.0
./configure

configure步骤会有很多配置项
其中,python的路径设置成python3的目录,其他全部默认值即可

然后通过bazel编译
如果不需要cuda版,则输入

bazel build --config=opt //tensorflow:libtensorflow_cc.so

如果需要cuda版,则输入

bazel build --config=opt --config=cuda //tensorflow:libtensorflow_cc.so

这个过程需要全程保持联网(科学上网),会在编译的过程中联网下载很多依赖,时间较长,耐心等待

成功后,会生成若干个目录

在tensorflow根目录的bazel-bin/tensorflow文件夹下会出现libtensorflow_cc.so以及libtensorflow_framework.so等文件(有些是软链接),建议将其拷贝出来到根目录的新建的lib目录,比如

tensorflow/lib
├── libtensorflow_cc.so
├── libtensorflow_cc.so.1
├── libtensorflow_framework.so
└── libtensorflow_framework.so.1

确保这个四个文件一定要有

在在tensorflow根目录的bazel-genfiles文件夹下会出现一些额外的h和cc等文件,这些是重要的依赖文件,建议将其拷贝出来到根目录新建的bazel-include目录,比如

tensorflow/bazel-include 
└── tensorflow

确保tensorflow这个文件夹一定要有

准备第三方依赖库

tensorflow需要用到第三方库文件比如Protobuf以及矩阵库Eigen等,应该使用官方依赖的对应版本,可以避免tensorflow和第三方库版本不对应而产生的问题,用tensorflow项目自带的脚本下载和编译这些依赖库

cd tensorflow
cd tensorflow/contrib/makefile
./build_all_linux.sh

同样的,这个过程需要全程保持联网(科学上网)

执行成功后,在tensorflow/tensorflow/contrib/makefile会产生两个文件夹

  • downloads存放第三方依赖的一些头文件和静态库,比如nsync、Eigen等
  • gen存放tensorflow生成必要的pb头文件

至此,tensorflow编译完成,可以使用C++接口编写程序了

使用

构建C++程序,调用tensorflow库

工程结构

.
├── CMakeLists.txt
└── src
    └── main.cpp

其中

CMakeLists.txt

project(tensorflow_cpp_test)
cmake_minimum_required(VERSION 3.0)

add_definitions(-std=c++11)

set(TENSORFLOW_ROOT_DIR /home/tashaxing/codetest/tensorflow)

# add other include dir if needed
include_directories(
    ${TENSORFLOW_ROOT_DIR}
    ${TENSORFLOW_ROOT_DIR}/bazel-include
    ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/gen/proto
    ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/gen/protobuf/include
    ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/downloads/eigen
    ${TENSORFLOW_ROOT_DIR}/tensorflow/contrib/makefile/downloads/absl
)

aux_source_directory(./src DIR_SRCS)

link_directories(/home/tashaxing/codetest/tensorflow/lib)

add_executable(tensorflow_cpp_test ${DIR_SRCS})
target_link_libraries(tensorflow_cpp_test
    tensorflow_cc
    tensorflow_framework
)

main.cpp

#include <iostream> #include "tensorflow/cc/client/client_session.h" #include "tensorflow/cc/ops/standard_ops.h" #include "tensorflow/core/framework/tensor.h" 
using namespace tensorflow;
using namespace tensorflow::ops;

int main()
{
  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));
  std::cout << "tensorflow session run ok" << std::endl;
  // Expect outputs[0] == [19; -3]   std::cout << outputs[0].matrix<float>();

  return 0;
}

输出结果

tensorflow session run ok
19
-3

实际上,tensorflow的后端都是C++写的,那么用C++的接口直接进行模型训练和加载预测,在性能上是非常可观的

《linux下深度学习框架tensorflow2.0的编译和C++接口使用》
支持是知识分享的动力,有问题可扫码哦

    原文作者:踏莎行
    原文地址: https://zhuanlan.zhihu.com/p/69216722
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞