Tensorflow: Javaインターフェース

作成日 2015年11月09日  ·  112コメント  ·  ソース: tensorflow/tensorflow

Java用のswigインターフェースの努力を追跡するための問題。 実装を開始しました-進行状況とともに更新されます。 誰かコメント/ヒントがあれば-ディスカッションに参加することを歓迎します!

最も参考になるコメント

アップデート:私は成功しjavacppで(@saudetのおかげで)行く事を取得し、Javaプログラムが読み持っている/ TensorFlowモデルを実行することができました。

https://medium.com/google-cloud/how-to-invoke-a-trained-tensorflow-model-from-java-programs-27ed5f4f502d#.tx8nyds5v

全てのコメント112件

良い!

このコメントをhttps://github.com/tensorflow/tensorflow/issues/3からここに移動し


かなり良い収束を備えたテストスイートがありますが、現在はほとんどがPythonであり、いくつかのC ++テストがあります。 現在Pythonのみであるグラフを作成するための多くの機能、特に自動微分機能もありますが、Javaでのグラフの評価には関係ありません。 将来的には、この機能を基盤となるC ++に移行する計画があります。その時点で、JavaSWIGバインディングはグラフの作成にさらに役立ちます。

誰かがJavaSWIGチャレンジに挑戦した場合、レビューなどが保留されているアップストリームでそれを受け入れて喜んでいます。その時点で、それは継続的テストの一部になります。 寄付の受け入れの詳細は現在流動的ですが、それは安定するでしょう。

こんにちはみんな
また、TensorFlowをJavaに適合させることにも関心があります。 @ravwojdyla万が一、Java用の

こんにちは、
私はメインのC ++ APIのSWIGラップに取り組んでいます。 これまでの私の進歩は私のフォークで見ることができますが、そこにあるものはまだ終わっていません。 現在、 #include "tensorflow/core/lib/core/error_codes.pb.h"解決できず、プロジェクトファイル内のどこにも目的のファイルが見つからないという問題が発生しています。 どんな種類の入力でも大歓迎です。

CaffeやOpenCVなどのライブラリで利用できるjavacppプリセットがあります。 https://github.com/bytedeco/javacpp-presets/issues/111も参照して

/ cc @saudet

@ pslam-私はこれに少しだけ取り組むことができました-間違いなくいくつかの助けを使うことができました!

こんにちは皆さん、私はJavaCPPのかなり機能的なバインディングを持っていると思います: https

とてもうまくやった@saudet! SWIGラップはほぼ終了しましたが、実装も同様に機能しているようです。 私のSWIGラップでできること、あなたができないことは何も見当たりません。 JavaCPPは非常にクールなようです。今後のプロジェクトで、JavaCPPを使用することを検討する必要があります。

こんにちは@kyleveddererror_codes.pb.h関連する問題を解決しましたか?
[編集]
すべての.pb.hファイルは.protoからコンパイルされます

@tnganはい、それも私が発見したことです。 さらに、このプロジェクトの.protoファイルでは、ProtoBuff3を使用する必要があります。 Ubuntu 14.04を使用していますが、パッケージマネージャーでProtoBuff3を使用できなかったため、 3.0.0ベータリリースから入手したソースからコンパイルし

私が解決しようとしている現在の障害は、ProtoBuffにファイルツリー全体を再帰させ、 .protoファイルを.h .ccファイルと.protoファイルへの依存関係が満たされないため、失敗します。

@kylevedder SWIGラッパーは別のリポジトリにありますか、それともtensorflowリポジトリで作業していますか? protocは、他のコンパイラと同様に機能します。 tensorflowリポジトリで作業している場合、またはBazelを使用している場合は、protobufビルドターゲットとそれらの間の依存関係を設定する必要があります。

別のリポジトリで作業していて、別のビルドシステムを使用している場合は、そのビルドシステムにprotobufプラグインを使用する必要があります。

必要に応じて、ビルドのセットアップをお手伝いさせていただきます。

@davidzchen申し出をありがとう、ありとあらゆる助けは大いに感謝されます。

私がこれまでに持っているもの:

私はすでにBazelをセットアップし、それを.whlファイルにコンパイルするように取得しました。次に、それをpip渡して、 FirstTensorFlowプログラムを実行できることを確認しました。

フォークされたリポジトリにSWIGラッパーファイルを生成しました。 それらはcore/javaWrapper下のフォルダにあります。 [[リンク](https://github.com/kylevedder/tensorflow/tree/master/tensorflow/core/javaWrapper)]

私がやろうとしていること:

最終的に、私の目標は、Javaでネイティブライブラリとして呼び出すことができる.soファイルを生成することです。 現在、g ++を使用してシステム全体を.soファイルにコンパイルしようとしています。 ただし、このコンパイルの前に、 .protoファイルを最初に.h.ccに展開する必要があります。これが、 protoc実行しようとしていることです。

あなたはラップスクリプトで私の試みを見ることができ、ここで、これまでのすべての使用での私の試みのが、それは私が取得していますされているものの良いアイデアを得る潜在的にprotoc 、ディレクトリによってディレクトリと、その結果として、いないされていますスクリプト内。

最後に、改善の領域に関するフィードバックをいただければ幸いです。 ありがとう!

@kylevedder JavaCPPプリセットの一部としてすでに.soビルドがあります//github.com/bytedeco/javacpp-presets/tree/master/tensorflow。 Bazelのおかげで、それは本当に簡単です。 次のようなパッチを適用するだけです。

diff -ruN tensorflow/tensorflow/cc/BUILD tensorflow-patch/tensorflow/cc/BUILD
--- tensorflow/tensorflow/cc/BUILD  2015-11-22 00:00:02.441829192 +0900
+++ tensorflow-patch/tensorflow/cc/BUILD    2015-11-14 11:15:12.689330351 +0900
@@ -75,6 +75,17 @@
     ],
 )

