implementation 'org.tensorflow:tensorflow-lite:+'
在我的build.gradle
依赖项下而使用了推理时间不太长,所以现在我想在Android的NDK中使用TFL。
因此,我在Android Studio的NDK中构建了Java应用程序的精确副本,现在我试图在项目中包含TFL库。我遵循TensorFlow-Lite的Android指南,并在本地构建了TFL库(并获得了AAR文件),并将该库包含在Android Studio的NDK项目中。
现在,我尝试通过#include
在代码中尝试在C ++文件中使用TFL库,但收到一条错误消息:(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')
}
项目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);
};
我还尝试遵循以下步骤:
但就我而言,我使用Bazel构建了TFL库。
尝试构建(label_image)的分类演示时,我设法将其构建adb push
到我的设备上,但是尝试运行时出现以下错误:
ERROR: Could not open './mobilenet_quant_v1_224.tflite'.
Failed to mmap model ./mobilenet_quant_v1_224.tflite
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",
},
)
而这是仅有的2cc_toolchain
秒。在存储库中搜索“ 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
通过更改soname
in build config并使用中的完整路径来构建体系结构库CMakeLists.txt
。这导致了.so
共享库。另外-arm64-v8a
通过调整aarch64_makefile.inc
文件,我能够构建使用TFLite Docker容器的库,但是我没有更改任何构建选项,build_aarch64_lib.sh
而是让其进行构建。这产生了一个.a
静态库。
所以现在我有两个TFLite库,但是我仍然无法使用它们(#include "..."
例如,我什么也做不了)。
尝试构建项目时,仅x86_64
可以正常使用,但尝试将arm64-v8a
库包含在忍者错误中:'.../libtensorflow-lite.a', needed by '.../app/build/intermediates/cmake/debug/obj/armeabi-v7a/libnative-lib.so', missing and no known rule to make it
。
lite
目录中获取了基本的C / C ++源文件和标头,并在中创建了类似的结构app/src/main/cpp
,其中包括(A)tensorflow,(B)absl和(C)flatbuffers文件#include "tensorflow/...
所有tensorflow头文件中的行更改为相对路径,以便编译器可以找到它们。build.gradle
我为.tflite
文件添加了无压缩行:aaptOptions { noCompress "tflite" }
assets
在应用程序中添加了目录native-lib.cpp
我从TFLite网站添加了一些示例代码arm64-v8a
)。我收到一个错误:
/path/to/Android/Sdk/ndk/20.0.5594570/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1/memory:2339: error: undefined reference to 'tflite::impl::Interpreter::~Interpreter()'
在<memory>
,第2339行是以下"delete __ptr;"
行:
_LIBCPP_INLINE_VISIBILITY void operator()(_Tp* __ptr) const _NOEXCEPT {
static_assert(sizeof(_Tp) > 0,
"default_delete can not delete incomplete type");
static_assert(!is_void<_Tp>::value,
"default_delete can not delete incomplete type");
delete __ptr;
}
如何在Android Studio中包含TFLite库,以便可以从NDK运行TFL推论?
或者-如何使用gradle(当前与cmake一起)来构建和编译源文件?
我通过以下方式将原生TFL与C-API结合使用:
.arr
文件的文件类型更改为,.zip
并解压缩该文件以获取共享库(.so
文件)c
目录下载所有头文件jni
目录(New
- > Folder
- > JNI Folder
)中app/src/main
,并在其中还可以创建架构子目录(arm64-v8a
或x86_64
例如)jni
目录中(架构目录旁边),并将共享库放在架构目录中CMakeLists.txt
文件,并add_library
在TFL库中包含一个节,在节中包含共享库的路径,并在set_target_properties
节中包含标题include_directories
(请参见下面的“注释”部分)。在native-lib.cpp
包括标题中,例如:
#include "../jni/c_api.h"
#include "../jni/common.h"
#include "../jni/builtin_ops.h"
TFL函数可以直接调用,例如:
TfLiteModel * model = TfLiteModelCreateFromFile(full_path);
TfLiteInterpreter * interpreter = TfLiteInterpreterCreate(model);
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor * input_tensor =
TfLiteInterpreterGetInputTensor(interpreter, 0);
const TfLiteTensor * output_tensor =
TfLiteInterpreterGetOutputTensor(interpreter, 0);
TfLiteStatus from_status = TfLiteTensorCopyFromBuffer(
input_tensor,
input_data,
TfLiteTensorByteSize(input_tensor));
TfLiteStatus interpreter_invoke_status = TfLiteInterpreterInvoke(interpreter);
TfLiteStatus to_status = TfLiteTensorCopyToBuffer(
output_tensor,
output_data,
TfLiteTensorByteSize(output_tensor));
cmake
环境也包括在内 cppFlags "-frtti -fexceptions"
CMakeLists.txt
例:
set(JNI_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../jni)
add_library(tflite-lib SHARED IMPORTED)
set_target_properties(tflite-lib
PROPERTIES IMPORTED_LOCATION
${JNI_DIR}/${ANDROID_ABI}/libtfl.so)
include_directories( ${JNI_DIR} )
target_link_libraries(
native-lib
tflite-lib
...)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句