如何在(Android Studio)NDK(C / C ++ API)中运行Tensorflow-Lite推理?

橙色东西橙色

信息

  • 我从Keras构建了Tensorflow(TF)模型,并将其转换为Tensorflow-Lite(TFL)
  • 我在Android Studio中构建了一个Android应用,并使用Java API运行了TFL模型
  • 在Java应用程序中,我将TFL支持库(请参阅此处)和JCenter的TensorFlow Lite AAR通过包含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
  • 我跟着zimenglyu的帖子:试图设置android_sdk_repository/android_ndk_repositoryWORKSPACE了我的错误: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_binarytensorflow/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'

使用Android Studio中的库:

我能够x86_64通过更改sonamein 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

不同的方法-使用Gradle构建/编译源文件:

  1. 我在Android Studio中创建了本机C ++项目
  2. 我从Tensorflow的lite目录中获取了基本的C / C ++源文件和标头,并在中创建了类似的结构app/src/main/cpp,其中包括(A)tensorflow,(B)absl和(C)flatbuffers文件
  3. 我将#include "tensorflow/...所有tensorflow头文件中更改为相对路径,以便编译器可以找到它们。
  4. 在应用程序的文件中,build.gradle我为.tflite文件添加了无压缩行aaptOptions { noCompress "tflite" }
  5. assets在应用程序中添加了目录
  6. 在其中,native-lib.cpp从TFLite网站添加了一些示例代码
  7. 尝试构建包含源文件的项目(构建目标为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结合使用:

设定:

  1. 下载最新版本的TensorFlow Lite AAR文件
  2. 将下载.arr文件的文件类型更改为.zip并解压缩该文件以获取共享库(.so文件)
  3. TFL信息库中c目录下载所有头文件
  4. 在Android Studio中创建一个Android C ++应用
  5. 创建一个jni目录(New- > Folder- > JNI Folder)中app/src/main,并在其中还可以创建架构子目录(arm64-v8ax86_64例如)
  6. 将所有头文件放在jni目录中(架构目录旁边),并将共享库放在架构目录中
  7. 打开CMakeLists.txt文件,并add_library在TFL库中包含一个节,在节中包含共享库的路径,并在set_target_properties节中包含标题include_directories(请参见下面的“注释”部分)。
  8. 同步摇篮

用法:

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));

笔记:

  • 在此安装程序中,使用了SDK版本29
  • 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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在C(Android NDK)中杀死子线程?

来自分类Dev

如何在C(Android NDK)中杀死子线程?

来自分类Dev

在 C++ 中使用加载的 tensorflow 模型运行推理

来自分类Dev

如何使用Android Studio + Gradle + NDK构建外部C ++库?

来自分类Dev

尝试在Android上使用专为ARM64构建的Tensorflow-Lite C API时使用未定义的引用-NDK ARM独立工具链

来自分类Dev

如何在Android NDK中将Android代码转换为C

来自分类Dev

如何在Tensorflow的C ++ API中传输CUDA常量内存

来自分类Dev

如何在Tensorflow的C ++ API中传输CUDA常量内存

来自分类Dev

如何在 NDK 中计算 C 中的输入 int 数组

来自分类Dev

如何在Android Studio 1.3中配置NDK项目

来自分类Dev

如何在 Android Studio 中查看 NDK 错误日志?

来自分类Dev

使用C ++中的NDK更新Android UI

来自分类Dev

在Android NDK C ++代码中捕获异常

来自分类Dev

Android NDK中的C ++函数重载

来自分类Dev

有没有办法在C ++中以编程方式执行adb命令?这部分C ++代码是使用android studio中的ndk build构建的。那里

来自分类Dev

使用Android NDK在C或C ++中创建本地本机模块?

来自分类Dev

将Java字符串处理为Android Studio + NDK的本机C / C ++

来自分类Dev

如何在C ++中运行Python文件?

来自分类Dev

如何在Heroku中运行C ++代码?

来自分类Dev

如何在Shell中运行C函数?

来自分类Dev

如何在C中多次运行循环?

来自分类Dev

如何在Android Studio 1.5中包括.so库和.c文件

来自分类Dev

如何在Android Studio中构建本地/主机OS C ++单元测试?

来自分类Dev

C:/ android-ndk“在android的PATH中找不到

来自分类Dev

在android中运行tensoflow推理图

来自分类Dev

如何在Android中不使用Xamarin的情况下使用Mono运行C#代码?

来自分类Dev

如何在Xamarin Android中的运行时执行C#代码?

来自分类Dev

如何在Xamarin Android中的运行时执行C#代码?

来自分类Dev

如何在VST中推理数组访问?

Related 相关文章

  1. 1

    如何在C(Android NDK)中杀死子线程?

  2. 2

    如何在C(Android NDK)中杀死子线程?

  3. 3

    在 C++ 中使用加载的 tensorflow 模型运行推理

  4. 4

    如何使用Android Studio + Gradle + NDK构建外部C ++库?

  5. 5

    尝试在Android上使用专为ARM64构建的Tensorflow-Lite C API时使用未定义的引用-NDK ARM独立工具链

  6. 6

    如何在Android NDK中将Android代码转换为C

  7. 7

    如何在Tensorflow的C ++ API中传输CUDA常量内存

  8. 8

    如何在Tensorflow的C ++ API中传输CUDA常量内存

  9. 9

    如何在 NDK 中计算 C 中的输入 int 数组

  10. 10

    如何在Android Studio 1.3中配置NDK项目

  11. 11

    如何在 Android Studio 中查看 NDK 错误日志?

  12. 12

    使用C ++中的NDK更新Android UI

  13. 13

    在Android NDK C ++代码中捕获异常

  14. 14

    Android NDK中的C ++函数重载

  15. 15

    有没有办法在C ++中以编程方式执行adb命令?这部分C ++代码是使用android studio中的ndk build构建的。那里

  16. 16

    使用Android NDK在C或C ++中创建本地本机模块?

  17. 17

    将Java字符串处理为Android Studio + NDK的本机C / C ++

  18. 18

    如何在C ++中运行Python文件?

  19. 19

    如何在Heroku中运行C ++代码?

  20. 20

    如何在Shell中运行C函数?

  21. 21

    如何在C中多次运行循环?

  22. 22

    如何在Android Studio 1.5中包括.so库和.c文件

  23. 23

    如何在Android Studio中构建本地/主机OS C ++单元测试?

  24. 24

    C:/ android-ndk“在android的PATH中找不到

  25. 25

    在android中运行tensoflow推理图

  26. 26

    如何在Android中不使用Xamarin的情况下使用Mono运行C#代码?

  27. 27

    如何在Xamarin Android中的运行时执行C#代码?

  28. 28

    如何在Xamarin Android中的运行时执行C#代码?

  29. 29

    如何在VST中推理数组访问?

热门标签

归档