+cc_binary(
+    name = "libtensorflow.so",
+    copts = tf_copts(),
+    linkshared = 1,
+    deps = [
+        ":cc_ops",
+        "//tensorflow/core:kernels",
+        "//tensorflow/core:tensorflow",
+    ],
+)
+
 filegroup(
     name = "all_files",
     srcs = glob(

そして、次のようにBazelを実行します。

bazel build -c opt //tensorflow/cc:libtensorflow.so

AFAIK、これはC ++ APIにとって関心のあるほとんどすべてのものをむさぼり食うはずです。

@saudet cc_libraryではなくcc_binaryルールを使用して共有ライブラリを構築している理由はありますか? tensorflowという名前のcc_libraryルールを設定すると、ビルドターゲットはlibtensorflow.soという共有ライブラリをビルドします。

@kylevedder目標が.soファイルを生成することである場合、 @ saudetが提案したものと同様の何かが機能します。

JavaコードでTensorFlowプロトを使用する必要がある場合は、 java_* Bazelビルドターゲットから.protoからJavaクラスを生成するproto_libraryターゲットに依存関係を追加する必要があります。 .protoファイル。

ネイティブのproto_libraryルールをオープンソース化する前にやるべきことがまだ少しありますが(bazelbuild / bazel#52を参照)、その間、TensorFlowはcc_proto_librarypy_proto_library protobufによって提供される、およびJavaの場合、 含まれているproto_libraryのタイムラインを確認し、Protobufが提供するルールをgenprotoと統合する価値があるかどうかを確認します。

他のいくつかのフィードバック:

  • ディレクトリ名の一貫性を保ち、 javaWrapperではなくjava_wrapperを使用する方がよいと思います。
  • おそらく、Javaラッパーのためのより良い場所は次のようになります//tensorflow/java/wrapperではなく//tensorflow/core/java_wrapper
  • 内部的には、 .swigファイルを取得してソースを生成するビルドルールがいくつかあります。 生成されたファイルのチェックインを回避するため、これはより理想的です。 このようなことを簡単にするために、BazelにSWIGビルドルールを追加するのがどれほど難しいかを見てみましょう。

@davidzchen特に理由はありません。 私はBazelを初めて使用し、メーリングリストに記載されているようにlinkshared=1を使用するだけでうまくいきました。 だから、ヒントをありがとう! 更新します。

@saudetありがとう! Bazelの問題ではないことを確認するためにチェックしていました。 :)問題が発生した場合は、遠慮なくお知らせいただくか、バグを開いてください。

@saudetBazelの使用に関する情報をありがとう。 私もそれに慣れておらず、その方法で.soを生成できることに気づいていません

@davidzchen cc_library使用に関する補遺をありがとう、Bazilラッパービルドを実装したときに@saudetの例を変更しました。 また、ディレクトリ構造に関するご意見をお寄せいただきありがとうございます。 私はあなたの提案に合うように私のフォルダ構造を更新しました。

さらに、 .soファイルの生成に関する以前のコメントではあまり明確ではありません.soファイルを生成することですが、JNIを容易にするために.so内に含めたいと思います。呼び出します。 現在、SWIGで生成された.cxxファイルをコンパイルできないという問題が発生しています。 参照するようにしようとしているJNI.hに位置ヘッダ$JAVA_HOME/include/ 、私はBazelは、外部パスを含める理解してもらうように見えることはできません。

@davidzchenうーんcc_libraryは機能しません。 Bazelに-sharedオプションをコンパイラに渡す方法は他にありません: http

@saudet自分で-sharedを渡す必要はないと思います。 cc_libraryは、デフォルトで.so構築する必要があります。 それはあなたのために働きますか?

@kylevedder JNIヘッダーはワークスペースの外にあるため、その方法で追加することはできません。 ただし、BazelにはローカルリポジトリとしてローカルJDKが含まれており、ローカルJDKに依存するために使用できる多数の組み込みターゲット( jdk.WORKSPACEおよび対応するjdk.BUILD )を提供します。 これらは、デフォルトで各Bazelワークスペースに含まれています。

Bazel自体はJNIを使​​用し、この方法でローカルJDKとインターフェイスします( src/main/native/BUILD )。 このBUILDファイルには、JNIヘッダーをコピーするための2つのgenruleと、ヘッダーに依存するJNIを使​​用して構築しているライブラリのcc_libraryターゲットとincludes = ["."]使用して、C ++コードに#include <jni.h>を含むJNIヘッダーを含めることができます。 外部リポジトリメカニズムの多くの改善に取り組んでおり、 @local-jdk名前が変更される可能性があるため、これは現在文書化されていませんが、TensorFlowやその他のJNIを使​​用するBazelプロジェクトに使用できます。 。

ここで追加あなたのビルドファイル用のパッチですgenruleあなたが必要とするJNIヘッダとにいくつかの変更コピーするための目標cc_libraryつまり、右の依存関係を設定するには、ターゲットは:

  1. jni.hjni_md.hを追加します。これらは、 genruleによって現在のパッケージにsrcsコピーされます。
  2. //tensorflow/core依存関係を追加して、 tensorflow/core/public下にヘッダーを含めることができるようにします。 別のディレクトリにあるヘッダーまたはソースファイルは、Bazelの観点からは別のパッケージに含まれているため、これらのファイルを含むビルドターゲットへの依存関係を追加する必要があることに注意してください。
diff --git a/tensorflow/core/java/wrapper/BUILD b/tensorflow/core/java/wrapper/BUILD
index 72b4076..04a3394 100644
--- a/tensorflow/core/java/wrapper/BUILD
+++ b/tensorflow/core/java/wrapper/BUILD
@@ -7,10 +7,30 @@ exports_files(["LICENSE"])
 load("/tensorflow/tensorflow", "tf_copts")
 load("/tensorflow/tensorflow", "tf_gen_op_wrappers_cc")

+genrule(
+    name = "copy_link_jni_md_header",
+    srcs = ["//external:jni_md_header-linux"],
+    outs = ["jni_md.h"],
+    cmd = "cp -f $< $@",
+)
+
+genrule(
+    name = "copy_link_jni_header",
+    srcs = ["//external:jni_header"],
+    outs = ["jni.h"],
+    cmd = "cp -f $< $@",
+)
+
 cc_library(
     name = "java_wrapper",
-    srcs = glob(["*.cc","*.cxx","*.h"]),
-    copts = ["-I$$JAVA_HOME/include/", "-I$$JAVA_HOME/include/linux/"],
+    srcs = glob(["*.cc", "*.cxx", "*.h"]) + [
+        ":jni.h",
+        ":jni_md.h",
+    ],
+    includes = ["."],
+    deps = [
+        "//tensorflow/core",
+    ],
     visibility = ["//visibility:public"],
 )

一般に、Bazelのコンパイルアクションはソースツリーのルートから実行されるため、SWIGファイルのインクルードを次のように変更してから、C ++ファイルを再生成して正しいインクルードを取得する必要があることに注意してください。良い:

diff --git a/tensorflow/core/java/wrapper/tensor_c_api.i b/tensorflow/core/java/wrapper/tensor_c_api.i
index d08b571..9ab1fa1 100644
--- a/tensorflow/core/java/wrapper/tensor_c_api.i
+++ b/tensorflow/core/java/wrapper/tensor_c_api.i
@@ -1,8 +1,8 @@
 %module tensor_c_api_module
 %{
-#include "../../public/tensor_c_api.h"
+#include "tensorflow/core/public/tensor_c_api.h"
 %}
-%include "../../public/tensor_c_api.h"
+%include "tensorflow/core/public/tensor_c_api.h"
 %include "stddef.h"

これが機能すると、 copy_link_jni_md_header genruleはLinux固有のヘッダーのみをコピーするため、Linux用にJNIビルドをセットアップできます。 正しいプラットフォーム固有のJNIヘッダーをコピーするには、次の手順を実行する必要があります。

  1. 他のプラットフォーム用にcpu config_setting設定します。 現在、tensorflowにはconfig_setting--cpu=darwinに対してtensorflow/python/BUILDます。 //tensorflow/coreなどのより適切なパッケージを移動する必要があります。 基本的に、Bazelと同じconfig_settingのセットが必要です( src/BUILD )。
  2. Bazelの場合と同様にselect()を使用して設定された構成設定に基づいて、適切なJNIヘッダーをcopy_link_jni_md_headerコピーします。 genruleは次のようになります。
genrule(
    name = "copy_link_jni_md_header",
    srcs = select({
        "//tensorflow/core:darwin": ["//external:jni_md_header-darwin"],
        "//tensorflow/core:darwin_x86_64": ["//external:jni_md_header-darwin"],
        "//tensorflow/core:freebsd": ["//external:jni_md_header-freebsd"],
        "//conditions:default": ["//external:jni_md_header-linux"],
    }),
    outs = ["jni_md.h"],
    cmd = "cp -f $< $@",
)

問題が発生した場合は、喜んでお手伝いさせていただきます。 これがあなたのために働くかどうか私に知らせてください。

@davidzchen cc_libraryは、多数の.aファイルを生成しますが、.soファイルは生成しません。 以前TensorFlowで推奨されていた0.1.0を使用しています...たぶん0.1.1で修正されていますか? もう一度やり直さなければなりません。

@davidzchenBUILDファイルSWIG .iファイルの両方をあなたが提案したように更新しました。 さらに、ラップスクリプトをcore/java/wrapperからルートディレクトリに移動し、それに応じてリンクを更新しました。

今のところ、 jni_md.hファイルのgenruleの一般化をスキップし、代わりにlibtensorflow.soビルドすることに焦点を当てています。 残念ながら、 libtensorflow.soが生成されていないように見えます。 最終的にファイルシステム全体で「libtensorflow」のバリアントという名前のファイルを検索しましたが、関連するものは何も表示されませんでした。 名前が異なる場合もあれば、ユーザーエラーの単純なケースの場合もあります。 さらに、 @ saudet.so生成のcc_libraryルールで発生している問題に関連している可能性があります。

改めて、ご協力ありがとうございました。本当に感謝しています。

申し訳ありませんが、私は間違っていたことがわかりました。 構築するために.so @saudetを使用しなかったものを推移依存関係、含まれているcc_binaryしてlinkshared = 1name = "libtensorflow.so"正しかったです。 cc_binary.linksharedドキュメントから

共有ライブラリを作成します。 この属性を有効にするには、ルールにlinkshared = 1を含めます。 デフォルトでは、このオプションはオフになっています。 これを有効にする場合は、バイナリlibfoo.so(またはターゲットプラットフォーム上のライブラリの命名規則)に、適切なfooの値を指定する必要があります。

主な違い.soによって構築のcc_library標的と.soで構築されたcc_binary方法を用いては、上述したということであるcc_libraryアーティファクトには、 srcsのコードのみが含まれます。 建物の理由はここにあるcc_libraryがないとターゲットsrcsとだけdeps 、のような//tensorflow/core 、すべての成果物を生成しません。 一方、 cc_binaryターゲットは、すべての推移的な依存関係にリンクします。

ご迷惑をおかけしましたことをお詫び申し上げます。 おそらく、ドキュメントを改善し、 .soの構築に関する例を追加する必要があります。

Tensorflowとそのすべての依存関係を構築するには、これらの手順に従う必要があると思います。 TensorFlowをnode.jsに移植する作業を行っており、リポジトリ全体から重要なソースのみをコンパイルして取得するためのシェルスクリプトを実装しました。
https://github.com/node-tensorflow/node-tensorflow/blob/1.0.0/tools/install.sh#L233 -L282

@davidzchen .soの作成に関する情報をありがとうございます。 それに応じてセットアップを更新し、_extremely_ベーシックテスターを使用してtensorflow/core/java/wrapper/exampleを作成し、JNI関数が.so動作を呼び出すことを証明しました。 compileAndRun.shを実行する前に、 createWrapper.sh実行する必要があることに注意してください。

SWIGラッパーを改善し、より良い例を作成しようと思います。現在持っているのは、バインディングが機能していることの最低限の証拠にすぎません。

最後に、 @ davidzchen@saudetのすべての支援に感謝します。 私はそれらなしではこれを行うことができなかっただろう。

良い! これに取り組んでくれてありがとう、@ kylevedder!

興味があれば、1)Skylark SWIGルールを作成し、2) BazelのJavaルールを使用してJavaコードをビルドすることにより、 createWrapper.shおよびcompileAndRun.shスクリプトをBazelビルドに統合してみることができます。

