【发布时间】:2018-09-24 20:51:10
【问题描述】:
我目前正在从事一个有关神经网络的项目。 为此,我想构建一个 Android 应用程序,它应该使用 tensorflow [lite] 来解决一些对象检测/识别问题。
由于我希望代码尽可能可移植,我想用 C++ 编写大部分代码,因此在 Java API/包装器上使用 tensorflow lite 的 C++ API。 因此,我修改了 tensorflow/contrib/lite/BUILD 并添加了以下内容,以便能够创建共享的 tensorflow 库。
cc_binary(
name = "libtensorflowLite.so",
linkopts=["-shared", "-Wl"],
linkshared=1,
copts = tflite_copts(),
deps = [
":framework",
"//tensorflow/contrib/lite/kernels:builtin_ops",
],
)
(根据这个问题的答案:https://github.com/tensorflow/tensorflow/issues/17826)
然后我用了
bazel build //tensorflow/contrib/lite:libtensorflowLite.so --crosstool_top=//external:android/crosstool --cpu=arm64-v8a --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --cxxopt="-std=c++11"
最终构建它。
之后,我前往 Android Studio 并设置了一个基本项目。 为了将共享库添加到项目中,我参考了这个示例:
我还添加了 flatbuffers 所需的依赖项。
构建/编译过程成功,没有任何链接器错误(好吧,至少在尝试了几个小时之后......)。
APK 随后成功安装在 Android 设备上,但在启动后立即崩溃。 Logcat 给出以下输出:
04-14 20:09:59.084 9623-9623/com.example.hellolibs E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.hellolibs, PID: 9623
java.lang.UnsatisfiedLinkError: dlopen failed: library "/home/User/tensorflowtest/app/src/main/cpp/../../../../distribution/tensorflow/lib/x86/libtensorflowLite.so" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
at java.lang.System.loadLibrary(System.java:1657)
at com.example.hellolibs.MainActivity.<clinit>(MainActivity.java:36)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1174)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2669)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
我在 android x86 模拟器和真正的 arm64-v8a android 智能手机上试过这个。
所以对我来说,这看起来就像应用程序在启动时尝试加载 tensorflowLite 共享库,但无法找到它。 使用 zip 存档管理器打开 apk 我可以验证平台(arm,x86)相关的 .so 文件是否按预期打包到 APK 中(通过将以下内容添加到 build.gradle:
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['../distribution/tensorflow/lib']
}
})
我不明白为什么它会在我将它放在我的 Ubuntu 17.10 PC 上的路径中查找库。 所以,我认为我在尝试修改前面提到的将外部库添加到 Android Studio 项目的示例时犯了一个错误。 这就是为什么我下载了整个项目并在 Android Studio 中打开它并验证该示例是否按预期工作。之后,我用 libtensorflowLite.so 替换了示例 libgperf.so 并保留了其他所有内容,尤其是 CMakeLists.txt,保持不变。 但是我再次遇到完全相同的错误,因此我怀疑这是 libtensorflowLite 库本身的问题,而不是 android 项目的问题(尽管这只是我的猜测)。
我正在开发 android studio 3.1.1、NDK 版本 14 和 API 级别 24 (Android 7.0)。 如果有人知道可能出了什么问题,我们将不胜感激任何帮助。 我也愿意接受任何其他允许我将 tensorflow lite 与 C++ 一起用于 android 应用程序的方法。
非常感谢,
马丁
【问题讨论】:
标签: android c++ tensorflow android-ndk android-studio-3.0