TensorFlowは、Googleが公開しているモバイルや、サーバなどデバイスを問わずどんな環境でもディープラーニングを動作させることができるライブラリです。
iOSアプリで識別することも、バージョン0.9.0からサポートされました。
本記事では、TensorFlowやiPhoneアプリ開発にそれほど馴染みのない方でも簡単にXcodeプロジェクトからTensorFlowのモデルを実行できるようになるまでを解説します。
TensorFlowをiOSで動作させるために必要なもの
TensorFlowをiOSプロジェクトで動作するには、以下のライブラリやソフトウェアが必要になります。
- Xcode7.3以上
- XcodeのCommand Line Tools
automake
,libtool
Xcodeは、iTunesストアからダウンロードしてください。 また、XcodeのCommand Line Toolsは以下のコマンドをターミナルから入力するとインストールすることができます。
automake
とlibtool
は、Homebrew経由でインストールできます。以下のコマンドでインストールします。
TensorFlowのレポジトリからライブラリをビルド
iOSプロジェクトを作成する前に、導入に必要なライブラリをビルドする必要があります。 TensorFlowレポジトリに、ライブラリをビルドするために必要なスクリプトが入っているので、まずは以下のコマンドでTensorFlowのソースコードをダウンロードします。
クローンできたら、スクリプトのあるディレクトリに移動してユニバーサルライブラリをビルドします。
このビルドにはMacbook Proで10~20分くらいかかる場合があります。正常に終了していれば、ビルド成功です。
ここで発生しがちなエラー
/usr/local/Library/ENV/4.3/sed: No such file or directory
というエラー
libtool
を再インストールする必要があります。Homebrewで再インストールしてビルドし直します。
configure: error: C compiler cannot create executables
というエラー
コンパイラのgcc
がシステムのgcc
ではなく、Homebrew経由でインストールしたgcc
となっている可能性があります。
まずは、Makefileのgccのパスを変更します。./tensorflow/contrib/makefile/Makefile
をテキストエディタで開いてHOST_CXX :=
の後にあるgcc
を/usr/bin/gcc
としましょう。
また、以下のように、コマンドの前にCC=/usr/bin/gcc
を付けることでシステムのコンパイラを使ってprotobufなど他の設定もしてくれるようになります。
これでも駄目だった場合は、
./tensorflow/contrib/makefile/Makefile
のコンパイラの設定部分をgcc
から/usr/bin/gcc
として実行してみてください。
まずはサンプルを動かしてみる
ここで、サンプルが動作するか一度確認してみます。Inception-v1のモデルファイルをダウンロードして、iOSから実行するサンプルを試します。
Xcodeのプロジェクトファイルを開きます。simpleディレクトリにあるtf_ios_makefile_example.xcodeprojファイルをダブルクリックして開くか、以下のコマンドでプロジェクトファイルをXcodeで読み込んで開くことができます。
以下のように、Xcodeが立ち上がったかと思います。左上のRunボタンを押して実行できるかを確認します。
シミュレーターが立ち上がって以下の画像のようなスクリーンになります。上部にあるRun Modelというボタンをタップすると、Inception-v1モデルが読み込まれて画像ファイルが何なのかを予測します。
予測結果は、ボタンの下部にあるデバッグログに出力されているはずです。
モデルファイルが読み込まれたことと、0.51 military uniform、0.1 motorboardというログが出力されたようです。どういう意味でしょうか。実は、このアプリはこちらの画像が何なのかを予測させた結果です。
military uniformとは、日本語で「軍服」という意味です。この写真は、51%の確率で軍服だと判断されたということです。確かに軍服を着ていますね!
他にもカメラアプリなどがサンプルとして用意されているので、試してみると面白いでしょう。
Xcodeでプロジェクトセットアップ
新規や既存のプロジェクトでTensorFlowを使用するXcodeの設定はどうすればいいのでしょうか。ここではiOSプロジェクトを構築する場合に必要な設定を1からプロジェクトを作成しながら解説します。
プロジェクトの作成
まずはプロジェクトを作成します。メニューバーのFile → New → Projectを選択します。
以下のようなダイアログが出てくるので、Single View Applicationを選択してNextボタンを押します。
TensorFlowのライブラリはObjective-C++のインターフェースから操作するようになっています。 今回はLanguageにはObjective-Cを選択して進みます。プロジェクトの設定次第ではSwiftでプロジェクトを作ってObjective-C++のコードを読み込むこともできます。
ここで、ディレクトリはTensorFlowのレポジトリをクローンしたディレクトリに作成しておくと良いでしょう。チームで共同開発するときに、パスの設定を共有したいからです。
これでプロジェクトの作成は完成です。以下のようにXcodeのプロジェクトが開かれたはずです。
Build Phasesにライブラリの追加
上部のタブにBuild Phasesという箇所があるので、クリックします。
すると、以下の画像のように「Link Binary with Libraries」という箇所があるので、下の+をクリックして以下のライブラリを追加してください。
- libstdc++.tbd
- Acceralate.framework
tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a
tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf.a
tensorflow/contrib/makefile/gen/protobuf_ios/lib/libprotobuf-lite.a
Library Search Pathsにライブラリパスの追加
ライブラリを追加したら、ビルドに必要なので先程追加したライブラリがあるLibrary Search Pathsにパスを追加します。
Library Search Pathsは、上部タブのBuild Settingsをクリックして、検索ボックスにSearch Pathsと入力すると簡単に探すことができます。下の画像のように、左から二列目の部分をクリックすると、追加する画面が出てくるので、左下の+ボタンを押して追加していきます。
追加するライブラリのパスは以下の2つです。TensorFlowのレポジトリのパスが一階層下であることを前提としています。違うパスを利用する場合には、適宜読み替えてください。
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/gen/lib
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/gen/protobuf_ios/lib
Header Search Pathsにパスの追加
Header Search Pathsにヘッダファイルのあるディレクトリを追加していきます。Header Search Pathsは、Library Search Pathsの1つ上の行にあります。
追加するパスは以下の5つです。
$(SRCROOT)/../tensorflow
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/downloads/protobuf/src
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/downloads
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/downloads/eigen
$(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/gen/proto
Other Linker Flagsにオプションの追加
Other Linker Flagsに、オプションを追加します。検索ボックスに「Linking」と入力するとすぐに見つかるはずです。Linkingの中に、Other Linker Flagsがあるので下の画像の位置をクリックして、+ボタンを押して以下のオプションを追加してください。
-force_load $(SRCROOT)/../tensorflow/tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a
C++11をサポートするビルドの設定の確認
C++11に対応するビルドの設定をします。デフォルトでプロジェクトを作成していれば問題ないはずですが、既存のプロジェクトに追加する場合には気をつけてください。
Apple LLVM 8.0 - Language - C++というセクションの下に、C++ Language Dialectという行があるはずです。ここがGNU++11または、GNU++14となっていれば問題ありません。
その下にあるC++ Standard Libraryという行は、libc++としておきます。
BitcodeをNOに変更
最後に、TensorFlowはまだBitcodeをサポートしていないので、Enable BitcodeをNOに変更しておきます。
これでプロジェクトの設定は終了です。
モデルファイルの読み込みと推論
グラフファイルの書き出し
TensorFlowで学習したモデルをスマホなどの端末側で利用する場合は、Pythonからよく使われるチェックポイントではなくてProtocol Buffer形式の学習済みグラフを書き出して使う必要があります。
Protocul Buffer形式の学習グラフの作り方は、
(1) 出力のノードに名前を付けて学習させる
(2) ノードの名前を使って以下のようなコードでグラフを出力する
で書き出すことができます。詳しくはTensorFlowのドキュメントを参考にしてください。
iPhone側からの呼び出し
iPhone側からは、Protocol Buffer形式のモデルファイルを読み込んで、識別することになります。
基本的には、Objective-C++を使ってTensorFlowのC++APIを通して操作する形になります。Objective-Cの拡張子を.m
から.mm
とすればObjective-CとC++を共存させることができるようになります。
使い方はサンプルプロジェクトを参考にすると分かりやすいです。
ポイントは、
(1) tensorflow::NewSession(options, &session_pointer)
とsession->Create(graph)
でSessionを作成する
(2) PortableReadFileToProto(file_name, proto)
でグラフファイルとの通信
(3) session->Run
で、出力を取得する
という順で実装することでiOSからでもTensorFlowのモデルを使った機械学習の実装ができます。
まとめ
TensorFlowをiOSに載せる方法を紹介しました。
TensorFlowは、Pythonを使ったサーバ側で実行する方式だけでなく、AndroidやiOSなどのクライアント側でも実行することができるようになりました!
モバイルアプリで機械学習を使ったサービスを提供する際には是非、試してみてください。