@davidzchenそれは素晴らしいことです! SWIGラッパーと基本例の改善に取り組みます。

JavaCPPのプリセットを完成させ、 example_trainer.ccサンプルを移植しました。
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow
SWIGを使用してこれを同等のラッパーと比較することを楽しみにしています!

APIリンクが壊れているようです: http

@verdiyanto申し訳ありませんが、私はまだCIを持っていませんが、APIドキュメントのアップロードは十分に簡単なので、少なくともそれは実行しました。 楽しみ!

@saudet JavaCPPプリセットでうまくいきました!

私の作業の更新:SWIGラッパーでさらにいくつかの作業を行いまします。 しかし、私は少し交差点にいて、進むための最良の方法がわかりません。

SWIGを使用する最初の主要なプロジェクトであることを考えると、私はSWIGにかなり慣れていないので、SWIGの動作とC / C ++をSWIGJavaラッパーでラップする方法を実行するSWIGの基本SWIGおよびJavaに関する

ドキュメントでは、SWIGがC / C ++のポインタを不透明なJavaオブジェクトに変換する方法について説明しています。そのため、SWIGによって生成されたSWIGTYPE_p_voidようなクラスを取得します。 問題は、POJOをこれらのSWIGクラスに変換する簡単な方法がないことです。

したがって、たとえば、 tensor_c_api.hでは、CメソッドTF_CreateTensor()は、入力データを指すvoid*と、のサイズを指定するためのsizeパラメーターを取ります。バイト単位の入力データ。 これはC / C ++の完全に合理的なデザインパターンですが、Javaではまったく無意味です。 SWIGは、Javaメソッド生成TF_CreateTensor()かかりSWIGTYPE_p_voidとともに、そのデータとしてオブジェクトをsize 、しかしようなPOJOを変換する方法はありませんString多くのコードを手書きせずにSWIGTYPE_p_void String変換します。

