Я пытаюсь использовать TensorFlow в мобильном приложении для Android, чтобы сделать вывод о модели. Во-первых, я уже построил и протестировал график TensorFlow; он сохраняется как файл protobuf. Затем у меня есть настройка цепочки инструментов, и я собрал и запустил Начальная демоверсия Android. Мой следующий шаг — создать новый Android-проект в Android Studio (с включенным C ++), следуя Android руководство. Я создал приложение JNI Hello World, оно компилируется и работает на Nexus. Но когда я попытался импортировать org.tensorflow, я не могу заставить Android Studio (AS) его распознать. Итак, мой основной вопрос: как добавить TensorFlow в мое демо-приложение.
Например, я создал простой класс для начала:
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 в проект (используя Bazel)
2) Внешне скомпилируйте библиотеку TF (.so) и импортируйте ее, или
3) Используйте CMakeList.txt для импорта библиотеки TF
В деталях:
Вариант 1) Изменить build.gradle
,
Я использовал Начало build.gradle
в качестве модели и скопировал большую часть этого. Такой же import org.tensorflow
по-прежнему не разрешается, хотя других ошибок нет. Здесь 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, \
'--host_crosstool_top=@bazel_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 в командной строке:
bazel build //tensorflow/examples/android:tensorflow_native_libs --crosstool_top=//external:android/crosstool --cpu=$CPU --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
и поместил его в ~ project / libs и ~ project / src / app / src / main / jniLibs. Но ничто, что я делаю, кажется, не поможет.
Вариант 3: Используйте CMakeList.txt для компиляции тензорного потока.
Я не тратил много времени на это. Я не думаю CMakeList.txt
сможет вызвать Bazel или импортировать файл .so. Я думаю, что вместо этого нужен файл .a.
Итак, как другие включили Tensorflow в проекты Android?
С наилучшими пожеланиями.
В последнее время стало намного проще встраивать предварительно обученную модель TensorFlow в ваше приложение для Android. Проверьте мои сообщения в блоге здесь:
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)
Мой пост в блоге более детален, но в целом все, что вам нужно сделать, это:
org.tensorflow:tensorflow-android:+
зависимость в вашем build.gradle. TensorFlowInferenceInterface
класс для взаимодействия с вашей моделью (нет необходимости изменять какой-либо нативный код).К вашему сведению, демо-приложение TensorFlow для Android было обновлено для использования этого нового подхода. Увидеть TensorFlowImageClassifier.recognizeImage где он использует TensorFlowInferenceInterface
,
Вам все еще нужно будет указать некоторую конфигурацию, например, имена входных и выходных узлов на графике и размер входных данных, но поскольку вы построили свой собственный график TensorFlow, вы, вероятно, знаете эту информацию. 🙂
Посмотрите на это:
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/android/cmake
И в debugCompile
а также releaseCompile
вместо tensorflow_inference
использование TensorFlow-Android-Inference
,
Это сработало для меня.