私は本当にC++でGoogleの新しいTensorflowライブラリを使い始めたいと思っています。 Webサイトとドキュメントは、プロジェクトのC++ APIのビルド方法に関しては本当に不明瞭です。どこから始めればよいのかわかりません。
もっと経験のある人は、tensorflowのC++ APIを使うためのガイドを見つけて共有することで助けになりますか?
始めるには、Githubからソースコードをダウンロードする必要があります。 こちらの指示に従います ( Bazel とGCCの最新版).
C++ API(およびシステムのバックエンド)はtensorflow/core
にあります。現時点では、 C++ Sessionインタフェース と C API のみです。サポートされています。 Python APIを使用して構築されGraphDef
プロトコルバッファにシリアル化されたTensorFlowグラフを実行するためにこれらのどちらかを使用することができます。 C++でグラフを作成するための実験的な機能もありますが、これは現在のところPython APIほどフル機能ではありません(例えば、現在のところ自動微分のサポートはありません)。ここで C++で小さなグラフを作成するプログラム例を見ることができます 。
C++ APIの2番目の部分は、新しいOpKernel
を追加するためのAPIです。これは、CPUとGPU用の数値カーネルの実装を含むクラスです。 C++で新しい命令を追加するための チュートリアルだけでなく、tensorflow/core/kernels
でこれらを構築する方法の例が多数あります。 。
@ 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",
]
)
おそらく回避策がある2つの警告:
https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f
Bazelを使用してプロジェクトをビルドすることと大きなバイナリを生成することの両方を避けたい場合は、TensorFlow C++ライブラリとCMakeの使用方法を説明するリポジトリを作成しました。あなたはそれを見つけることができます ここで 。一般的な考え方は次のとおりです。
tensorflow/BUILD
に追加します(提供されているものには、C++機能のすべてが含まれているわけではありません)。まず、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を使用することを検討している場合は、使用できるc ++バージョンをビルドするためにtensorflow_cc.so(c apiバージョンのtensorflow.soもあります)が必要になるでしょう。
bazel build -c opt //tensorflow:libtensorflow_cc.so
注1:組み込みサポートを追加したい場合は、このフラグを次のように追加できます。--copt=-msse4.2 --copt=-mavx
Note 2:あなたのプロジェクトでOpenCVを使うことを考えているのであれば、両方のライブラリを一緒に使うとき( テンソルフローの問題 )に問題があります。 --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
このShellScriptを使用して、ほとんどの依存関係のインストール、クローン作成、ビルド、コンパイルを行い、必要なすべてのファイルを../src/includes
フォルダーに入れることができます。
https://github.com/node-tensorflow/node-tensorflow/blob/master/tools/install.sh
あなた自身で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プロジェクトの開発者です。
あなたがCMakeを使っても構わないのなら、TF C++ APIをビルドしてインストールする tensorflow_cc プロジェクトと、リンクできる便利なCMakeターゲットもあります。に対して。プロジェクトREADMEには、簡単に従うことができる例とDockerfilesが含まれています。
私はTFライブラリ全体を自分でビルドする必要がないようにするためにハック/回避策を使用します(これにより時間が短縮され(3分でセットアップされます)、ディスクスペース、dev依存関係のインストール、および生成されるバイナリのサイズ)。正式にはサポートされていませんが、すぐに飛びたい場合はうまくいきます。
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++で最も必要な機能です。
Tensorflow自体は、C++ APIに関する非常に基本的な例のみを提供しています。
これはデータセット、rnn、lstm、cnnなどの例を含む良いリソースです。
テンソルフローc ++の例
上記の答えはライブラリを構築する方法を示すのに十分良いですが、ヘッダを集める方法はまだややこしいです。ここで、必要なヘッダをコピーするために使用する小さなスクリプトを共有します。
SOURCE
は、テンソルフローソース(ビルド)ディレクトリである最初のパラメータです。DST
は2番目のパラメーターです。これは、収集されたヘッダーを保持する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