如何构建和使用 Google TensorFlow C++ api
Posted
技术标签:
【中文标题】如何构建和使用 Google TensorFlow C++ api【英文标题】:How to build and use Google TensorFlow C++ api 【发布时间】:2016-02-10 18:54:17 【问题描述】:我非常渴望开始在 C++ 中使用 Google 的新 Tensorflow 库。网站和文档在如何构建项目的 C++ API 方面真的不清楚,我不知道从哪里开始。
有更多经验的人可以通过发现和分享使用 tensorflow 的 C++ API 的指南来提供帮助吗?
【问题讨论】:
+1 回答您的问题。有机会在 Windows 上安装/编译吗?网站仅显示 Linux/Mac 。需要一个让 bazel 运行的指南。这个例子可能是一个很好的学习起点:github.com/tensorflow/tensorflow/tree/master/tensorflow/… 这个问题仍然没有答案。如何仅安装 C++ tensorflow C++ API 库没有任何指南,即使通过多个提供的链接中的任何一个,接受的答案也没有给出任何指导。 对于 Windows,我发现 this question 及其接受的答案最有帮助。通过构建示例培训项目,您将整个 TensorFlow 项目构建为一个静态库,然后链接到它。您可以制作自己的项目并以相同的方式链接 TensorFlow。 【参考方案1】:要开始使用,您应该从 Github 下载源代码,由 following the instructions here 提供(您需要 Bazel 和最新版本的 GCC)。
C++ API(和系统后端)位于tensorflow/core
。目前,仅支持C++ Session interface 和C API。您可以使用其中任何一个来执行使用 Python API 构建并序列化到 GraphDef
协议缓冲区的 TensorFlow 图。还有一个用于在 C++ 中构建图形的实验性功能,但目前还没有 Python API 功能齐全(例如,目前不支持自动微分)。你可以看到builds a small graph in C++ here的示例程序。
C++ API 的第二部分是用于添加新的OpKernel
的 API,它是包含用于 CPU 和 GPU 的数字内核实现的类。在tensorflow/core/kernels
和tutorial for adding a new op in C++ 中有很多如何构建这些的示例。
【讨论】:
tensorflow.org/install 没有显示 C++ 的安装说明,但有显示的示例程序 tensorflow.org/api_guides/cc/guide 显然使用了 C++ api。您究竟是如何为 Tensorflow 安装 C++ 的? @Dwight 我以前看过那个页面,但我没有看到任何关于 C++ 的信息 @user3667089 在上述安装过程之后,这些头文件将位于您在安装过程中选择的 python 发行版的 dist-packages 文件夹中(例如 /usr/local/lib/python2. 7/dist 包)。在该文件夹中将有一个文件夹 tensorflow/include,其中包含所有标题。你需要做一些工作来确保你正在构建的任何东西都包含在它的包含路径上。我个人使用 CMAKE,所以我在 this 中苦苦挣扎。 到目前为止,这不是一个真正的答案。它以“开始”开头,然后在人们在此处寻找指导的地方已经查找到任何相关信息。然后它无法提供下一步,改变主题。 @Dwight 你如何构建 .so 文件?【参考方案2】:为了补充 @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",
]
)
可能有解决方法的两个注意事项:
现在,需要在 TensorFlow 存储库内进行构建。 编译后的二进制文件很大 (103MB)。https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f
【讨论】:
你好,吉姆。本教程仍然是使用 TF 编译 c++ 项目的最佳/最简单方法吗?还是如您在帖子末尾预测的那样,现在有更简单的方法吗? 我相信现在有一个内置的构建规则。不久前我提交了一个 PR。我不确定这些警告。我希望第一个保留,因为它是 Bazel 的结果,而不是 TF。第二个可能会有所改进。 我按照该教程进行操作,但是在运行./loader
时出现错误:Not found: models/train.pb
。
现在有办法将您的项目放在 TensorFlow 源代码目录之外吗?
@Jim 目前是否有任何改进的方法可用于在 C/C++ 中进行推理?【参考方案3】:
如果您正在考虑在独立包上使用 Tensorflow c++ api,您可能需要 tensorflow_cc.so(还有一个 c api 版本 tensorflow.so)来构建您可以使用的 c++ 版本:
bazel build -c opt //tensorflow:libtensorflow_cc.so
注意1:如果您想添加内在函数支持,您可以将此标志添加为:--copt=-msse4.2 --copt=-mavx
注意 2:如果您也在考虑在您的项目中使用 OpenCV,那么同时使用两个库时会出现问题 (tensorflow issue),您应该使用 --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 版的路径(您可能需要检查您的版本中是否有任何更改)。
这个链接也帮助我找到了所有这些信息:link
【讨论】:
我需要这个额外的包含路径来构建 1.11 版:tensorflow/bazel-tensorflow/external/com_google_absl
【参考方案4】:
首先,在安装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 的疯狂官方构建指南用于构建 pip 模块,tks 用于构建选项“tensorflow:libtensorflow_cc.so”,它甚至没有记录在 tensorflow.org @lababidi 在“bazel build”命令之前应该有哪些 c++ 依赖项?我面临一个小时后构建失败的问题,这很难一次又一次地测试构建【参考方案5】:如果您希望避免使用 Bazel 构建项目和生成大型二进制文件,我已经组装了一个存储库,用于指导使用 TensorFlow C++ 库和 CMake。你可以找到它here。大致思路如下:
克隆 TensorFlow 存储库。 向tensorflow/BUILD
添加构建规则(提供的规则不包括所有C++ 功能)。
构建 TensorFlow 共享库。
安装特定版本的 Eigen 和 Protobuf,或将它们添加为外部依赖项。
配置您的 CMake 项目以使用 TensorFlow 库。
【讨论】:
【参考方案6】:我发现使用 Tensorflow C++ API 的一种替代方法是使用 cppflow。
它是Tensorflow C API 的轻量级 C++ 包装器。你会得到非常小的可执行文件,它链接到libtensorflow.so
已经编译的文件。还有一些使用示例,您使用 CMAKE 而不是 Bazel。
【讨论】:
此替代方案不包括 TensorFlow C++ API 的所有功能。例如,使用 C API 无法将 TensorFlow 生成的线程数减少到 1。您可以使用***.com/questions/60206113/… 和***.com/questions/45063535/… 和 找到有关该问题的更多详细信息【参考方案7】:如果您不介意使用 CMake,还有 tensorflow_cc 项目可为您构建和安装 TF C++ API,以及您可以链接的便捷 CMake 目标。项目 README 包含一个示例和 Dockerfile,您可以轻松遵循。
【讨论】:
它在 ubuntu 上成功运行,但在 CentOS 中存在一些问题。问题在于在构建期间使用 curl/wget 下载 tensorflow zip 文件。【参考方案8】:您可以使用此 ShellScript 安装(大部分)它的依赖项、克隆、构建、编译并将所有必要的文件放入 ../src/includes
文件夹:
https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh
【讨论】:
【参考方案9】:如果您不想自己构建 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 项目的开发者。
【讨论】:
【参考方案10】:我使用 hack/workaround 来避免自己构建整个 TF 库(这样可以节省时间(在 3 分钟内完成设置)、磁盘空间、安装开发依赖项以及生成的二进制文件的大小)。官方不支持它,但如果你只是想快速加入,它会很好用。
通过 pip(pip install tensorflow
或 pip 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'
哦,感谢您指出...您还必须链接到 python2.7
库...我会相应地编辑帖子。
@MartinPecka 我在 Raspbian Buster 上使用 armv7l(Raspberry PI 2)进行了尝试。最新的 Python 2.7 和 3.7 ***适用于 1.14.0,但我的目标是 2.0.0。无论如何,谢谢,我赞成你的黑客。【参考方案11】:
上面的答案足以说明如何构建库,但如何收集标题仍然很棘手。在这里,我分享我用来复制必要标题的小脚本。
SOURCE
是第一个参数,即 tensorflow 源(构建)目录;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
【讨论】:
这对sn-p很有帮助,创建目录时出现问题,所以我不得不在cp $line $DST/tensorflow/$target_dir
之前添加这个mkdir -p $DST/tensorflow$target_dir
@hakunami I made a gist out of this script。让我知道你的想法。如果你想制作自己的要点,我会删除我的并克隆你的。
我在多次从源代码构建 tensorflow 后退出了。每次问题都是缺少头文件。他们github.com/FloopCZ/tensorflow_cc 解决了我的问题。【参考方案12】:
Tensorflow 本身仅提供有关 C++ API 的非常基本的示例。 这是一个很好的资源,其中包括数据集、rnn、lstm、cnn 等示例tensorflow c++ examples
【讨论】:
以上是关于如何构建和使用 Google TensorFlow C++ api的主要内容,如果未能解决你的问题,请参考以下文章
利用 AutoML 的功能构建和部署 TensorFlow.js 模型
Think with Google 京东如何玩转TensorFlow?
使用 ScaNN 进行高效检索以进行检索 7使用 TensorFlow 构建推荐系统 Efficient serving with ScaNN for retrieval