2016-12-16 82 views
0

我想在Android移動應用程序中使用TensorFlow來推斷模型。首先,我已經構建並測試了一個TensorFlow圖;它被保存爲一個protobuf文件。接下來,我有工具鏈設置,我已經建立並運行了Inception Android demo。我的下一步是在Android Studio(啓用C++)後創建一個新的Android項目,遵循Android tutorial。我創建了JNI Hello World應用程序,它編譯並在Nexus上運行。但是當我嘗試導入'org.tensorflow'時,我無法讓Android Studio(AS)識別它。所以,我的主要問題是:如何將TensorFlow帶入我的Demo應用程序。
例如,我創建了一個簡單的類入手:TensorFlow,Android Studio和Bazel:設置新項目

package com.foobar.tfdemo; 

import org.tensorflow.contrib.android.TensorFlowInferenceInterface; 

public class TensorFlowClassifier implements Classifier { 
// do something 
} 

但是Android Studio無法解析org.tensorflow。 可能的選項: 1)修改build.gradle編譯TF到項目(使用巴澤勒) 2)外部編譯TF庫(的.so)並將其導入,或 3)使用CMakeList.txt導入TF庫

詳細:

選項1)修改build.gradle
我使用Inception build.gradle作爲模型並複製了大部分。即使沒有其他錯誤,仍然不能解析相同的​​。這裏是build.gradle文件:

apply plugin: 'com.android.application' 
def bazel_location = '/usr/local/bin/bazel' 
def cpuType = 'armeabi-v7a' 
def nativeDir = 'libs/' + cpuType 

android { 
    compileSdkVersion 24 
    buildToolsVersion "25.0.2" 
    defaultConfig { 
     applicationId "com.algoint.tfdemo" 
     minSdkVersion 23 
     targetSdkVersion 24 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 

     externalNativeBuild { 
      cmake { 
       cppFlags "" 
      } 
     } 
    } 
    buildTypes { 
     release { 
      minifyEnabled false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    externalNativeBuild { 
     cmake { 
      path "CMakeLists.txt" 
     } 
    } 
} 

dependencies { 
    compile fileTree(include: ['*.jar'], dir: 'libs') 
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 
     exclude group: 'com.android.support', module: 'support-annotations' 
    }) 
    compile 'com.android.support:appcompat-v7:24.2.1' 
    testCompile 'junit:junit:4.12' 
} 

task buildNative(type:Exec) { 
    workingDir '../../..' 
    commandLine bazel_location, 'build', '-c', 'opt', \ 
     'tensorflow/examples/android:tensorflow_native_libs', \ 
     '--crosstool_top=//external:android/crosstool', \ 
     '--cpu=' + cpuType, \ 
     '[email protected]_tools//tools/cpp:toolchain' 
} 

task copyNativeLibs(type: Copy) { 
    from('../../../bazel-bin/tensorflow/examples/android') { include '**/*.so' } 
    into nativeDir 
    duplicatesStrategy = 'include' 
} 

copyNativeLibs.dependsOn buildNative 
assemble.dependsOn copyNativeLibs 
tasks.whenTaskAdded { task -> 
    if (task.name == 'assembleDebug') { 
     task.dependsOn 'copyNativelibs' 
    } 
} 

選項2:引入張量流庫(.so)文件。
我在這方面花了很多時間。我在命令行中使用巴澤勒產生libtensorflow_demo.so

bazel build //tensorflow/examples/android:tensorflow_native_libs --crosstool_top=//external:android/crosstool --cpu=$CPU [email protected]_tools//tools/cpp:toolchain 

,並把它放在這兩個項目的〜/庫和項目的〜/ SRC /應用/ src目錄/主/ jniLibs。但我所做的一切似乎都無濟於事。

選項3:使用CMakeList.txt編譯tensorflow。
我沒有花太多時間在這個。我不認爲CMakeList.txt將能夠調用Bazel或導入.so文件。我認爲它需要一個.a文件。

那麼,其他人如何將Tensorflow整合到Android項目中呢? 此致敬禮。

回答

0

在您的Android應用程序中嵌入預先訓練好的TensorFlow模型最近變得容易多了。在這裏看看我的博客文章:
https://medium.com/@daj/using-a-pre-trained-tensorflow-model-on-android-e747831a3d6(第1部分) https://medium.com/@daj/using-a-pre-trained-tensorflow-model-on-android-part-2-153ebdd4c465(部分2)

我的博客文章進入更多細節,但總的來說,所有你需要做的是:

  1. 包括在build.gradle中編譯org.tensorflow:tensorflow-android:+依賴項。
  2. 使用Java TensorFlowInferenceInterface類與您的模型接口(不需要修改任何本機代碼)。

僅供參考,TensorFlow Android演示程序已更新爲使用此新方法。有關使用TensorFlowInferenceInterface的位置,請參閱TensorFlowImageClassifier.recognizeImage

您仍然需要指定一些配置,例如圖中輸入和輸出節點的名稱以及輸入的大小,但是由於您構建了自己的TensorFlow圖,因此您可能知道此信息。 :-)