如何构建和使用谷歌TensorFlow c++ api

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

是否有更有经验的人可以通过发现和分享使用tensorflow的c++ API的指南来帮助您?

158650 次浏览

首先,你应该通过按照这里的说明操作从Github下载源代码(你需要巴泽尔和最新版本的GCC)。

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

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

为了补充@mrry的帖子,我整理了一个教程,解释如何用c++ API加载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

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

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

如果你希望避免使用Bazel构建项目和生成大型二进制文件,我已经组装了一个库,指导使用CMake TensorFlow c++库。你可以找到它在这里。总体思路如下:

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

我使用了一种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。然后在构建系统能找到它的地方(例如/usr/lib/local)创建一个指向这个名为lib_pywrap_tensorflow.so的库的符号链接。前缀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,所以你可能会在奇怪的链接时间或运行时问题中运行。但是我能够加载存储的图形,恢复权重并运行推理,这是我在c++中最想要的功能。

首先,在安装了protobufeigen之后,你想要构建Tensorflow:

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

然后将以下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/

最后,使用一个示例编译:

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

如果你不介意使用CMake,还有tensorflow_cc项目为你构建和安装TF c++ API,以及方便的CMake目标,你可以链接到。项目README包含一个示例和Dockerfiles,您可以轻松地遵循。

如果你想在一个独立的包上使用Tensorflow c++ api,你可能需要tensorflow_cc。还有一个c api版本的tensorflow。所以)构建c++版本,你可以使用:

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

注1:如果您想添加intrinsic支持,可以将此标记添加为:--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的路径(您可能需要检查您的版本中是否有任何更改)。

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

如果你不想自己构建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项目的开发者。

Tensorflow本身只提供了关于c++ api的非常基本的示例 这是一个很好的资源,其中包括数据集的例子,rnn, lstm, cnn和更多
Tensorflow c++的例子 < / p >

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

SOURCE是第一个参数,它是tensorflow源(构建)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

我发现使用Tensorflow c++ API的另一个替代方法是使用cppflow

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

我们现在在https://github.com/ika-rwth-aachen/libtensorflow_cc提供了一个预构建的库和Docker镜像,方便安装和使用TensorFlow c++ API

  1. 我们提供了预构建的libtensorflow_cc。因此,将附带的头文件作为一个命令安装deb-package。
  2. 我们提供了一个基于官方TensorFlow Docker镜像的预构建Docker镜像。我们的Docker镜像同时安装了TensorFlow Python和TensorFlow c++。

通过运行示例应用程序自己尝试一下:

git clone https://github.com/ika-rwth-aachen/libtensorflow_cc.git && \
cd libtensorflow_cc && \
docker run --rm \
--volume $(pwd)/example:/example \
--workdir /example \
rwthika/tensorflow-cc:latest \
./build-and-run.sh

虽然我们目前只支持运行Ubuntu的x86_64机器,但将来可以很容易地扩展到其他操作系统和平台。除了一些例外,TensorFlow从2.0.0到2.9.2的所有版本都可用,2.10.0即将推出。

如果你想使用TensorFlow c++ API在c++中加载、检查和运行保存的模型和冻结的图形,我们建议你也检查我们的帮助库tensorflow_cpp