そして、これは私が現在嘘をついている岐路です。私は、 TF_DataType定義された任意の型を取り、 void*に変換する、大量のC / C ++変換メソッドを作成するか、または同じことを行うためのSWIGタイプマップ。 SWIGのドキュメントは、どちらも一見互換性があるように見えるため、どちらのソリューションも支持していないようです。

それで、問題は、C / C ++変換関数またはSWIGタイプマップですか?

@kylevedderそもそもなぜJavaCPPを作成したのか理解し始めているようです。 :)

@saudetのJavaCPPプリセットを使用してきましたが、非常に便利です。ありがとうございます。 私はそれを使用して、tensorflowへのClojureインターフェースを構築しています。

いくつかのコメント:

a)簡素化/上位層の機会があります

多くのJavaCPPAPIは、ブリッジなしでJVM上で直接実現できるprotobuf機能を複製します。 これを理解するのに少し時間がかかりましたが、JavaCPPバインディングを使用してprotobufオブジェクトを構築し、相互運用機能を使用してこのプラットフォームに依存しない表現を生成し、それをセッションに詰め込むだけです。

JavaCPPコンストラクター関数をバイパスして、jvmベースのprotobufsを使用してグラフを直接作成することになりました。 これにはいくつかの利点があります。プログラミングが簡単なAPIと、人間が読める形式のprotobufを表示する優れた.toString形式です。

特にClojureの場合、データ構造内の各ノードのコンストラクター関数を検索して呼び出すよりも、データ構造の観点からテンソルフローグラフを記述し、それらを直接protobufに変換する方がはるかに簡単です。

b)構築とパッケージの改善

私はネイティブコードのビルドや、これらのプロジェクトで使用されるビルドツールの専門家ではありません。 Maven化されたアーティファクトがあると便利です。 特に、生成されたjavaprotobufクラスも含まれている場合。 これを行う方法を理解するのに恥ずかしい時間がかかりました。

c)対象とするグラフテストケースの数が少ないと便利です。

今のところ、私の方法論はやや面倒です。JavaCPPコンストラクター関数を使用してグラフを生成し、それをJVMプロトタイプにマッシュオールして人間が読める形式を確認し、同じフォームを作成するために独自のコンストラクターを構築する方法を理解します。

TensorFlowのコア機能を実行する非常に単純なグラフの小さなコレクションがあると便利です。そのため、私のような人々は、さまざまな言語への相互運用を対象とする妥当なテストケースのセットを持っています。

とにかくみんなの努力に感謝し、良い仕事を続けてください!

@kovasbフィードバックをありがとう! 明らかに、Java、Scala、Clojureなどのインターフェースをより自然にするためにやるべきことがたくさんあります。

C ++ APIをJavaprotobuf APIと統合するヘルパークラスがある場合は、生成されたJava protobufクラス自体を含め、それらすべてを次のパッケージに自由に入れて、PRを送信してください。
https://github.com/bytedeco/javacpp-presets/tree/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper
それが意図されていることであり、Bazelがサポートしていないように見えるMavenアーティファクトに自動的にパッケージ化されます。 とにかく、これを調べてくれてありがとう!

@kovasbclojureインターフェースは本当に面白いですね。 まだ共有するコードはありますか?

ありがとう!

したがって、このスレッドの人々は、 https

私はデータフローを完全には理解していませんが、おそらくC ++ libと一緒にpythonヘルパーのものを起動することは可能ですか?

私が見ている別の解決策は、Jpyまたは他のブリッジの1つを使用することです(誰かが推奨事項がありますか?)JyNiも非常に興味深いように見えますが、プライムタイムからはかなり遠いです(その背後にある勢い/コミュニティが増えるのは素晴らしいことですが)

JyNiが整理された場合、それとjythonは、JVMにPythonエコシステムの相互運用に関する本当に素晴らしいストーリーを提供します。 人は夢を見ることができます。

