我真的很想开始在C ++中使用Google的新Tensorflow库。网站和文档在如何构建项目的C ++ API方面还不清楚,我不知道从哪里开始。
有更多经验的人可以通过发现和共享使用tensorflow的C ++ API的指南来提供帮助吗?
我真的很想开始在C ++中使用Google的新Tensorflow库。网站和文档在如何构建项目的C ++ API方面还不清楚,我不知道从哪里开始。
有更多经验的人可以通过发现和共享使用tensorflow的C ++ API的指南来提供帮助吗?
Answers:
找到的使用Tensorflow C ++ API的一种替代方法是使用cppflow。
它是围绕Tensorflow C API的轻量级C ++包装器。您将获得非常小的可执行文件,它链接到libtensorflow.so
已编译的文件。还有一些使用示例,您可以使用CMAKE代替Bazel。
首先,请按照此处的说明从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的教程。
为了补充@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",
]
)
有两个警告,可能有解决方法:
https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f
./loader
出现错误:Not found: models/train.pb
。
首先,在安装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
如果您想在独立软件包上使用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版的路径(您可能需要检查版本中是否有任何更改)。
此外,此链接还帮助我找到了所有这些信息:链接
tensorflow/bazel-tensorflow/external/com_google_absl
您可以使用此ShellScript来安装(大多数)依赖项,克隆,构建,编译并将所有必需的文件放入../src/includes
文件夹中:
https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh
如果您不介意使用CMake,也可以使用tensorflow_cc项目为您构建和安装TF C ++ API,以及可以链接的便捷CMake目标。项目README包含一个示例和您可以轻松遵循的Dockerfile。
如果您不想自己构建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项目的开发人员。
我使用一种技巧/解决方法来避免自己构建整个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 ++中最需要的功能。
undefined reference to 'PyType_IsSubtype'
python2.7
库...我将相应地编辑帖子。
Tensorflow本身仅提供有关C ++ API的非常基本的示例。
这是一个很好的资源,其中包括数据集示例,rnn,lstm,cnn和更多的
tensorflow c ++示例
上面的答案足以说明如何构建库,但是如何收集标头仍然很棘手。在这里,我分享了用于复制必要标头的小脚本。
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
mkdir -p $DST/tensorflow$target_dir
之前添加它cp $line $DST/tensorflow/$target_dir