Информация
- Я построил модель Tensorflow (TF) из Keras и преобразовал ее в Tensorflow-Lite (TFL)
- Я создал приложение Android в Android Studio и использовал API Java для запуска модели TFL
- . В приложении Java я использовал библиотеку поддержки TFL (см. здесь ) и TensorFlow Lite AAR из JCenter. включив
implementation 'org.tensorflow:tensorflow-lite:+'
в мои build.gradle
зависимости
Время вывода не так велико, так что теперь я хочу использовать TFL в NDK Android.
Так что я собрал точную копию приложения Java в NDK Studio 1145 *, и теперь я пытаюсь включить библиотеки TFL в проект. Я следовал TensorFlow-Lite Android гиду и создал библиотеку TFL локально (и получил файл AAR) и включил библиотеку в свой проект NDK в Android Studio.
Сейчас Я пытаюсь использовать библиотеку TFL в своем файле C ++, пытаясь #include
это в коде, но я получаю сообщение об ошибке: cannot find tensorflow
(или любое другое имя, которое я пытаюсь использовать, в соответствии с именем Я даю это в моем CMakeLists.txt
файле).
Файлы
Приложение build.gradle :
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.ndk.tflite"
minSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
ndk {
abiFilters 'arm64-v8a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
// tf lite
aaptOptions {
noCompress "tflite"
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// tflite build
compile(name:'tensorflow-lite', ext:'aar')
}
Project build. gradle :
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.6.2'
}
}
allprojects {
repositories {
google()
jcenter()
// native tflite
flatDir {
dirs 'libs'
}
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
CMakeLists.txt :
cmake_minimum_required(VERSION 3.4.1)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
add_library( # Sets the name of the library.
tensorflow-lite
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib tensorflow-lite
# Links the target library to the log library
# included in the NDK.
${log-lib} )
native-lib. cpp:
#include <jni.h>
#include <string>
#include "tensorflow"
extern "C" JNIEXPORT jstring JNICALL
Java_com_xvu_f32c_1jni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
class FlatBufferModel {
// Build a model based on a file. Return a nullptr in case of failure.
static std::unique_ptr<FlatBufferModel> BuildFromFile(
const char* filename,
ErrorReporter* error_reporter);
// Build a model based on a pre-loaded flatbuffer. The caller retains
// ownership of the buffer and should keep it alive until the returned object
// is destroyed. Return a nullptr in case of failure.
static std::unique_ptr<FlatBufferModel> BuildFromBuffer(
const char* buffer,
size_t buffer_size,
ErrorReporter* error_reporter);
};
Progress
Я также попытался выполнить следующие действия:
но в моем случае я использовал Bazel для сборки библиотек TFL.
Пытаясь создать классификационную демонстрацию ( label_image ), мне удалось собрать ее и adb push
для моего устройства, но при попытке запустить я получил следующую ошибку:
ERROR: Could not open './mobilenet_quant_v1_224.tflite'.
Failed to mmap model ./mobilenet_quant_v1_224.tflite
- Я следовал Пост zimenglyu : попытка установить
android_sdk_repository
/ android_ndk_repository
в WORKSPACE
получил меня ошибка: WORKSPACE:149:1: Cannot redefine repository after any load statement in the WORKSPACE file (for repository 'androidsdk')
, и размещение этих операторов в разных местах приводило к одной и той же ошибке. - Я удалил эти изменения в
WORKSPACE
и продолжил работу с постом zimenglyu: я скомпилировал libtensorflowLite.so
и отредактировал CMakeLists.txt
, чтобы на файл libtensorflowLite.so
была ссылка, но часть FlatBuffer
была исключена. Проект Android успешно скомпилирован, но очевидных изменений не произошло, я все еще не могу включить библиотеки TFLite.
Пытаясь скомпилировать TFL, я добавил cc_binary
к tensorflow/tensorflow/lite/BUILD
( следуя примеру label_image ):
cc_binary(
name = "native-lib",
srcs = [
"native-lib.cpp",
],
linkopts = tflite_experimental_runtime_linkopts() + select({
"//tensorflow:android": [
"-pie",
"-lm",
],
"//conditions:default": [],
}),
deps = [
"//tensorflow/lite/c:common",
"//tensorflow/lite:framework",
"//tensorflow/lite:string_util",
"//tensorflow/lite/delegates/nnapi:nnapi_delegate",
"//tensorflow/lite/kernels:builtin_ops",
"//tensorflow/lite/profiling:profiler",
"//tensorflow/lite/tools/evaluation:utils",
] + select({
"//tensorflow:android": [
"//tensorflow/lite/delegates/gpu:delegate",
],
"//tensorflow:android_arm64": [
"//tensorflow/lite/delegates/gpu:delegate",
],
"//conditions:default": [],
}),
)
и пытаясь построить его для x86_64
, и arm64-v8a
я получаю сообщение об ошибке: cc_toolchain_suite rule @local_config_cc//:toolchain: cc_toolchain_suite '@local_config_cc//:toolchain' does not contain a toolchain for cpu 'x86_64'
.
Проверка external/local_config_cc/BUILD
(которая вызвала ошибку) в строке 47:
cc_toolchain_suite(
name = "toolchain",
toolchains = {
"k8|compiler": ":cc-compiler-k8",
"k8": ":cc-compiler-k8",
"armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a",
"armeabi-v7a": ":cc-compiler-armeabi-v7a",
},
)
, и это только 2 cc_toolchain
s, найденных. При поиске в репозитории "cc -compiler-" я обнаружил только " aarch64 ", который, как я предполагал, предназначен для 64-разрядного ARM, но ничего с "x86_64". Есть "x64_ windows", хотя - и я на Linux.
Попытка собрать с помощью aarch64 следующим образом:
bazel build -c opt --fat_apk_cpu=aarch64 --cpu=aarch64 --host_crosstool_top=@bazel_tools//tools/cpp:toolchain //tensorflow/lite/java:tensorflow-lite
приводит к ошибке:
ERROR: /.../external/local_config_cc/BUILD:47:1: in cc_toolchain_suite rule @local_config_cc//:toolchain: cc_toolchain_suite '@local_config_cc//:toolchain' does not contain a toolchain for cpu 'aarch64'
Я смог собрать библиотеку для архитектуры x86_64 и включить ее в Android Studio - добавив -soname
в конфигурацию сборки и используя полные пути в CMakeLists.txt
, но не смог использовать библиотека (#include "..."
например). Сборка для ARM все еще не удалась.
Вопрос
В моем приложении (Android Studio) я получаю ошибки (1) Can't resolve type 'ErrorReporter'
и (2) cannot find tensorflow
из native-lib.cpp
file.
Как мне выполнить вывод TFL из NDK?