Javaインターフェースの場合は+1!

javaCPPを使用できる場合でも、SWIGは必要ですか? SWIGインターフェースを実装するために協力しますか?

@maxiwu JavaCPPはSWIGよりも優れた仕事をしていると思うのが好きですが、実際にそれを証明するためにそれらを比較するために私はすべてです:)

@kovasbClojureインターフェースの支援/貢献に非常に興味があります。

@sorenmacbethは、Gmailのファーストネームドットラストネームで私にメールを送ってください。

ここには完全なJavacppプリセットがあるようです。 それは「チーム」にとって受け入れ可能な解決策ですか?

@saudet JavaCPPラッパーのコピーを作成しようとしていますが、テンソルフローソースの変化が速いため、0.6.0リリースまたは今日のマスターブランチのいずれとも互換性がないようです。 テストされた正確なテンソルフローコミット/バージョンへのポインターでそれらを更新することは可能でしょうか?

@nikitakitここでマスターブランチの更新を行いました: https

ただし、Caffeとは異なり、TensorFlowは実際には毎月リリースされるようです。そのため、次のリリース(0.7.0?)から、それらの時点でバインディングの安定化を開始すると思います。

@martinwickeどう思いますか?

安定したJavaバインディングがあれば、ScalaAPIで作業できてうれしいです。

/ cc @databricks

@kovasb私はこれを初めて逃したと思います。 Pythonを介してTensorFlowを使用することで得られるすべての優れた自動微分の魔法は、C ++ライブラリではなくPython内に実装されていると言っていますか? したがって、実際には、Java APIはこれらすべてを再実装する必要があるのでしょうか、それとも単なる別の数値ライブラリであるのでしょうか。 TensorFlowやPython接着剤の内部については、どこで重い物を持ち上げるのかを正確に理解するのに十分な知識がありません。

@drdozerは私の理解です。 @ girvingのコメントに基づいて、ソースを少し自分で調べています。 Javaでの再実装は、初心者のように思えます。 #3のコメントを見ることをお勧めします

誰かが本当に興味を持っている場合は、Java APIを使用していくつかのトレーニング例を試してみることをお勧めします(これまでのところ、フォワードパスを見た/実行したばかりです)。

JythonでPythonコードをどこまで実行できるのだろうか...

Python APIレイヤーには、C ++レイヤーAPIが公開していないロジックがたくさんあると思います。
私はJavaCppパスをたどろうとしていましたが、最終的には多くの重複コードがあり、Python実装で何かが変更されたときに一貫性を維持するのが困難になります。

おそらくもっと簡単な方法は、 @ saudetが以前に述べたようにJythonを使用することです...

https://github.com/tensorflow/tensorflow/issues/476で@ josh11bに割り当てられました。 彼がこれに取り組んでいる場合、Jythonを使用することは意味がありません。

jythonを使用する場合、c ++コードは引き続き機能しますか? これをJava内のサーバーに使用しようとしていますが、Javaルートを直接試すか、ソケットを介してPythonプロセスにデータを送信するかで行き詰まっています。

Java APIには自動微分のような多くの機能が含まれていませんが、これが自分の仕事の障壁になるとは思っていません。 Pythonでモデルを生成し、それを.protoファイルにシリアル化してから、トレーニングのためにJavaラッパーを介してモデルを開くことに大きな成功を収めました。 セーバー機能はC ++およびJavaAPIを介して利用できると私は信じているので、テスト時に同じことを行うことができます。

+1

@saudet
javacppとtensorflowのプリセットを作成していただきありがとうございます。 JavaでPythonグラフを正常に再作成できましたが、保存されたモデルファイルから復元しようとして立ち往生しています。 この行は機能しません:

Tensor fn = new Tensor(tensorflow.DT_STRING、new TensorShape(1));
CharBuffer buffer = fn.createBuffer();
buffer.put( "modelfile.tf");
session.Run(...);

しかし、CharBufferはNULLであることが判明しました。 DT_STRINGをDT_FLOATに変更すると、FloatBufferを取得しますが、DT_STRINGが機能していないようです。

@nikitakitあなたはこれが

@lakshmanok

編集:申し訳ありませんが、ここであなたが言ったことを読み間違えました。 Javaの外部セーバーを使用するためのヘルプを提供できません

参考までに、テンソルフローグラフをインポートするコードの一部は次のとおりです: https ://gist.github.com/nikitakit/d3ec270aee9d930267cec3efa844d5aa

それはScalaにありますが、Java /他のJVM言語への移植は簡単なはずです。

残念ながら、グラフで実際にノードを実行するためのコードは、使用しているScalaフレームワークと密接に関連しているため、この部分についてはtensorflowAPIドキュメントに依存する必要があります。

誰かがPythonテンソルフロー環境をjvmに埋め込むことでどこかに行きましたか? jython + JyNIで言いますか? それとも、これはすべて少し実験的すぎて、確実に機能することができませんか?

現在、グラフ定義のサポートを追加するためにCAPIの拡張に取り組んでいます。 いつ行われるかはわかりませんが、1.0より前の目標の1つです。

Javaからのテンソルフローの使用に取り組んでいます。 jythonを使用し、テンソルフローのcpythonライブラリを変更して、別のpythonインタープリターに対応することで問題に取り組んでいます。 cpythonは問題なく動作し続けるはずであり、私のコードはインタープリターがJythonであるかどうかを検出し、インポート/モジュールを変更して動作できるようにします。 その下では、libtensorflow_cc.soのjavacppバインディングを使用します。 これは、グーグルチームが公式リポジトリに公開するものですか? @vrv

