2016-01-20 11 views
18

AndroidでTensorflowモデルをトレーニングして展開するためのワークフローを理解しようとしています。私はStackOverflowでこのような他の質問を知っているが、それらのどれも私が遭遇した問題に対処していないようだ。AndroidでTensorflowモデルを実行する

TensorflowリポジトリからAndroidの例を勉強した後、これは、私はワークフローがあるべきだと思うものです:

  1. ビルドとPythonでモデルをTensorflow訓練。
  2. 新しいグラフを作成し、関連するすべてのノード(つまり、トレーニングを担当するノードではない)をこの新しいグラフに転送します。訓練された重み変数は、C++ APIがそれらを読み取ることができるように定数としてインポートされます。
  3. JavaでAndroid GUIを開発し、nativeキーワードを使用してTensorflowモデルへの呼び出しをスタブアウトします。
  4. javahを実行して、Tensorflowネイティブコール用のC/C++スタブコードを生成します。
  5. Tensorflow C++ APIを使用してスタブを記入し、訓練された/シリアル化されたモデルを読み込んでアクセスします。
  6. Bazelを使用して、JavaアプリケーションとネイティブTensorflowインターフェイス(.soファイル)の両方をビルドし、APKを生成します。
  7. adbを使用してAPKを導入します。

    手順6が問題です。 BazelはJNI経由でJavaから呼び出せるネイティブ(OSX).dylibをうれしくコンパイルします。 Android Studioも同様に、必要なGUIを作成するXMLコードを生成します。しかし、BazelはすべてのJavaアプリケーションコードを(ワークスペース)の最上位ディレクトリ(Tensorflowリポジトリ内)に入れることを望んでいます.Android StudioはSDKのあらゆる種類の外部ライブラリを直ちにリンクしてGUIを作成しますこれらのリソースが見つからない場合、Bazelのコンパイルは失敗します)。私がBazelに.soファイルをクロスコンパイルさせる唯一の方法は、それをAndroidルールの従属ルールにすることです。ネイティブlibを直接クロスコンパイルするのは私のA.Sを移植するのが好きです。コードをBazelプロジェクトに追加します。

    これをどのように正方形にしますか? BazelはAndroidコードをコンパイルすると思われますが、Android StudioはBazelがコンパイルできないコードを生成します。 Googleのすべての例は、生成された方法についてのヒントなしに、単にレポからコードを提供します。私が知る限り、Androidスタジオアプリの一部であるXMLは、手作業で作られるのではなく、生成されるはずです。手作業で作ることができるのであれば、どうすればそれらの外部ライブラリの必要性を避けることができますか?

    私はワークフローが間違っているか、Bazel/Android Studioのいくつかの側面がわかりません。どんな助けもありがたい。

ありがとう!

編集:

  1. 私は、最新のBazelにアップグレード:

    私はそれをやってしまったいくつかのことに成功し、ライブラリの構築に寄与している可能性がありました。

  2. TensorFlowをソースから再構築しました。
  3. 私はお勧めBazelは、(Androidの例から取られた)いくつかの追加で、以下のファイルを作成し実施し
  4. 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は、ネイティブライブラリの存在を認めることに非常に精通しているようです。

+0

AndroidがOSX-dylibでないため、.dylibを作成することはまったく役に立ちません。OSX-dylibはOSXのみの形式です。それはLinuxだから、あなたは.so(これはほとんど同じ機能ですが、別のファイル形式です)を構築する必要があります。また、AndroidのXMLはすべて手作業で作られたものではありません。どんなGoogleの例でもほとんど何も生成されていません。あなたがそれを期待しているという事実はおそらくあなたの問題の一部です。 –

+0

また、あなたのTensorflowソフトウェアがBazelを使用する必要がない限り、Androidワークに使用されていることは聞いたことがありません。 Gradleは新しい標準であり、Antは従来の標準です。あなたがBazelを使っているなら、あなたは最先端を出ているか、あなた自身のことを完全にやっています。 –

+0

@ammあなたが作ったアプリのサイズはどれくらいですか? – sau

答えて

10

ワークスペースファイル内の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 \ 
    [email protected]_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 
0.1.4がリリースされ

Bazel wants all of the java app code to be inside the 'WORKSPACE' top-level directory (in the Tensorflow repo)

は(今それを押します)、TensorFlowとProtobufにいくつかの修正を加えました.TensorFlowレポをリモートリポジトリとして使用することができます。 WORKSPACEファイルに設定したら、@tensorflow//foo/barラベルを使用してTensorFlowルールを参照することができます。

+0

[Bazelグループ](https://github.com/ulfjack/bazel/graphs/contributors)のメンバーは、あなたの[SOのプロフィール](http://stackoverflow.com/users)でメモすることができます。/4731056/ulf-adams)。回答した人が開発チームのメンバーであることが分かっている場合は、回答をアップアップする方がより適切です。 –

+0

コメントの意味:アプリケーションコードをTensorflowルートとは別のディレクトリ構造に保存できません。 – amm

+0

この解決法は私のためには機能しません。エラーメッセージ:「エラー:cpu 'darwin'のツールチェーンが見つかりません」私はandroid_sdk_repository()とandroid_ndk_repository()をWORKSPACEファイルに定義しました。 – amm

1
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git 

注: - サブモジュールをプルするには--recurse-submodulesが重要です。

ここからBazelをインストールしてください。 Bazelは、TensorFlowの主要構築システムです。 これで、WORKSPACEを編集すると、以前にクローン化したTensorFlowのルートディレクトリでWORKSPACEファイルを見つけることができます。

当社のSDKとNDKパスと以下のように
# 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) 

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 \ 
    [email protected]_tools//tools/cpp:toolchain \ 
    --cpu=armeabi-v7a 

armeabi-v7aを希望するターゲットアーキテクチャに置き換えます。 Javaのカウンターパートを構築するには

bazel-bin/tensorflow/contrib/android/libtensorflow_inference.so 

: ライブラリがに配置されます

bazel build //tensorflow/contrib/android:android_tensorflow_inference_java 

我々がでJARファイルを見つけることができます。

bazel-bin/tensorflow/contrib/android/libandroid_tensorflow_inference_java.jar 

今、私たちは、両方の瓶を持っています。だからファイル。私はすでに.soファイルとjarの両方をビルドしていますが、projectから直接使用できます。

libandroid_tensorflow_inference_java.jarをlibsフォルダに置き、右クリックしてライブラリとして追加します。

compile files('libs/libandroid_tensorflow_inference_java.jar') 

メインディレクトリにjniLibsフォルダを作成し、jniLibs/armeabi-v7a /フォルダに入れlibtensorflow_inference.so。

ここで、TensorFlow Java APIを呼び出すことができます。

TensorFlow Java APIは、TensorFlowInferencefaceクラスを使用して、必要なすべてのメソッドを公開しています。

ここで、モデルパスでTensorFlow Java APIを呼び出してロードする必要があります。

私は完全なブログhereを書きました。

関連する問題