我正在尝试找出在 Android 上训练和部署 Tensorflow 模型的工作流程。我知道 StackOverflow 上与此类似的其他问题,但它们似乎都没有解决我遇到的问题。
在研究了 Tensorflow 存储库中的 Android 示例后,我认为工作流程应该是这样的:
- 在 Python 中构建和训练 TensorFlow 模型。
- 创建一个新图,并将所有相关节点(即不是负责训练的节点)转移到这个新图上。经过训练的权重变量作为常量导入,以便 C++ API 可以读取它们。
- 在 Java 中开发 Android GUI,使用 native 关键字来存根对 Tensorflow 模型的调用。
- 运行 javah 为 Tensorflow 本机调用生成 C/C++ 存根代码。
- 使用 Tensorflow C++ API 填写存根,以读取和访问经过训练/序列化的模型。
- 使用 Bazel 构建 Java 应用程序、原生 Tensorflow 接口(作为 .so 文件)并生成 APK。
使用 adb 部署 APK。
第6步是问题。Bazel 将愉快地编译一个本机(针对 OSX).dylib,我可以通过 JNI 从 Java 调用它。同样,Android Studio 会生成一大堆 XML 代码来制作我想要的 GUI。但是,Bazel 希望所有 java 应用程序代码都位于“WORKSPACE”顶级目录中(在 Tensorflow 存储库中),并且 Android Studio 立即从 SDK 链接到各种外部库以制作 GUI(我知道是因为我的Bazel 编译运行在找不到这些资源时失败)。我能找到强制 Bazel 交叉编译 .so 文件的唯一方法是使其成为 Android 规则的依赖规则。直接交叉编译原生库是我更喜欢将我的 AS 代码移植到 Bazel 项目的方式。
我该如何解决这个问题?Bazel 应该会编译 Android 代码,但 Android Studio 会生成 Bazel 无法编译的代码。来自 Google 的所有示例都只是为您提供了来自 repo 的代码,而没有任何关于它是如何生成的线索的。据我所知,作为 Android Studio 应用程序一部分的 XML 应该是生成的,而不是手工制作的。如果可以手工制作,我如何避免对所有这些外部库的需要?
也许我弄错了工作流程,或者我不理解 Bazel/Android Studio 的某些方面。任何帮助表示赞赏。
谢谢!
编辑:
我最终做的几件事可能有助于图书馆的成功建设:
- 我升级到最新的 Bazel。
- 我从源代码重建了 TensorFlow。
我在下面实现了推荐的 Bazel BUILD 文件,并添加了一些内容(取自 Android 示例):
cc_binary( name = "libName.so", srcs = ["org_tensorflowtest_MyActivity.cc", "org_tensorflowtest_MyActivity.h", "jni.h", "jni_md.h", ":libpthread.so"], deps = ["//tensorflow/core:android_tensorflow_lib", ], copts = [ "-std=c++11", "-mfpu=neon", "-O2", ], linkopts = ["-llog -landroid -lm"], linkstatic = 1, linkshared = 1, ) cc_binary( name = "libpthread.so", srcs = [], linkopts = ["-shared"], tags = [ "manual", "notap", ], )
我还没有验证这个库是否可以在 Android 中加载和使用;Android Studio 1.5 似乎对承认本机库的存在非常挑剔。