これは概念実証のように思えますが、公式のバインディングでは、Pythonを使用するよりもネイティブにバインドしたいと思うでしょう:(

いいえ、c-pythonラッパーを呼び出す代わりに、javaccpラッパーを呼び出します。 したがって、cpythonテンソルフローと同じですが、Jythonを使用してJVMから評価されます。 Pythonロジック全体を別の言語で再実装するのは多すぎるように思われ、最終的には別のAPIになります。 javacppバインディングを使用すると、問題なく推論を実行できますが、現時点では、モデルをcpythonスクリプトからビルド/トレーニングする必要があります。

Kotlinでテンソルフローを機能させることを検討した人はいますか? それはより自然な適合のようであり、それでも1日の終わりには100%Javaです。 Kotlin言語は、Pythonと純粋なJavaの非常に優れた中間点であることがわかりました。

アップデート:私は成功しjavacppで(@saudetのおかげで)行く事を取得し、Javaプログラムが読み持っている/ TensorFlowモデルを実行することができました。

https://medium.com/google-cloud/how-to-invoke-a-trained-tensorflow-model-from-java-programs-27ed5f4f502d#.tx8nyds5v

@lakshmanok@saudetに感謝します。 javacppプロジェクトは、ほとんどのTensorFlowAPIを実装しているようです。 Javaでテンソルフロー/サービングを実行しようとし

APIはシンプルで、 protobuf定義されています。 これでサーバーが実装され、Javaでクライアントを実装する必要があります。 JavaでTensorProtoを作成し、 gRPC呼び出しを呼び出すだけです。 TensorFlowには、PythonとC ++の複数の次元配列を変換するヘルパー関数がありますが、Javaは提供していません。

javacppを使用する方法、またはこれを自分で実装する方法を教えてください。

あなたが探しているものはおそらくすでにhttps://github.com/bytedeco/javacpp-presets/blob/master/tensorflow/src/main/java/org/bytedeco/javacpp/helper/tensorflow.javaにありますが、私に知らせてください何かが足りない場合。 ありがとう!

これはまだ取り組んでいますか? この移植プロジェクトの公式githubリポジトリはありますか? ランダムなリポジトリがいくつか表示されますが、わかりません。

うん、でもおそらく10月/ 11月のいつか。 C ++ APIにSWIGする代わりにCAPIを使用しています。 それまでの間、saudetが言及したバインディングを使用できます。

どのようにしてCAPIを使用するという結論に達しましたか? 私たちは取り組んでいます
swigを使用したrubyインターフェース:
http://github.com/somaticio/tensorflow.rb

18:22で火、2016年9月13日には、ジョナサン・Hseu [email protected]
書きました:

うん、でもおそらく10月/ 11月のいつか。 CAPIを使用しています
C ++ APIにSWIGする代わりに。 それまでの間、
saudetが言及したバインディング。


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -246844192、
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAA5v3g86Z6D1rz-aTGdMyMWnQZhrZUYks5qpyIJgaJpZM4Getd8

今後は、すべての言語バインディングでCAPIを使用することをお勧めします。 ドキュメントが近日公開されます。

ここで使用例を見ることができます:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/go

ただし、緊急性はありません。SWIGの上に構築することは今のところ問題ありません。

@jhseuこれは、Pythonバインディングが現在アクセスできるすべてのものをカバーするようにC APIが拡張されることを意味しますか?

うわー、大きな変化。 これが以前に決定されたことを望みます。 とにかくドキュメントを見る
より早く?

17:56の水曜日、2016年9月14日には、サミュエルAudet [email protected]
書きました:

@jhseu https://github.com/jhseuそれは、 CAPI
Pythonバインディングが現在アクセスできるすべてをカバーするように拡張されましたか?


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/tensorflow/tensorflow/issues/5#issuecomment -247167887、
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAA5vwfBJoZC2s33_7E9Xy6-NYNUjHjnks5qqG2FgaJpZM4Getd8

@saudetほとんどの機能。ただし、短期的には、いくつかのもの(グラデーション、オプティマイザーなど)が欠落します。
@jtoy移行する緊急性はありません。 SWIGはしばらくの間機能し続けます。

ドキュメントには、その方法と命名規則が記載されています。 ただし、それらがなくてもCAPIへの移行を開始できます。
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

@saudetに感謝しTensorProtoを生成することについて、 stackoverflowでこれを見つけました。 そして、これがgRPCJavaクライアントにサービスを提供するTensorFlowのサンプルコードです。

@ tobegit3hubいいですね、C ++ APIでこれを機能させることができる場合は、JavaCPPプリセットのヘルパーパッケージに追加して、プルリクエストを送信してください。 この男はそのようなものに興味があるでしょう: https

@girving javacppはすでに問題を解決していますか?
tensorflow java apiに貢献したいのですが、Pythonのように実装することを好みます。

こんにちは皆さん、誰かがすでにCAPIを使用してJava / Scala言語バインディングの作業を開始しましたか?
(SWIGの上に構築する代わりに)

JNR経由でCAPIのみを使用して、テンソルフローへのJava / Scalaインターフェースが機能しています。 残念ながら、私はまだそれをオープンソース化する許可を持っていません。 リリースしたらここに投稿します。 それはまだ進行中の作業ですが、それは非常に機能的です。

@jdolson公開するAPIはTensorFlowのプロトコルバッファオブジェクトを受け入れますか? 私は@saudetからjavacppプリセットを使用して持っていた最大の問題の1つは、あなたがJavaクライアント・コードプロトコルバッファコンパイラによって生成されるorg.tensorflow.framework.TensorProtoとあなたしている取引でテンソルオブジェクトを操作しているときということですjavaを出力するように構成されています。 ただし、TensorFlow APIラッパーでは、Cを生成するように構成されたときにプロトコルバッファーコンパイラーによって生成されたcコードを指すとjavacppによって生成されるorg.bytedeco.javacpp.tensorflow.TensorProto.TensorProtoを処理しています。同じように、ラップされたTensorFlowAPIを呼び出すときにJavaコードのテンサーを直接使用することはできません。

@Intropyはい、すべてのtensorflow *.protoソースをprotocを使用してJavaソースコードにコンパイルし、APIでそれらのクラスを使用します。

@jhseu C APIインターフェースは、11月中にリリースされる予定ですか? そうでない場合、現在のステータスは何ですか?

@eaplatanios :C APIはほとんど安定しており(正式には1.0までにそうなるでしょう)、完全ではありませんが使用できます(グラフへの計算を自動的に勾配する機能がありません)。 C APIを使用して言語バインディングを構築する方法を説明するドキュメントは、 https://www.tensorflow.org/how_tos/language_bindings/index.htmlにあります。

Go APIは、上記のドキュメントに従う最初の例としてCAPIを使用して実装されました。

この上に(JNIを使​​用して)Javaバインディングを構築してもらい、少し調査を開始したいと考えています。 @saudetのすばらしい作業を使用してJavaCPPを機能させることに基づいて人々がコメント/学習したことは、知っておくと便利です。

JavaCPPバインディングの使用に基づいたいくつかの提案があります。

まず、プロトコルバッファはJavaに直接コンパイルされるため、Javaバージョンを使用する必要があります。 できれば、APIに参加するプロトコルバッファは、Mavenモジュールとして個別に利用可能であり、プロト定義が付属している必要があります。これにより、Javaスタックのユーザーは、定義をバイナリとして取得するだけでなく、簡単に取得できるようになります。他のプロト定義に含めるためのプロト定義を取得する方法。

次に、TensorFlowが必要とするlibcの最小バージョンを見つけて、それに対してビルドすると便利です。

第三に、自動生成されたAPIよりも慎重に設計されたAPIを使用する方がはるかに簡単です。 それは明らかで、JavaCPPでのショットのような音だと思います。 私はそうなるという意味ではありません。 自動生成されたインターフェースが存在することを本当にうれしく思います。 使用可能です。 しかし、それは奇妙な迂回を必要とし、多くの疣贅があり、あなたがやろうとしていることをどのように行うかを理解するためにコードを読むのはかなり難しいです。 この提案が「あなたはそれを良くするべきである」よりも役立つことを願っていますが、要点は、C ++ APIとpythonAPIがどれほど異なっているかということだと思います。 どちらも、自動的に変換されたコードが一致する可能性が低い方法で環境に適合しているため、簡単です。

SwigのCバックエンドをサポートし、Swigを介してTF C APIを生成する方が良かったかもしれません: https

CFFIを使用して任意の言語のサポートを追加するための既存のCAPIがあります。
https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/c_api.h

(これが、TensorFlowのGo、Java、Rustなどのバインディングを構築するために使用されるものです)

JNAを使用して

@jhseuつまり、C APIを手動で実装する前に、以前にC ++ APIから生成された可能性があります。

Quantum64 @、ここではJNAを使用していますtensorflowの結合スカラ座です。

この問題はまだ開いているので、どうすればよいですか
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/java
実装されており、コミットのPRは何でしたか?

@hsaputra :あなたが探しているものについて詳しくtensorflow/javaのコードに寄与する複数のコミットがあり、そのほとんどはこの問題で参照されています(2b1cd28、d73a266、およびその間の他の多くなど)

こんにちは@asimshankar 、返信ありがとう

このチケットは閉じられていないので、Java APIを実装するためにtensorflow/javaがたどるパスは何だったのだろうかと思っています。
JavaCPPとSWIGの使用とJython経由の呼び出しについての議論がありました。

tensorflow/javaは、代わりにC APIを呼び出すための直接JNIで実装されているように見えますか?

正しい。

おい、

昨日、これらのSwigバインディングを機能させました。 APIの変更をリクエストしています。 現在、Tensorsを生成するにはリフレクションが必要であり、配列の形式はn次元のネイティブJava配列を使用する必要があるため、少し扱いに​​くいです。 このインターフェースを維持するだけでなく、1次元配列を必要とするテンソルを作成し、longの別の配列を使用して形状を指定するためのいくつかのメソッドを追加できますか? 私はそれがこのように見えるかもしれないと想像します:

double[] matrix = {1.414, 2.718, 3.1415, 3.4, 56.7, 89.0};
long[] shape = {2, 3};

// add a method for each primitive type
org.tensorflow.Tensor tensor = org.tensorflow.Tensor.createDouble(matrix, shape);

これにより、int8、int16、uint8、uint16、uint32テンソルも作成される可能性があり、互換性が向上します。

これを問題にする必要がありますか? それともここで大丈夫ですか?

また、これらのメソッドを構築することに挑戦することは幸せです。

@hollinwilkins :PR#6577がこれに対処することを望んでいますが、提案されているファクトリメソッドを少し調整するだけです。

Tensor tensor = Tensor.create(shape, DoubleBuffer.wrap(matrix));

@asimshankarこれは素晴らしいです! 早速のお返事ありがとうございます。 マージにもかなり近いようです:+1:

新しいJavaAPIを使おうとしていますが、思ったよりも使いづらくなることがいくつかあります。

  1. Java APIは、GraphDefオブジェクトを受け入れる必要があります。 現在、GraphDefプロトコルバッファのシリアル化されたバイナリを表すバイト配列のみを受け入れます。 ライブラリの境界でシリアル化/逆シリアル化の手順が必要になるのは奇妙なことです。
  2. Session.Runner.feedはorg.tensorflow.framework.TensorProtoを受け入れることができるか、org.tensorflow.framework.TensorProtoからorg.tensorflow.Tensorを作成する良い方法があるはずです。
  3. Session.Runner.runは、Tensorオブジェクトのリストを返します。 上記と同様に、TensorProtoの出力を直接取得するか、org.tensorflow.TensorにTensorProtoに変換するための良い方法を提供することで簡単な方法があります。
  4. Session.Runner.runはステータスを飲み込みます。 おそらく例外をスローすることによって、失敗に関する情報を取得する方法があるはずです。

また、これを処理する方法を見逃した可能性もありますが、実行からの出力でサポートされているすべてのテンソルタイプを取得できないように見えます。 たとえば、出力テンソルがdtype INT16の場合、そこから値を抽出する方法はありません。 Tensor.shortValueなどはなく、Tensor.intValueは完全に一致する必要があるようです。 これは、tensor_jni.ccのDEFINE_GET_SCALAR_METHODを読み取ることに基づいています。

@Intropy :コメントありがとうございます。間違いなく理にかなっています。 今のところ、私はあなたといくつかの簡単な考えを共有することができます:

RE:protobufs:現時点では、いくつかの理由でコアAPIをprotobufsから独立させようとしています( nanprotoのようなものがより適切なリソース制限システムでの使用を含む)。 それが私たちが躊躇している理由ですが、それは私たちが考えていることであり、提案は高く評価されています。 1つの可能性は、protobufに関連するすべての機能を個別のパッケージに入れて、明確に分離することです。

だから、あなたのポイントに戻ります:

  1. 上記を参照。 ただし、 byte[]方が理にかなっている場合が多いと思います(ファイルやネットワークチャネルからグラフを読み取るなど)。

  2. 取ったポイント

  3. 上記を参照。

  4. Session.runner.runは嚥下状態であってなりませsession_jni.cc:166 )。 それが起こらない場合は、バグを報告してください。

