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


168

我真的很想开始在C ++中使用Google的新Tensorflow库。网站和文档在如何构建项目的C ++ API方面还不清楚,我不知道从哪里开始。

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


4
为您的问题+1。有机会在Windows上安装/编译吗?网站仅显示Linux / Mac。需要指导来运行挡板。这个例子可能是一个很好的起点,以学习:github.com/tensorflow/tensorflow/tree/master/tensorflow/...
alrama

这个问题仍然没有答案。如何仅安装C ++ tensorflow C ++ API库对此没有指导,即使是通过提供的多个链接中的任何一个,公认的答案也没有提供有关如何做到这一点的指导。
iantonuk

对于Windows,我发现此问题及其公认的答案最有帮助。通过构建示例训练器项目,您可以将整个TensorFlow项目构建为静态库,然后链接到它。您可以创建自己的项目并以相同方式链接TensorFlow。
omatai

Answers:


2

找到的使用Tensorflow C ++ API的一种替代方法是使用cppflow

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


55

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

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

C ++ API的第二部分是用于添加new的API,OpKernel该类包含用于CPU和GPU的数字内核的实现。有许多如何构建这些示例的示例tensorflow/core/kernels,以及有关在C ++中添加新op教程


7
否为C ++安装说明中示出tensorflow.org/install,但也有示出的示例程序tensorflow.org/api_guides/cc/guide清楚地被用C ++ API。您是如何为Tensorflow安装C ++的?
user3667089

@ user3667089安装过程的位置现在位于tensorflow.org/install/install_sources
Dwight

6
@Dwight我之前看过该页面,但没有看到有关C ++的任何信息
user3667089

2
@ user3667089在上述安装过程之后,标头将位于安装过程中选择的python发行版的dist-packages文件夹内(例如/usr/local/lib/python2.7/dist-packages)。在该文件夹中将有一个tensorflow / include文件夹,其中将包含所有标题。您需要做一点点的工作,以确保您所构建的所有内容都包含在其中。我个人使用CMake的,所以我通过跋涉
德怀特

4
到目前为止,这还不是真正的答案。它以“开始使用”开始,然后在一个已经在此处查找指南的人们未链接的地方链接任何相关信息。然后,它无法提供下一步操作,无法更改主题。
iantonuk

28

为了补充@mrry的帖子,我整理了一个教程,该教程说明了如何使用C ++ API加载TensorFlow图。它很小,应该可以帮助您了解所有部分如何组合在一起。这是它的实质:

要求:

  • 安装挡板
  • 克隆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",
    ]
)

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

  • 现在,需要 TensorFlow回购中进行构建。
  • 编译的二进制文件很大(103MB)。

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


1
你好吉姆。本教程仍然是用TF编译c ++项目的最佳/最简便方法吗?还是您在帖子末尾预测时,现在有没有更简单的方法?
桑德

3
我相信现在有一个内置的构建规则。我不久前提交了一份PR。我不确定这些警告。我希望第一个保留下来是因为Bazel而不是TF。第二个可能会得到改进。
吉姆(Jim)

我遵循了该教程,但是在运行时./loader出现错误:Not found: models/train.pb
9th Dimension

3
现在是否可以将项目置于TensorFlow源代码目录之外?
Seanny123 '17

是的,鉴于您已共享.so库的Tensorflow,如何使其退出?
Xyz

15

如果您既希望避免使用Bazel构建项目,又不想生成大型二进制文件,那么我已组装了一个存储库,用于指示CMake使用TensorFlow C ++库。你可以在这里找到它。总体思路如下:

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

15

首先,在安装protobuf和之后eigen,您想构建Tensorflow:

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

然后将以下包含头文件和动态共享库复制到/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/

最后,使用示例进行编译:

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

我相信没有必要安装protobuf和eigen。bazel工作空间配置包括用于下载和构建这些组件的规则。

最后,tensorflow.org / install / source上疯狂的OFFICIAL构建指南是用于构建pip模块,构建选项“ tensorflow:libtensorflow_cc.so”是tks,甚至在tensorflow.org上也没有记录
daddinhquoc

@lababidi在“ bazel build”命令之前应该有什么c ++依赖关系?我面临一个小时后构建失败的问题,很难一次又一次地测试构建
daddinhquoc

15

如果您想在独立软件包上使用Tensorflow c ++ api,则可能需要tensorflow_cc.so(也有ac api版本tensorflow.so)来构建可以使用的c ++版本:

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

注意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

并将库链接到您的项目:

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

并且在构建项目时,还应向编译器指定要使用c ++ 11标准。

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

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


1
我需要此附加包含路径以使用版本1.11构建:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S


8

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


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项目的开发人员。


5

我使用一种技巧/解决方法来避免自己构建整个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 ++中最需要的功能。


我无法使它正常工作。我收到大量关于未定义对python的引用的链接时间错误,例如:undefined reference to 'PyType_IsSubtype'
0xcaff

哦,谢谢指出。您还必须链接到python2.7库...我将相应地编辑帖子。
Martin Pecka

@MartinPecka我使用armv7l(Raspberry PI 2)在Raspbian Buster上尝试了此操作。最新的Python 2.7和3.7轮子适用于1.14.0,但我的目标是2.0.0。无论如何,谢谢,我赞成您的入侵。
荒木大辅(Daisuke Aramaki)

2

Tensorflow本身仅提供有关C ++ API的非常基本的示例。
这是一个很好的资源,其中包括数据集示例,rnn,lstm,cnn和更多的
tensorflow c ++示例


2

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

SOURCE是第一个参数,它是张量流源(构建)目录;
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

1
这是非常有用的代码段,创建目录时出现问题,所以我不得不在此mkdir -p $DST/tensorflow$target_dir之前添加它cp $line $DST/tensorflow/$target_dir
user969068

@hakunami 我从这个脚本中得出了要点。让我知道你的想法。如果您想制作自己的要点,我将删除我的并克隆您的。
荒木大辅(Daisuke Aramaki)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.