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

the*_*ith 152 c++ tensorflow

我真的很想在C++中开始使用谷歌新的Tensorflow库.关于如何构建项目的C++ API,网站和文档真的不清楚,我不知道从哪里开始.

通过发现和分享使用tensorflow的C++ API的指南,有经验帮助的人可以提供帮助吗?

mrr*_*rry 53

首先,您应该按照此处的说明从Github下载源代码(您需要Bazel和最新版本的GCC).

C++ API(和系统的后端)在tensorflow/core.目前,只支持C++ Session接口C API.您可以使用其中任何一个来执行使用Python API构建并序列化为GraphDef协议缓冲区的TensorFlow图.还有一个用于在C++中构建图形的实验性功能,但目前这并不像Python API那样功能齐全(例如目前不支持自动微分).您可以在此处看到一个用C++构建小图的示例程序.

C++ API的第二部分是用于添加新的API OpKernel,它是包含CPU和GPU的数值内核实现的类.有很多关于如何构建这些内容的示例tensorflow/core/kernels,以及在C++中添加新操作教程.

  • 没有显示C++的安装说明https://www.tensorflow.org/install/,但是有一些示例程序显示为https://www.tensorflow.org/api_guides/cc/guide,显然正在使用C++ api.你究竟是如何为Tensorflow安装C++的? (5认同)
  • @Dwight之前我看过那个页面,但是我没有看到任何关于C++的信息 (5认同)
  • 到目前为止,这还不是真正的答案。它以“开始使用”开头,然后在一个已经在此处查找指南的人们未链接的地方链接任何相关信息。这样就无法提供下一步操作,无法更改主题。 (3认同)
  • @ user3667089在上面的安装过程之后,标题将位于您在安装过程中选择的python发行版的dist-packages文件夹中(例如/usr/local/lib/python2.7/dist-packages).在该文件夹中将有一个文件夹tensorflow/include,它将包含所有标题.你需要做一些工作来确保你正在建造的东西上有它的包含路径.我个人使用CMAKE,所以我正在跋涉[this](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/public/session.h). (2认同)

Jim*_*Jim 27

要添加到@ mrry的帖子,我整理了一个教程,解释了如何使用C++ API加载TensorFlow图.它非常小,应该可以帮助您了解所有部件是如何组合在一起的.这是它的核心:

要求:

  • Bazel安装
  • 克隆TensorFlow回购

文件夹结构:

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

建立:

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

两个警告可能有解决方法:

  • 现在,需要 TensorFlow 仓库中进行构建.
  • 编译后的二进制文件很大(103MB).

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

  • 我相信现在有一个内置的构建规则.我暂时提交了PR.我不确定这些警告.我希望第一个保留,因为它是Bazel的结果,而不是TF.第二个可能会得到改善. (3认同)
  • 现在有办法让你的项目在TensorFlow源代码目录之外吗? (3认同)

小智 15

如果您希望避免使用Bazel构建项目并生成大型二进制文件,我已经组装了一个存储库,指示使用TakeorFlow C++库和CMake.你可以在这里找到它.一般的想法如下:

  • 克隆TensorFlow存储库.
  • 添加构建规则tensorflow/BUILD(提供的规则不包括所有C++功能).
  • 构建TensorFlow共享库.
  • 安装特定版本的Eigen和Protobuf,或将它们添加为外部依赖项.
  • 配置CMake项目以使用TensorFlow库.


lab*_*idi 15

首先,安装后protobufeigen,你想打造Tensorflow:

./configure
bazel build //tensorflow:libtensorflow_cc.so
Run Code Online (Sandbox Code Playgroud)

然后将以下包含标头和动态共享库复制到/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/
Run Code Online (Sandbox Code Playgroud)

最后,使用示例编译:

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
Run Code Online (Sandbox Code Playgroud)

  • 最后,https://www.tensorflow.org/install/source 上疯狂的官方构建指南用于构建 pip 模块,tks 用于构建选项“tensorflow:libtensorflow_cc.so”,它甚至没有在tensorflow.org 上记录 (2认同)

小智 14

如果您正考虑在独立包上使用Tensorflow c ++ api,您可能需要tensorflow_cc.so(还有ac api版本tensorflow.so)来构建您可以使用的c ++版本:

bazel build -c opt //tensorflow:libtensorflow_cc.so
Run Code Online (Sandbox Code Playgroud)

