如何构建和使用 Google TensorFlow C++ api
How to build and use Google TensorFlow C++ api
我真的很想开始使用 Google 的 C++ 新 Tensorflow 库。就如何构建项目的 C++ API 而言,网站和文档真的不清楚,我不知道从哪里开始。
经验丰富的人能否通过发现和分享使用 tensorflow 的 C++ 的指南来提供帮助 API?
要开始,您应该从 Github、following the instructions here (you'll need Bazel 和最新版本的 GCC 下载源代码。
C++ API(和系统后端)在 tensorflow/core
中。现在,只有 C++ Session interface, and the C API are being supported. 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. There is also an experimental feature for building graphs in C++, but this is currently not quite as full-featured as the Python API (e.g. no support for auto-differentiation at present). You can see an example program that builds a small graph in C++ here.
C++ 的第二部分 API 是 API 用于添加新的 OpKernel
,它是 class 包含 [=27] 的数值内核的实现=] 和 GPU。在 tensorflow/core/kernels
以及 tutorial for adding a new op in C++.
中有许多关于如何构建这些的示例
为了添加到@mrry 的 post,我整理了一个教程,解释了如何使用 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
您可以使用此 Shell 脚本安装(大部分)它的依赖项,克隆、构建、编译并将所有必需的文件放入 ../src/includes
文件夹:
https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh
如果您希望避免使用 Bazel 构建项目和生成大型二进制文件,我已经组装了一个存储库,指导如何将 TensorFlow C++ 库与 CMake 结合使用。你可以找到它here。大致思路如下:
- 克隆 TensorFlow 存储库。
- 向
tensorflow/BUILD
添加构建规则(提供的规则不包括所有 C++ 功能)。
- 构建 TensorFlow 共享库。
- 安装特定版本的 Eigen 和 Protobuf,或将它们添加为外部依赖项。
- 配置您的 CMake 项目以使用 TensorFlow 库。
我使用 hack/workaround 来避免必须自己构建整个 TF 库(这节省了时间(设置在 3 分钟内)、磁盘 space、安装开发依赖项和大小生成的二进制文件)。官方不支持它,但如果您只是想快速入门,它会很好用。
通过 pip 安装 TF(pip install tensorflow
或 pip install tensorflow-gpu
)。然后找到它的库 _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
的库创建一个 symlink。前缀 lib
很重要!您还可以给它另一个 lib*.so
名称 - 如果您将它命名为 libtensorflow.so
,您可能会更好地与其他为 TF 编写的程序兼容。
然后按照您习惯的方式创建一个 C++ 项目(CMake、Make、Bazel,随您喜欢)。
然后您就可以 link 反对这个库,让 TF 可用于您的项目(您还必须 link 反对 python2.7
图书馆)!在 CMake 中,你例如只需添加 target_link_libraries(target _pywrap_tensorflow python2.7)
.
C++ 头文件位于该库周围,例如在 /usr/local/lib/python2.7/dist-packages/tensorflow/include/
.
再次声明:官方不支持这种方式,您可能会运行遇到各种问题。该库似乎是针对例如 link 静态编辑的。 protobuf,因此您可能 运行 出现奇数 link 次或 运行 次问题。但是我能够加载存储的图,恢复权重和 运行 推理,这是 IMO C++ 中最需要的功能。
首先,在安装 protobuf
和 eigen
之后,您想要构建 Tensorflow:
./configure
bazel build //tensorflow:libtensorflow_cc.so
然后复制下面的include headers和动态共享库到/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 目标,您可以 link .项目自述文件包含一个示例和您可以轻松遵循的 Dockerfile。
如果您正在考虑在独立包上使用 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
并且 link 库到您的项目:
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 帮助我找到了所有这些信息:link
如果您不想自己构建 Tensorflow 并且您的操作系统是 Debian 或 Ubuntu,您可以下载带有 Tensorflow C/C++ 库的预构建包。此分布可用于 C/C++ 推理 CPU,不包括 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++ examples
上面的答案足以说明如何构建库,但是如何收集 headers 仍然很棘手。在这里我分享我用来复制必要的小脚本headers。
SOURCE
是第一个参数,也就是tensorflow source(build) direcoty;
DST
是第二个参数,即 include directory
保存收集的 headers。 (例如,在 cmake 中,include_directories(./collected_headers_here)
)。
#!/bin/bash
SOURCE=
DST=
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。
我真的很想开始使用 Google 的 C++ 新 Tensorflow 库。就如何构建项目的 C++ API 而言,网站和文档真的不清楚,我不知道从哪里开始。
经验丰富的人能否通过发现和分享使用 tensorflow 的 C++ 的指南来提供帮助 API?
要开始,您应该从 Github、following the instructions here (you'll need Bazel 和最新版本的 GCC 下载源代码。
C++ API(和系统后端)在 tensorflow/core
中。现在,只有 C++ Session interface, and the C API are being supported. 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. There is also an experimental feature for building graphs in C++, but this is currently not quite as full-featured as the Python API (e.g. no support for auto-differentiation at present). You can see an example program that builds a small graph in C++ here.
C++ 的第二部分 API 是 API 用于添加新的 OpKernel
,它是 class 包含 [=27] 的数值内核的实现=] 和 GPU。在 tensorflow/core/kernels
以及 tutorial for adding a new op in C++.
为了添加到@mrry 的 post,我整理了一个教程,解释了如何使用 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
您可以使用此 Shell 脚本安装(大部分)它的依赖项,克隆、构建、编译并将所有必需的文件放入 ../src/includes
文件夹:
https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh
如果您希望避免使用 Bazel 构建项目和生成大型二进制文件,我已经组装了一个存储库,指导如何将 TensorFlow C++ 库与 CMake 结合使用。你可以找到它here。大致思路如下:
- 克隆 TensorFlow 存储库。
- 向
tensorflow/BUILD
添加构建规则(提供的规则不包括所有 C++ 功能)。 - 构建 TensorFlow 共享库。
- 安装特定版本的 Eigen 和 Protobuf,或将它们添加为外部依赖项。
- 配置您的 CMake 项目以使用 TensorFlow 库。
我使用 hack/workaround 来避免必须自己构建整个 TF 库(这节省了时间(设置在 3 分钟内)、磁盘 space、安装开发依赖项和大小生成的二进制文件)。官方不支持它,但如果您只是想快速入门,它会很好用。
通过 pip 安装 TF(pip install tensorflow
或 pip install tensorflow-gpu
)。然后找到它的库 _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
的库创建一个 symlink。前缀 lib
很重要!您还可以给它另一个 lib*.so
名称 - 如果您将它命名为 libtensorflow.so
,您可能会更好地与其他为 TF 编写的程序兼容。
然后按照您习惯的方式创建一个 C++ 项目(CMake、Make、Bazel,随您喜欢)。
然后您就可以 link 反对这个库,让 TF 可用于您的项目(您还必须 link 反对 python2.7
图书馆)!在 CMake 中,你例如只需添加 target_link_libraries(target _pywrap_tensorflow python2.7)
.
C++ 头文件位于该库周围,例如在 /usr/local/lib/python2.7/dist-packages/tensorflow/include/
.
再次声明:官方不支持这种方式,您可能会运行遇到各种问题。该库似乎是针对例如 link 静态编辑的。 protobuf,因此您可能 运行 出现奇数 link 次或 运行 次问题。但是我能够加载存储的图,恢复权重和 运行 推理,这是 IMO C++ 中最需要的功能。
首先,在安装 protobuf
和 eigen
之后,您想要构建 Tensorflow:
./configure
bazel build //tensorflow:libtensorflow_cc.so
然后复制下面的include headers和动态共享库到/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 目标,您可以 link .项目自述文件包含一个示例和您可以轻松遵循的 Dockerfile。
如果您正在考虑在独立包上使用 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
并且 link 库到您的项目:
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 帮助我找到了所有这些信息:link
如果您不想自己构建 Tensorflow 并且您的操作系统是 Debian 或 Ubuntu,您可以下载带有 Tensorflow C/C++ 库的预构建包。此分布可用于 C/C++ 推理 CPU,不包括 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++ examples
上面的答案足以说明如何构建库,但是如何收集 headers 仍然很棘手。在这里我分享我用来复制必要的小脚本headers。
SOURCE
是第一个参数,也就是tensorflow source(build) direcoty;
DST
是第二个参数,即 include directory
保存收集的 headers。 (例如,在 cmake 中,include_directories(./collected_headers_here)
)。
#!/bin/bash
SOURCE=
DST=
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。