タイトルは論文っぽく書いていますが、要はTensorFlowのページにAndroid / iOS で動かせるぜーとあったのでどんなものかやってみた、という話です。
やってみると、確かにAndroid、iOS両方でビルドすることができたので、その手順などを書きたいと思います。
Android
まずはAndroid版から。
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/examples/android
基本的にはこちらに従います。ビルドできると、GoogleのInceptionモデルを使ったTF Classify, Scalable Object Detection using Deep Neural Networks をベースにしたTF Detectが作られます。
さらににスタイル変換するTF Stylizeまで実装されていたらしい…ので改めて以下の環境でビルドし直してみました。
- Android Studio 2.2.3
- Android 6.0.1 (Xperia Z3)
TensorFlowのビルド
まずは最新版をクローンしてきます。いまTensorFlowはr0.12だったような。
git clone --recurse-submodules https://github.com/tensorflow/tensorflow.git
次にビルドツールbazelをインストールします。
brew install bazel
C/C++コードをコンパイルするためにNDKが必要です。
https://developer.android.com/ndk/guides/index.html
によると、Preferencesからsdkで検索して SDK Tools
タブを開きます。ここで
- CMake
- LLDB
- NDK
にチェックを入れてApplyすればインストールできます。SDKについてはとなりの SDK Platforms
からインストールできて、Android 5.0以上はすべてインストールしておきました。
続いて、 /tensorflow/WORKSPACE
ファイルを編集します。コメントアウトされている部分を自分の設定に直します。
Uncomment and update the paths in these entries to build the Android demo.
-#android_sdk_repository(
-# name = "androidsdk",
-# api_level = 23,
-# build_tools_version = "23.0.1",
-# # Replace with path to Android SDK on your system
-# path = "<PATH_TO_SDK>",
-#)
-#
-#android_ndk_repository(
-# name="androidndk",
-# path="<PATH_TO_NDK>",
-# api_level=21)
+android_sdk_repository(
+ name = "androidsdk",
+ api_level = 25,
+ build_tools_version = "25.0.2",
+ # Replace with path to Android SDK on your system
+ path = "/Users/user-name/Library/Android/sdk/",
+)
+
+android_ndk_repository(
+ name="androidndk",
+ path="/Users/user-name/Library/Android/sdk/ndk-bundle/",
+ api_level=21)
以下でTensorFlowの学習モデルを落として適切な場所に配置します。モデルはassetsディレクトリに置けばよいことがわかります。学習モデルであるグラフ: tensorflow_inception_graph.pb
は53.9MBでした。またdetectionのモデルグラフ: multibox_model.pb
は18.6MBのようです。
$ curl -L https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip -o /tmp/inception5h.zip
$ curl -L https://storage.googleapis.com/download.tensorflow.org/models/mobile_multibox_v1.zip -o /tmp/mobile_multibox_v1.zip
$ unzip /tmp/inception5h.zip -d tensorflow/examples/android/assets/
$ unzip /tmp/mobile_multibox_v1.zip -d tensorflow/examples/android/assets/
これでビルドする準備が整ったのでルートディレクトリ(WORKSPACEが置いてあるところ)でbazel buildします。
$ bazel build -c opt //tensorflow/examples/android:tensorflow_demo
20分くらいかかるので、エスプレッソでも抽出してましょう。無事通ったら、実際に端末にインストールして動かしてみます。
$ adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk
以下のようなエラーがさっき出たらupdateしろとのことなので、従うとちゃんとビルドできました。
$ adb install -r bazel-bin/tensorflow/examples/android/tensorflow_demo.apk
It appears you do not have 'Android SDK Platform-tools' installed.
Use the 'android' tool to install them:
android update sdk --no-ui --filter 'platform-tools'
先週は割にぬるぬる動いた印象だったのにビルドし直したらちょいと重くなったような印象が…気のせいかもしれませんが。Scalable Object Detectionのアプリケーションもインストールされているはずです。そしてスタイル変換はとてもよくできていて、画面下に絵画のサンプルがあって、それをどのくらいスタイルとして用いるかを選べるUIになっていました。解像度が32〜1024まで選べるようになっていて、さすがに192くらいからはリアルタイムではまわりませんが、画像生成できていました。
ソースコードのコミットを見ると、わずか1週間の間で StylizeActivity.java
と TensorFlowYoloDetector.java
が増えていた…びっくり。
iOS
続いてiOSです。基本的には
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/ios_examples
にある TensorFlow iOS Examples
に従います。Xcode 7.3以降が必要とあって、iOSをあげてしまっていたのもあってXcodeをアップデートして、以下の環境でビルドできました。
- Xcode 8.2.1
- iOS 10.1.1 (iPhone SE)
TensorFlowのビルド
まずは
https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/makefile
のiOSの項に従ってTensorFlowをビルドせよとあるのでやります。
xcode-select --install
brew install automake
brew install libtool
をインストール。次のシェルで1発でビルドできるようです。
tensorflow/contrib/makefile/build_all_ios.sh
これによって tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a
が生成されるようです。これをXcode Projectでリンクしてあげればよいらしい。20分近くかかるのでコーヒーでも淹れましょう。このシェルではなく1つ1つ生成しようとすると、まずはdependenciesをダウンロード。
tensorflow/contrib/makefile/download_dependencies.sh
次に、iOS向けにprotobufをコンパイル。
tensorflow/contrib/makefile/compile_ios_protobuf.sh
そしてiOSをターゲットにmake。
make -f tensorflow/contrib/makefile/Makefile \
TARGET=IOS \
IOS_ARCH=ARM64
Inceptionモデルのダウンロードとプロジェクトの実行
TensorFlowディレクトリのルートで、以下を実行するか、リンクからInception v1のモデルをダウンロードして解凍します。
mkdir -p ~/graphs
curl -o ~/graphs/inception5h.zip \
https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip \
&& unzip ~/graphs/inception5h.zip -d ~/graphs/inception5h
cp ~/graphs/inception5h/* tensorflow/contrib/ios_examples/benchmark/data/
cp ~/graphs/inception5h/* tensorflow/contrib/ios_examples/camera/data/
cp ~/graphs/inception5h/* tensorflow/contrib/ios_examples/simple/data/
これを見ると、アプリのサンプルは benchmark
, camera
, simple
の3つあることがわかります。画像認識をするのはもちろん camera
です。inceptionのモデルはそれぞれのアプリのdataディレクトリ配下に置けばよさそうです。これが終わったら、あとはディレクトリの中にあるcamera_example.xcodeprojファイルを開いてrunするだけです。
Android版とはちがって、画面下に画像取得を止められる機能がついていました。手持ちのiPhone SEでぬるぬる動きます。
http://qiita.com/shu223/items/ce190ea6669b2636a8a7
の記事によると、iPhone6で数秒の遅延があるということだったので、モデル自体がそのときと比べて小さくなったのか、記事で言及されているGPU Acceleratedをサポートしたのか、iOS 10 で Accelerate.framework に追加された BNNSが実装されたのか(issueがcloseしてないのでまだっぽい…)
逆に実装されてなくてこの速さなら、iPhone 6s以降であればもっとfpsをあげられなくもなさそう。
まとめ
TensorFlowの学習モデルをモバイルで動かすサンプルをビルドしてみました。Android/iOSどちらでも結構ぬるぬる動いていて、どれくらい重たいモデルまでいけるのかが気になるところ。