注意1:如果要添加内在支持,可以将此标志添加为: --copt=-msse4.2 --copt=-mavx

注意2:如果您正考虑在项目中使用OpenCV,那么将两个库一起使用时会出现问题(tensorflow问题),您应该使用--config=monolithic.

构建库后,您需要将其添加到项目中.为此,您可以包含以下路径:

tensorflow
tensorflow/bazel-tensorflow/external/eigen_archive
tensorflow/bazel-tensorflow/external/protobuf_archive/src
tensorflow/bazel-genfiles
Run Code Online (Sandbox Code Playgroud)

并将库链接到您的项目:

tensorflow/bazel-bin/tensorflow/libtensorflow_framework.so (unused if you build with --config=monolithic)
tensorflow/bazel-bin/tensorflow/libtensorflow_cc.so
Run Code Online (Sandbox Code Playgroud)

在构建项目时,您还应该向编译器指定您将使用c ++ 11标准.

侧注:相对于tensorflow版本1.5的路径(您可能需要检查您的版本中是否有任何更改).

此链接也帮助我找到了所有这些信息:链接


Ber*_*san 10

我发现使用 Tensorflow C++ API 的一种替代方法是使用 cppflow

它是围绕Tensorflow C API的轻量级 C++ 包装器。你得到非常小的可执行文件,它链接到libtensorflow.so已经编译的文件。还有一些使用示例,您可以使用 CMAKE 而不是 Bazel。


Iva*_*del 8

您可以使用此ShellScript安装(大多数)它的依赖项,克隆,构建,编译并将所有必需的文件放入../src/includes文件夹:

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


Flo*_*oop 8

如果您不介意使用CMake,也可以使用tensorflow_cc项目为您构建和安装TF C ++ API,以及可以链接的便捷CMake目标。项目README包含一个示例和您可以轻松遵循的Dockerfile。


kec*_*sap 8

如果您不想自己构建Tensorflow并且您的操作系统是Debian或Ubuntu,则可以使用Tensorflow C/C++库下载预构建的软件包.此分发可用于CPU的C/C++推断,不包括GPU支持:

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

有关于如何在Tensorflow(TFLearn)中冻结检查点并使用C/C++ API加载此模型以进行推理的说明:

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

注意:我是这个Github项目的开发者.


Mar*_*cka 5

我使用 hack/workaround 来避免自己构建整个 TF 库(这样可以节省时间(在 3 分钟内完成设置)、磁盘空间、安装开发依赖项以及生成的二进制文件的大小)。它正式不受支持,但如果您只想快速加入,它会很好用。

通过 pip (pip install tensorflowpip install tensorflow-gpu)安装 TF 。然后找到它的库_pywrap_tensorflow.so(TF 0.* - 1.0) 或_pywrap_tensorflow_internal.so(TF 1.1+)。在我的情况下(Ubuntu)它位于/usr/local/lib/python2.7/dist-packages/tensorflow/python/_pywrap_tensorflow.so. 然后创建一个指向这个库的符号链接,该库被称为lib_pywrap_tensorflow.so构建系统找到它的地方(例如/usr/lib/local)。前缀lib很重要!你也可以给它另一个lib*.so名字——如果你叫它libtensorflow.so,你可能会更好地与其他为使用 TF 而编写的程序兼容。

然后按照习惯创建一个 C++ 项目(CMake、Make、Bazel,任何你喜欢的)。

然后你就可以链接到这个库,让 TF 可用于你的项目(你还必须链接到python2.7库)!在 CMake 中,您例如只需添加target_link_libraries(target _pywrap_tensorflow python2.7).

C++ 头文件位于该库周围,例如在/usr/local/lib/python2.7/dist-packages/tensorflow/include/.

再说一次:这种方式不受官方支持,您可能会遇到各种问题。该库似乎与 protobuf 等静态链接,因此您可能会遇到奇怪的链接时或运行时问题。但是我能够加载存储的图形,恢复权重并运行推理,这是 IMO 最需要的 C++ 功能。


hak*_*ami 5

上面的答案足以展示如何构建库,但如何收集标头仍然很棘手。在这里我分享我用来复制必要标题的小脚本。

SOURCE是第一个参数,即tensorflow source(build) direcoty;
DST是第二个参数,它include directory保存收集的标头。(例如,在 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
Run Code Online (Sandbox Code Playgroud)