简体   繁体   English

如何构建和使用 Google TensorFlow C++ api

[英]How to build and use Google TensorFlow C++ api

I'm really eager to start using Google's new Tensorflow library in C++.我真的很想开始在 C++ 中使用 Google 的新 Tensorflow 库。 The website and docs are just really unclear in terms of how to build the project's C++ API and I don't know where to start.网站和文档在如何构建项目的 C++ API 方面真的不清楚,我不知道从哪里开始。

Can someone with more experience help by discovering and sharing a guide to using tensorflow's C++ API?有更多经验的人可以通过发现和分享使用 tensorflow 的 C++ API 的指南来提供帮助吗?

To get started, you should download the source code from Github, by following the instructions here (you'll need Bazel and a recent version of GCC).首先,您应该按照此处的说明从 Github 下载源代码(您需要Bazel和最新版本的 GCC)。

The C++ API (and the backend of the system) is in tensorflow/core . C++ API(和系统的后端)在tensorflow/core Right now, only the C++ Session interface , and the C API are being supported.目前,仅支持C++ Session interfaceC API You can use either of these to execute TensorFlow graphs that have been built using the Python API and serialized to a GraphDef protocol buffer.您可以使用其中任何一个来执行使用 Python API 构建并序列化到GraphDef协议缓冲区的 TensorFlow 图。 There is also an experimental feature for building graphs in C++, but this is currently not quite as full-featured as the Python API (eg no support for auto-differentiation at present).在 C++ 中还有一个用于构建图形的实验性功能,但目前它不像 Python API 那样功能齐全(例如,目前不支持自动微分)。 You can see an example program that builds a small graph in C++ here .您可以在此处查看使用 C++ 构建小图的示例程序。

The second part of the C++ API is the API for adding a new OpKernel , which is the class containing implementations of numerical kernels for CPU and GPU. C++ API 的第二部分是用于添加新OpKernel的 API,该类包含 CPU 和 GPU 数值内核的实现。 There are numerous examples of how to build these in tensorflow/core/kernels , as well as a tutorial for adding a new op in C++ .有许多示例说明如何在tensorflow/core/kernels构建这些,以及在 C++ 中添加新操作教程

To add to @mrry's post, I put together a tutorial that explains how to load a TensorFlow graph with the C++ API.为了补充@mrry 的帖子,我整理了一个教程,解释了如何使用 C++ API 加载 TensorFlow 图。 It's very minimal and should help you understand how all of the pieces fit together.它非常小,应该可以帮助您了解所有部分是如何组合在一起的。 Here's the meat of it:这是它的肉:

Requirements:要求:

  • Bazel installed安装了巴泽尔
  • Clone TensorFlow repo克隆 TensorFlow 存储库

Folder structure:文件夹结构:

  • tensorflow/tensorflow/|project name|/
  • tensorflow/tensorflow/|project name|/|project name|.cc (eg https://gist.github.com/jimfleming/4202e529042c401b17b7)
  • tensorflow/tensorflow/|project name|/BUILD

BUILD:建造:

cc_binary(
    name = "<project name>",
    srcs = ["<project name>.cc"],
    deps = [
        "//tensorflow/core:tensorflow",
    ]
)

Two caveats for which there are probably workarounds:可能有解决方法的两个警告:

  • Right now, building things needs to happen within the TensorFlow repo.现在,需要TensorFlow 存储库中进行构建。
  • The compiled binary is huge (103MB).编译后的二进制文件很大(103MB)。

https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f

If you are thinking into using Tensorflow c++ api on a standalone package you probably will need tensorflow_cc.so ( There is also ac api version tensorflow.so ) to build the c++ version you can use:如果您正在考虑在独立包上使用 Tensorflow c++ api,您可能需要 tensorflow_cc.so (还有 ac api 版本 tensorflow.so )来构建您可以使用的 c++ 版本:

bazel build -c opt //tensorflow:libtensorflow_cc.so

Note1: If you want to add intrinsics support you can add this flags as: --copt=-msse4.2 --copt=-mavx注意1:如果你想添加内在支持,你可以添加这个标志:-- --copt=-msse4.2 --copt=-mavx

Note2: If you are thinking into using OpenCV on your project as well, there is an issue when using both libs together ( tensorflow issue ) and you should use --config=monolithic .注2:如果您也考虑在您的项目中使用 OpenCV,则在同时使用两个库时会出现问题( tensorflow 问题),您应该使用--config=monolithic

After building the library you need to add it to your project.构建库后,您需要将其添加到您的项目中。 To do that you can include this paths:为此,您可以包含以下路径:

tensorflow
tensorflow/bazel-tensorflow/external/eigen_archive
tensorflow/bazel-tensorflow/external/protobuf_archive/src
tensorflow/bazel-genfiles

And link the library to your project:并将库链接到您的项目:

tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so (unused if you build with --config=monolithic)
tensorflow/bazel-bin/tensorflow/libtensorflow_cc.so

And when you are building your project you should also specify to your compiler that you are going to use c++11 standards.当您构建项目时,您还应该向编译器指定您将使用 c++11 标准。

Side Note: Paths relative to tensorflow version 1.5 (You may need to check if in your version anything changed).旁注:相对于 tensorflow 1.5 版的路径(您可能需要检查您的版本中是否有任何更改)。

Also this link helped me a lot into finding all this infos: link此链接也帮助我找到了所有这些信息: 链接

First, after installing protobuf and eigen , you'd like to build Tensorflow:首先,在安装protobufeigen ,您想构建 Tensorflow:

./configure
bazel build //tensorflow:libtensorflow_cc.so

Then Copy the following include headers and dynamic shared library to /usr/local/lib and /usr/local/include :然后将以下头文件和动态共享库复制到/usr/local/lib/usr/local/include

mkdir /usr/local/include/tf
cp -r bazel-genfiles/ /usr/local/include/tf/
cp -r tensorflow /usr/local/include/tf/
cp -r third_party /usr/local/include/tf/
cp -r bazel-bin/libtensorflow_cc.so /usr/local/lib/

Lastly, compile using an example:最后,使用示例进行编译:

g++ -std=c++11 -o tf_example \
-I/usr/local/include/tf \
-I/usr/local/include/eigen3 \
-g -Wall -D_DEBUG -Wshadow -Wno-sign-compare -w  \
-L/usr/local/lib/libtensorflow_cc \
`pkg-config --cflags --libs protobuf` -ltensorflow_cc tf_example.cpp

If you wish to avoid both building your projects with Bazel and generating a large binary, I have assembled a repository instructing the usage of the TensorFlow C++ library with CMake.如果您希望避免使用 Bazel 构建项目和生成大型二进制文件,我已经组装了一个存储库,指导如何使用 TensorFlow C++ 库和 CMake。 You can find it here .你可以在这里找到它。 The general ideas are as follows:大体思路如下:

  • Clone the TensorFlow repository.克隆 TensorFlow 存储库。
  • Add a build rule to tensorflow/BUILD (the provided ones do not include all of the C++ functionality).tensorflow/BUILD添加构建规则(提供的规则不包括所有 C++ 功能)。
  • Build the TensorFlow shared library.构建 TensorFlow 共享库。
  • Install specific versions of Eigen and Protobuf, or add them as external dependencies.安装特定版本的 Eigen 和 Protobuf,或将它们添加为外部依赖项。
  • Configure your CMake project to use the TensorFlow library.配置您的 CMake 项目以使用 TensorFlow 库。

One alternative to using Tensorflow C++ API I found is to use cppflow .我发现使用 Tensorflow C++ API 的一种替代方法是使用cppflow

It's a lightweight C++ wrapper around Tensorflow C API .它是围绕Tensorflow C API的轻量级 C++ 包装器。 You get very small executables and it links against the libtensorflow.so already compiled file.你得到非常小的可执行文件,它链接到libtensorflow.so已经编译的文件。 There are also examples of use and you use CMAKE instead of Bazel.还有一些使用示例,您可以使用 CMAKE 而不是 Bazel。

If you don't mind using CMake, there is also tensorflow_cc project that builds and installs TF C++ API for you, along with convenient CMake targets you can link against.如果您不介意使用 CMake,还有tensorflow_cc项目可以为您构建和安装 TF C++ API,以及您可以链接的方便的 CMake 目标。 The project README contains an example and Dockerfiles you can easily follow.项目 README 包含一个示例和您可以轻松遵循的 Dockerfile。

You can use this ShellScript to install (most) of it's dependencies, clone, build, compile and get all the necessary files into ../src/includes folder:您可以使用此 ShellScript 来安装(大部分)它的依赖项、克隆、构建、编译并将所有必需的文件放入../src/includes文件夹:

https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh

If you don't want to build Tensorflow yourself and your operating system is Debian or Ubuntu, you can download prebuilt packages with the Tensorflow C/C++ libraries.如果您不想自己构建 Tensorflow,并且您的操作系统是 Debian 或 Ubuntu,您可以下载带有 Tensorflow C/C++ 库的预构建包。 This distribution can be used for C/C++ inference with CPU, GPU support is not included:此发行版可用于 CPU 的 C/C++ 推理,不包括 GPU 支持:

https://github.com/kecsap/tensorflow_cpp_packaging/releases https://github.com/kecsap/tensorflow_cpp_packaging/releases

There are instructions written how to freeze a checkpoint in Tensorflow (TFLearn) and load this model for inference with the C/C++ API:有关于如何在 Tensorflow (TFLearn) 中冻结检查点并加载此模型以使用 C/C++ API 进行推理的说明:

https://github.com/kecsap/tensorflow_cpp_packaging/blob/master/README.md https://github.com/kecsap/tensorflow_cpp_packaging/blob/master/README.md

Beware: I am the developer of this Github project.当心:我是这个 Github 项目的开发者。

I use a hack/workaround to avoid having to build the whole TF library myself (which saves both time (it's set up in 3 minutes), disk space, installing dev dependencies, and size of the resulting binary).我使用 hack/workaround 来避免自己构建整个 TF 库(这样可以节省时间(3 分钟内完成设置)、磁盘空间、安装开发依赖项以及生成的二进制文件的大小)。 It's officially unsupported, but works well if you just want to quickly jump in.它正式不受支持,但如果您只想快速加入,它会很好用。

Install TF through pip ( pip install tensorflow or pip install tensorflow-gpu ).通过 pip 安装 TF( pip install tensorflowpip install tensorflow-gpu )。 Then find its library _pywrap_tensorflow.so (TF 0.* - 1.0) or _pywrap_tensorflow_internal.so (TF 1.1+).然后找到它的库_pywrap_tensorflow.so (TF 0.* - 1.0) 或_pywrap_tensorflow_internal.so (TF 1.1+)。 In my case (Ubuntu) it's located at /usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so .在我的情况下(Ubuntu)它位于/usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so Then create a symlink to this library called lib_pywrap_tensorflow.so somewhere where your build system finds it (eg /usr/lib/local ).然后在你的构建系统找到它的地方创建一个名为lib_pywrap_tensorflow.so库的符号链接(例如/usr/lib/local )。 The prefix lib is important!前缀lib很重要! You can also give it another lib*.so name - if you call it libtensorflow.so , you may get better compatibility with other programs written to work with TF.你也可以给它另一个lib*.so名字——如果你叫它libtensorflow.so ,你可能会更好地与其他为使用 TF 而编写的程序兼容。

Then create a C++ project as you are used to (CMake, Make, Bazel, whatever you like).然后按照习惯创建一个 C++ 项目(CMake、Make、Bazel,任何你喜欢的)。

And then you're ready to just link against this library to have TF available for your projects (and you also have to link against python2.7 libraries)!然后你就可以链接到这个库,让 TF 可用于你的项目(你还必须链接到python2.7库)! In CMake, you eg just add target_link_libraries(target _pywrap_tensorflow python2.7) .在 CMake 中,您例如只需添加target_link_libraries(target _pywrap_tensorflow python2.7)

The C++ header files are located around this library, eg in /usr/local/lib/python2.7/dist-packages/tensorflow/include/ . C++ 头文件位于该库周围,例如在/usr/local/lib/python2.7/dist-packages/tensorflow/include/

Once again: this way is officially unsupported and you may run in various issues.再说一次:这种方式不受官方支持,您可能会遇到各种问题。 The library seems to be statically linked against eg protobuf, so you may run in odd link-time or run-time issues.该库似乎与 protobuf 等静态链接,因此您可能会遇到奇怪的链接时或运行时问题。 But I am able to load a stored graph, restore the weights and run inference, which is IMO the most wanted functionality in C++.但是我能够加载存储的图形,恢复权重并运行推理,这是 IMO 最需要的 C++ 功能。

answers above are good enough to show how to build the library, but how to collect the headers are still tricky.上面的答案足以说明如何构建库,但如何收集标题仍然很棘手。 here I share the little script I use to copy the necessary headers.在这里我分享我用来复制必要标题的小脚本。

SOURCE is the first param, which is the tensorflow source(build) direcoty; SOURCE是第一个参数,它是 tensorflow source(build) direcoty;
DST is the second param, which is the include directory holds the collected headers. DST是第二个参数,它是include directory收集到的头文件的include directory (eg. in cmake, include_directories(./collected_headers_here) ). (例如,在 cmake 中, include_directories(./collected_headers_here) )。

#!/bin/bash

SOURCE=$1
DST=$2
echo "-- target dir is $DST"
echo "-- source dir is $SOURCE"

if [[ -e $DST ]];then
    echo "clean $DST"
    rm -rf $DST
    mkdir $DST
fi


# 1. copy the source code c++ api needs
mkdir -p $DST/tensorflow
cp -r $SOURCE/tensorflow/core $DST/tensorflow
cp -r $SOURCE/tensorflow/cc $DST/tensorflow
cp -r $SOURCE/tensorflow/c $DST/tensorflow

# 2. copy the generated code, put them back to
# the right directories along side the source code
if [[ -e $SOURCE/bazel-genfiles/tensorflow ]];then
    prefix="$SOURCE/bazel-genfiles/tensorflow"
    from=$(expr $(echo -n $prefix | wc -m) + 1)

    # eg. compiled protobuf files
    find $SOURCE/bazel-genfiles/tensorflow -type f | while read line;do
        #echo "procese file --> $line"
        line_len=$(echo -n $line | wc -m)
        filename=$(echo $line | rev | cut -d'/' -f1 | rev )
        filename_len=$(echo -n $filename | wc -m)
        to=$(expr $line_len - $filename_len)

        target_dir=$(echo $line | cut -c$from-$to)
        #echo "[$filename] copy $line $DST/tensorflow/$target_dir"
        cp $line $DST/tensorflow/$target_dir
    done
fi


# 3. copy third party files. Why?
# In the tf source code, you can see #include "third_party/...", so you need it
cp -r $SOURCE/third_party $DST

# 4. these headers are enough for me now.
# if your compiler complains missing headers, maybe you can find it in bazel-tensorflow/external
cp -RLf $SOURCE/bazel-tensorflow/external/eigen_archive/Eigen $DST
cp -RLf $SOURCE/bazel-tensorflow/external/eigen_archive/unsupported $DST
cp -RLf $SOURCE/bazel-tensorflow/external/protobuf_archive/src/google $DST
cp -RLf $SOURCE/bazel-tensorflow/external/com_google_absl/absl $DST

Tensorflow itself only provides very basic examples about C++ APIs. Tensorflow 本身仅提供有关 C++ API 的非常基本的示例。
Here is a good resource which includes examples of datasets, rnn, lstm, cnn and more这是一个很好的资源,其中包括数据集、rnn、lstm、cnn 等的示例
tensorflow c++ examples张量流 C++ 示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM