Google TensorFlow C ++ APIを構築して使用する方法


168

C ++でGoogleの新しいTensorflowライブラリを使い始めたいと思っています。Webサイトとドキュメントは、プロジェクトのC ++ APIを構築する方法の点で本当に不明確であり、どこから始めればよいかわかりません。

より経験のある人がtensorflowのC ++ APIを使用するためのガイドを見つけて共有することで手助けできますか?


4
質問に+1してください。Windowsにインストール/コンパイルする機会はありますか?ウェブサイトにはLinux / Macのみが表示されます。バゼルを走らせるためのガイドが必要です。この例では、学ぶための出発点は良いかもしれないgithub.com/tensorflow/tensorflow/tree/master/tensorflow/...
alrama

この質問にはまだ答えがありません。C ++ tensorflow C ++ APIライブラリだけをインストールする方法はありません。また、提供された複数のリンクのいずれを使用しても、受け入れられた回答はその方法についての指針にはなりません。
iantonuk 2017

Windowsの場合、この質問とその回答が最も役に立ちました。サンプルトレーナープロジェクトをビルドすることで、TensorFlowプロジェクト全体を静的ライブラリとしてビルドし、それにリンクします。独自のプロジェクトを作成し、同じ方法でTensorFlowをリンクできます。
omatai

回答:


2

私が見つけたTensorflow C ++ APIを使用する別の方法は、cppflowを使用することです

これは、Tensorflow C APIの軽量C ++ラッパーです。非常に小さな実行可能ファイルを取得し、libtensorflow.soすでにコンパイルされたファイルにリンクします。使用例もあり、Bazelの代わりにCMAKEを使用します。


55

開始するには、こちらの手順に従って、 Githubからソースコードをダウンロードする必要があります(Bazelと最新バージョンのGCC が必要です)。

C ++ API(およびシステムのバックエンド)はにありtensorflow/coreます。現在、C ++セッションインターフェイスC APIのみがサポートされています。これらのいずれかを使用して、Python APIを使用して構築され、GraphDefプロトコルバッファーにシリアル化されたTensorFlowグラフを実行できます。C ++でグラフを構築するための実験的な機能もありますが、これは現在、Python APIほど完全には機能していません(たとえば、現在のところ自動微分のサポートはありません)。C ++で小さなグラフ作成するサンプルプログラムは、こちらにあります

C ++ APIの2番目の部分は、新しいを追加するためのAPIですOpKernel。これは、CPUおよびGPUの数値カーネルの実装を含むクラスです。これらをでビルドする方法の例や、C ++で新しいopを追加するためtensorflow/core/kernelsチュートリアルがあります


7
C ++のインストール手順はtensorflow.org/installには示されていませんが、明らかにC ++ apiを使用しているtensorflow.org/api_guides/cc/guideに示されているサンプルプログラムがあります。Tensorflow用のC ++を正確にインストールしたか。
user3667089 2017年

@ user3667089インストール手順の場所はtensorflow.org/install/install_sources
Dwight

6
@Dwight以前にそのページを見ましたが、C ++に関する情報は何も表示されません
user3667089

2
@ user3667089上記のインストール手順の後のヘッダーは、インストール手順中に選択したpythonディストリビューションのdist-packagesフォルダー(/usr/local/lib/python2.7/dist-packagesなど)内にあります。そのフォルダーには、すべてのヘッダーを持つフォルダーtensorflow / includeがあります。あなたが構築しているものがそれがインクルードパス上に持っていることを確認するために少し作業をする必要があります。私は個人的にとても重そうに歩くを通じて午前、CMAKEを使用して、この
ドワイト

4
これまでのところ、これは本当の答えではありません。「はじめに」から始まり、ここでガイダンスを探している人々がすでに調べているであろう場所に関連情報をリンクしていません。次に、主題を変更する次のステップを提供できません。
iantonuk 2017

28

@mrryの投稿に追加するために、C ++ APIでTensorFlowグラフをロードする方法を説明するチュートリアルをまとめました。これは非常に最小限であり、すべての要素がどのように組み合わされるかを理解するのに役立ちます。ここにその肉があります:

要件:

  • インストールされたバゼル
  • 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つの警告:

  • 現在、TensorFlowリポジトリでビルドを行う必要があります。
  • コンパイルされたバイナリは巨大です(103MB)。

https://medium.com/@jimfleming/loading-a-tensorflow-graph-with-the-c-api-4caaff88463f


1
こんにちはジム。このチュートリアルはまだTFでc ++プロジェクトをコンパイルするための最良/最も簡単な方法ですか?または、投稿の最後に予測するより簡単な方法はありますか?
サンダー

3
今では組み込みのビルドルールがあると思います。しばらく前にPRをしました。警告についてはわかりません。それはTFではなくBazelの結果であるため、最初のものは残ると思います。2番目は改善される可能性があります。
ジム

そのチュートリアルに従いましたが、実行./loaderするとエラーが発生しますNot found: models/train.pb
9次元

3
TensorFlowソースコードディレクトリの外にプロジェクトを置く方法はありますか?
Seanny123 2017年

うん、あなたがテンソルフローの.soライブラリを共有しているのでそれを追い払う方法は?
Xyz

15

Bazelでのプロジェクトのビルドと大きなバイナリの生成の両方を回避したい場合は、CMakeでTensorFlow C ++ライブラリの使用方法を指示するリポジトリを作成しました。あなたはここでそれを見つけることができます。一般的なアイデアは次のとおりです。

  • TensorFlowリポジトリのクローンを作成します。
  • ビルドルールを追加しますtensorflow/BUILD(提供されているものにはすべてのC ++機能が含まれているわけではありません)。
  • TensorFlow共有ライブラリをビルドします。
  • EigenとProtobufの特定のバージョンをインストールするか、外部の依存関係として追加します。
  • TensorFlowライブラリを使用するようにCMakeプロジェクトを構成します。

15

まず、protobufおよびをインストールした後eigen、Tensorflowをビルドします。

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

次に、次のインクルードヘッダーと動的共有ライブラリを/usr/local/libandにコピーします/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モジュールのビルド用で、ビルドオプション「tensorflow:libtensorflow_cc.so」のtksです。これは、tensorflow.orgにも記載されていません
datdinhquoc

@lababidi 'bazel build'コマンドの前にc ++の依存関係はどうあるべきですか?1時間後にビルドが失敗するという問題に直面しています。これはビルドを何度もテストするのが難しい
datdinhquoc

15

スタンドアロンパッケージでTensorflow c ++ apiを使用することを考えている場合、使用できるc ++バージョンをビルドするには、おそらくtensorflow_cc.so(ac apiバージョンtensorflow.soもあります)が必要になります。

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

注1:組み込みサポートを追加する場合は、このフラグを次のように追加できます。 --copt=-msse4.2 --copt=-mavx

注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に関連するパス(バージョンで変更されているかどうかを確認する必要がある場合があります)。

また、このリンクは、このすべての情報を見つけるのに大いに役立ちました:リンク


1
私は、この追加は、バージョン1.11でビルドへのパスを含める必要:tensorflow/bazel-tensorflow/external/com_google_absl
Noah_S


8

CMakeを使用してもかまわない場合は、TF C ++ APIをビルドしてインストールするtensorflow_ccプロジェクトと、リンクできる便利なCMakeターゲットがあります。プロジェクトのREADMEには、サンプルと簡単にフォローできるDockerfileが含まれています。


8

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プロジェクトの開発者です。


5

私はハック/回避策を使用して、TFライブラリ全体を自分でビルドする必要がないようにしています(これにより、時間(3分で設定されます)、ディスク領域、インストールする開発依存関係、および結果のバイナリのサイズの両方が節約されます)。正式にはサポートされていませんが、すぐに利用したい場合は問題なく機能します。

TFをpip(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ます。次に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ライブラリにもリンクする必要があります...それに応じて投稿を編集します。
Martin Pecka 2017年

@MartinPecka私はこれをRaspbian Busterでarmv7l(Raspberry PI 2)で試しました。利用可能な最新のPython 2.7および3.7ホイールは1.14.0用ですが、私は2.0.0を対象としています。とにかくありがとう、私はあなたのハックに賛成しました。
荒巻大輔

2

Tensorflow自体は、C ++ APIに関する非常に基本的な例のみを提供します。
これは、データセットの例、rnn、lstm、cnn、およびその他のtensorflow c ++の例を含む優れたリソース
です


2

上記の回答は、ライブラリの構築方法を示すのに十分ですが、ヘッダーを収集する方法はまだトリッキーです。ここで、必要なヘッダーをコピーするために使用する小さなスクリプトを共有します。

SOURCE最初のパラメータです。これはテンソルフローのソース(ビルド)ディレクトリです。
DSTinclude directory収集されたヘッダーを保持する2番目のパラメーターです。(例: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

1
これは本当に便利スニペットたディレクトリを作成しているとき、私はこれを追加する必要がありましたので、問題があったが、mkdir -p $DST/tensorflow$target_dir前にcp $line $DST/tensorflow/$target_dir
user969068

@hakunami 私はこのスクリプトから要点を作りました。どう考えているか教えてください。あなたが自分の要点を作りたいなら、私は私のものを削除してあなたのものを複製します。
荒巻大輔
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.