確かに、すべてのタイプがまだサポートされているわけではありませんが、簡単に追加できるはずです。 不足しているタイプが差し迫った必要がある場合は、お気軽に問題を提出するか、PRを送信してください。 貢献は大歓迎です:)

@asimshankarご意見ありがとうございます。

最初の点に関しては、それは本当に大したことではありません。 あなたが言うように、byte []が最も理にかなっている時があります。 私自身のユースケースでは、byte []に​​変換するのは簡単なInputStreamがあります。 プロトコルバッファAPIを使用すると、変換が簡単になります。 とにかく(TF_GraphImportGraphDefで)逆シリアル化する必要があり、この方法では型の安全性が失われるため、私はbyte []をAPIの疣贅と見なしています。 考慮すべきproto3のjsonシリアル化もあります。

嚥下状態については、その通りです。 チェックされていない例外を見逃しました。

2と3を処理する最も明白な方法は、org.tensorflow.TensorにTensorProtoといくつかのtoTensorProto()から変換するファクトリを与えることです。 リソースが限られたユースケースがプロトコルバッファの問題である場合、そのような状況の人々は単にそれらの機能を使用できませんでした。 問題は、これらの関数を使用する人々が、Tensorにデータを直接プロトバフに保存させることで回避できる可能性のある変換のコストを支払うことになるということです。 これまでjniを使用したことがないため、データの保存方法を追跡するのに問題がありますが、nativeHandleは、基本的にサイズのvoid *のように扱われるTensorBufferを持つTF_Tensorへのポインターのように扱われているようです。

