Я пытаюсь выяснить рабочий процесс для обучения и развертывания модели Tensorflow на Android. Я знаю другие вопросы, подобные этому в StackOverflow, но ни один из них, похоже, не справляется с проблемами, с которыми я столкнулся.
Изучив пример Android из репозитория Tensorflow, я думаю, что рабочий процесс должен быть:
- Создайте и подготовьте модель Tensorflow в Python.
- Создайте новый график и переместите все соответствующие узлы (т.е. не узлы, ответственные за обучение) на этот новый график. Измененные переменные весов импортируются как константы, поэтому С++ API может их читать.
- Разработать графический интерфейс Android на Java, используя ключевое слово native, чтобы отключить вызов модели Tensorflow.
- Запустите javah, чтобы сгенерировать код заглушки C/С++ для родного вызова Tensorflow.
- Заполните заглушку, используя API Tensorflow С++ для чтения и доступа к обученной/сериализованной модели.
- Используйте Bazel для создания BOTH приложения Java, собственного интерфейса Tensorflow (как .so файл) и создания APK.
-
Используйте adb для развертывания APK.
Этап 6 - проблема. Bazel с радостью скомпилирует родной (OSX).dylib, который я могу вызывать из Java через JNI. Android Studio также будет генерировать целую кучу XML-кода, который сделает GUI, который я хочу. Тем не менее, Bazel хочет, чтобы весь код приложения java находился в директории верхнего уровня WORKSPACE (в репозитории Tensorflow), а Android Studio сразу же ссылается во всех видах внешних библиотек из SDK для создания GUI (я знаю, потому что мой Сбой компиляции Bazel не удается, если он не может найти эти ресурсы). Единственный способ, которым я могу найти, чтобы заставить Bazel перекрестно скомпилировать файл .so, делает его зависимым от правила Android. Непосредственная кросс-компиляция родного lib - это то, что я предпочел бы портировать мой A.S. кода в проект Bazel.
Как это сделать? Bazel предположительно компилирует код Android, но Android Studio генерирует код, который Bazel не может скомпилировать. Все примеры из Google просто дают вам код из репо без каких-либо подсказок о том, как он был сгенерирован. Насколько я знаю, XML, часть приложения Android Studio должна быть сгенерирована, а не сделана вручную. Если это можно сделать вручную, как мне избежать необходимости во всех этих внешних библиотеках?
Возможно, я ошибаюсь в работе, или есть какой-то аспект Bazel/Android Studio, который я не понимаю. Любая помощь оценивается.
Спасибо!
Edit:
Было несколько вещей, которые я закончил делать, которые могли бы успешно способствовать созданию библиотеки:
- Я обновился до последней версии 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, по-видимому, очень тонко заявляет о наличии родных libs.