AndroidでTensorflowモデルをトレーニングしてデプロイするためのワークフローを理解しようとしています。 StackOverflowでこれに似た他の質問を知っていますが、私が遭遇した問題に対処しているようには見えません。
TensorflowリポジトリからAndroidの例を検討した後、ワークフローは次のようになると思います。
Adbを使用してAPKをデプロイします。
ステップ6が問題です。 Bazelは、JavaからJNI経由で呼び出すことができるネイティブ(OSXへの).dylibを喜んでコンパイルします。 Android Studioも同様に、必要なGUIを作成するXMLコードを大量に生成します。ただし、Bazelは、すべてのJavaアプリコードを(Tensorflowリポジトリ内の)「WORKSPACE」トップレベルディレクトリ内に配置することを望んでおり、Android StudioはSDKからのあらゆる種類の外部ライブラリにすぐにリンクしますGUIを作成する(これらのリソースが見つからない場合、Bazelのコンパイル実行が失敗するためです)。 Bazelに.soファイルのクロスコンパイルを強制する唯一の方法は、Androidルールの依存ルールにすることです。ネイティブライブラリを直接クロスコンパイルすることは、A.S。を移植することを好むものです。 Bazelプロジェクトへのコード。
これを二乗するにはどうすればよいですか? BazelはおそらくAndroidコードをコンパイルしますが、Android StudioはBazelがコンパイルできないコードを生成します。 Googleのすべての例は、リポジトリがどのように生成されたかについての手がかりなしに、リポジトリからコードを提供するだけです。私の知る限り、Android Studioアプリの一部であるXMLは、手動で作成されるのではなく、生成されることになっています。手作業で作成できる場合、これらすべての外部ライブラリの必要性を回避するにはどうすればよいですか?
ワークフローが間違っているか、Bazel/AndroidStudioの一部の側面が理解できない可能性があります。助けていただければ幸いです。
ありがとう!
編集:
図書館の建設に成功したかもしれない、私がやったことがいくつかありました。
以下に推奨されるBazelBUILDファイルを実装しましたが、いくつか追加しました(Androidの例から取得)。
cc_binary(
name = "libName.so",
srcs = ["org_tensorflowtest_MyActivity.cc",
"org_tensorflowtest_MyActivity.h",
"jni.h",
"jni_md.h",
":libpthread.so"],
deps = ["//tensorflow/core:Android_tensorflow_lib",
],
copts = [
"-std=c++11",
"-mfpu=neon",
"-O2",
],
linkopts = ["-llog -landroid -lm"],
linkstatic = 1,
linkshared = 1,
)
cc_binary(
name = "libpthread.so",
srcs = [],
linkopts = ["-shared"],
tags = [
"manual",
"notap",
],
)
このライブラリをAndroidに読み込んで使用できることはまだ確認していません。 Android Studio 1.5は、ネイティブライブラリの存在を認めるのに非常に気難しいようです。
WORKSPACEファイルにAndroid NDKを設定した後、Bazelは次のようにAndroid用の.soをクロスコンパイルできます。
cc_binary(
name = "libfoo.so",
srcs = ["foo.cc"],
deps = [":bar"],
linkstatic = 1,
linkshared = 1,
)
$ bazel build foo:libfoo.so \
--crosstool_top=//external:Android/crosstool --cpu=armeabi-v7a \
--Host_crosstool_top=@bazel_tools//tools/cpp:toolchain
$ file bazel-bin/foo/libfoo.so
bazel-bin/foo/libfoo.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Bazelは、すべてのJavaアプリコードを「WORKSPACE」トップレベルディレクトリ(Tensorflowリポジトリ内)内に配置することを望んでいます。
0.1.4がリリースされ(今すぐプッシュ)、TensorFlowとProtobufにいくつかの修正がプッシュされたら、TensorFlowリポジトリをリモートリポジトリとして使用できるようになります。 WORKSPACEファイルで設定した後、@tensorflow//foo/bar
ラベルを使用してTensorFlowルールを参照できます。
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git
注:-recurse-submodulesは、サブモジュールをプルするために重要です。
ここからBazelをインストールします。 Bazelは、TensorFlowの主要なビルドシステムです。ここで、WORKSPACEを編集すると、以前に複製したTensorFlowのルートディレクトリにWORKSPACEファイルがあります。
# Uncomment and update the paths in these entries to build the Android demo.
#Android_sdk_repository(
# name = "androidsdk",
# api_level = 23,
# build_tools_version = "25.0.1",
# # Replace with path to Android SDK on your system
# path = "<PATH_TO_SDK>",
#)
#
#Android_ndk_repository(
# name="androidndk",
# path="<PATH_TO_NDK>",
# api_level=14)
以下のように、SDKとNDKのパスを使用します。
Android_sdk_repository(
name = "androidsdk",
api_level = 23,
build_tools_version = "25.0.1",
# Replace with path to Android SDK on your system
path = "/Users/amitshekhar/Library/Android/sdk/",
)
Android_ndk_repository(
name="androidndk",
path="/Users/amitshekhar/Downloads/Android-ndk-r13/",
api_level=14)
次に、.soファイルを作成します。
bazel build -c opt //tensorflow/contrib/Android:libtensorflow_inference.so \
--crosstool_top=//external:Android/crosstool \
--Host_crosstool_top=@bazel_tools//tools/cpp:toolchain \
--cpu=armeabi-v7a
Armeabi-v7aを目的のターゲットアーキテクチャに置き換えます。ライブラリは次の場所にあります。
bazel-bin/tensorflow/contrib/Android/libtensorflow_inference.so
Java対応物を構築するには:
bazel build //tensorflow/contrib/Android:android_tensorflow_inference_Java
JARファイルは次の場所にあります。
bazel-bin/tensorflow/contrib/Android/libandroid_tensorflow_inference_Java.jar
これで、jarファイルと.soファイルの両方ができました。私はすでに.soファイルとjarの両方をビルドしました。 プロジェクト から直接使用できます。
Libandroid_tensorflow_inference_Java.jarをlibsフォルダーに置き、右クリックしてライブラリとして追加します。
compile files('libs/libandroid_tensorflow_inference_Java.jar')
メインディレクトリにjniLibsフォルダを作成し、libtensorflow_inference.soをjniLibs/armeabi-v7a /フォルダに配置します。
これで、TensorFlow Java APIを呼び出すことができます。
TensorFlow Java APIは、クラスTensorFlowInferenceInterfaceを介して必要なすべてのメソッドを公開しました。
ここで、モデルパスを使用してTensorFlow Java APIを呼び出し、ロードする必要があります。
私は完全なブログを書きました ここ 。