この問題を分割して、Javaインターフェイスの機能ごとに個別の問題を提出できますか? 追跡/解析が簡単になり、この問題を解決できます。

@drpngx :私の意図は、Goの場合と同じようにこれを閉じて、機能/バグを個別に

いいですね、ありがとう!

了解しました。構築するのに十分な基盤があるようです(たとえば、

この問題を解決します。 Java APIにはまだやるべきことがたくさんありますが、それらについては別の問題で議論/追跡しましょう。 ありがとう!

@asimshankarディープラーニングフレームワーク(mxnet / tf)を選択中ですが、etl / apiはspark / akkaフローに基づいています... Java APIにdistributed_runtimeサポートを追加して、psを使用してモデル並列トレーニングを実行する計画はありますかノード? psノードは多くのユースケースで重要です... C API自体にdistributed_runtimeが含まれていないように見えるため、javacppプリセットは最初のカットでエクスポートする方が簡単な場合があります...

@ debasish83 :分散ランタイムを含めること自体は簡単ですが、Python APIには、 Estimatorクラスのように、さまざまな処理(チェックポイント、サマリー保存など)を行う高レベルの構造がたくさんあります。 TensorBoardを使用して視覚化を簡単にします)。これにより、Pythonでトレーニングジョブを実行するのに適したものになる可能性があります。

これはすべて、Java APIの既存のプリミティブを使用して構築できますが、適切なアプローチは正確なニーズによって異なります。

おそらく、スレッドから同期する必要がありますか?

@asimshankarノードのリスト、入力および出力形式など、graphDef(ディスク上のグラフの.pbファイルから構築された)から情報を取得するためのテンソルフローJavaバインディングからの方法はすでにありますか、それとも着信機能ですか? ありがとう!

@asimshankar TFJavaでトレーニングを行うために何が欠けているのかわかりません。 数値ライブラリの問題ですか(numpyがありません)? つまり、TensorBoard datavizに興味がなくても、ネイティブJava数値ライブラリを使用してトレーニングのみを行う場合、トレーニングにのみpythonを使用するのはなぜですか( Estimatorクラスについて提案しているように)。

ありがとう。

Javaでのトレーニングモデルの状態はどうなっていますか? https://arxiv.org/pdf/1505.04597.pdf (最近、細胞追跡や生物医学アプリケーションの画像セグメンテーションで非常に人気があり

@bergwerf :特に便利ではないにしても、Javaでのトレーニングは確かに可能です。
サンプルはhttps://github.com/tensorflow/models/tree/master/samples/languages/java/trainingにあります。

(また、ご存知だと思いますが、https://imagej.net/TensorFlowも参照してください)

ああ、すごい! 私の情報は古くなっているに違いありません;-)。 読んだと思った
どこかでJavaAPIは、事前にトレーニングされた状態で予測することだけを目的としていました
モデル。 例を見ていきます。

水、2018年3月28日には、午前22時01分にはASIMシャンカール[email protected]書きました:

@bergwerf https://github.com/bergwerf:Javaでのトレーニングは確かに
おそらく、特に便利ではないにしても。
サンプルは次の場所にあります。
https://github.com/tensorflow/models/tree/master/samples/languages/java/training


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/tensorflow/tensorflow/issues/5#issuecomment-377015867
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AEQJ1UD9-xACQAII5996ees_UFJ_NzL-ks5ti-wSgaJpZM4Getd8

@asimshankarそれは素晴らしいです👍💯🥇、私は私のリポジトリに追加するつもりですhttps://github.com/loretoparisi/tensorflow-java

このページは役に立ちましたか?
0 / 5 - 0 評価