在Android上运行Tensorflow模型

amm*_*amm 18 android bazel tensorflow

我正在尝试找出在Android上培训和部署Tensorflow模型的工作流程.我知道在StackOverflow上有类似于这个的其他问题,但它们似乎都没有解决我遇到的问题.

在研究了Tensorflow存储库中的Android示例后,我认为这应该是工作流程:

  1. 在Python中构建和训练Tensorflow模型.
  2. 创建一个新图,并将所有相关节点(即不是负责培训的节点)传输到这个新图.训练有素的权重变量作为常量导入,以便C++ API可以读取它们.
  3. 使用Java开发Android GUI,使用native关键字来存根对Tensorflow模型的调用.
  4. 运行javah以生成Tensorflow本机调用的C/C++存根代码.
  5. 使用Tensorflow C++ API填写存根,读入并访问训练/序列化模型.
  6. 使用Bazel构建Java应用程序,本机Tensorflow接口(作为.so文件),并生成APK.
  7. 使用adb来部署APK.

    第6步是问题所在.Bazel很乐意编译一个本机(到OSX).dylib,我可以通过JNI从Java调用它.同样,Android Studio将生成一大堆XML代码,这些代码构成了我想要的GUI.但是,Bazel希望所有java应用程序代码都在'WORKSPACE'顶级目录(在Tensorflow repo中)中,并且Android Studio会立即链接到SDK中的各种外部库以生成GUI(我知道因为我的Bazel编译运行失败,因为它找不到这些资源).我可以找到迫使Bazel交叉编译.so文件的唯一方法是使其成为Android规则的依赖规则.直接交叉编译本机库是我更喜欢将我的AS代码移植到Bazel项目的.

    我该怎么做?据说Bazel会编译Android代码,但Android Studio会生成Bazel无法编译的代码.来自Google的所有示例都只是从回购中提供代码,而不知道它是如何生成的.据我所知,Android Studio应用程序中的XML应该是生成的,而不是手工制作的.如果可以手工制作,我如何避免需要所有这些外部库?

    也许我的工作流程出错了,或者Bazel/Android Studio的某些方面我不理解.任何帮助赞赏.

谢谢!

编辑:

我最终做了几件事可能有助于图书馆建设成功:

  1. 我升级到了最新的Bazel.
  2. 我从源头重建了TensorFlow.
  3. 我在下面实现了推荐的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",
         ],
    )
    
    Run Code Online (Sandbox Code Playgroud)

我还没有验证这个库可以在Android中加载和使用; 关于承认本机库的存在,Android Studio 1.5似乎非常挑剔.

Ulf*_*ams 10

在您的WORKSPACE文件中设置Android NDK之后,Bazel可以交叉编译Android的.so,如下所示:

cc_binary(
    name = "libfoo.so",
    srcs = ["foo.cc"],
    deps = [":bar"],
    linkstatic = 1,
    linkshared = 1,
)

$ bazel build foo:libfoo.so \
    --crosstool_top=//external:android/crosstool --cpu=armeabi-v7a \
    --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
$ file bazel-bin/foo/libfoo.so
bazel-bin/foo/libfoo.so: ELF 32-bit LSB  shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), not stripped
Run Code Online (Sandbox Code Playgroud)

Bazel希望所有java应用程序代码都在'WORKSPACE'顶级目录中(在Tensorflow repo中)

当0.1.4发布(现在推送)并且我们已经将一些修复推送到TensorFlow和Protobuf时,您可以开始使用TensorFlow存储库作为远程存储库.在WORKSPACE文件中进行设置后,可以使用@tensorflow//foo/bar标签引用TensorFlow规则.