iOS
DeepLearning
人工知能
Swift
TensorFlow

TensorFlowの学習済みモデルを拾ってきてiOSで利用する

More than 1 year has passed since last update.

iOS 10でニューラルネットワークAPIのBNNS (Basic neural network subroutines) がAccelerateフレームワークに追加されたり、TensorFlowのiOSサポートが追加されたり、Prismaがオフライン対応したりと、なんとなくあらかじめ学習させておいたモデルを使って計算するぐらいのことはiOSデバイス側でやらせてもいいんじゃないか、という空気感も出てきたような気がしてます。1

・・・いや、そんな大層な理由ではなくて、機械学習/ディープラーニングについて無知な自分が、学習用に大量のデータを集めて、Pythonスクリプトを書いて自前モデルを作成するのは一段ハードルが高いように思えてしまいます。

というわけで、先日書いた『TensorFlowにiOSサポートが追加されたそうなので試してみた』の次のステップとして、GitHubとかに落ちている学習済みモデルを拾ってきてTensorFlow/iOSで動かすということを試してみました。

IMG_0003_r1_c1.jpg

(今回の成果の一例)

事例1: 花を識別するモデル

GitHubで "Tensorflow iOS Models" という気になる名前のリポジトリを見つけました。

Tensorflow iOSで使えるモデルのまとめリポジトリにしたい、というコンセプトのようですが、2016年8月23日現在、置いてあるのは "Flowers" というモデル1つだけ 2 です。

サンプルもなかったので、これをTensorFlowの公式リポジトリの ios_examples 配下にあるsimpleサンプルで使えるようにしてみました。

ソースの変更点

simpleサンプルでFlowersモデルを利用するにあたってコードを書き換えた点は以下。全部 RunModelViewController の変更です。

  • モデルのファイル名
NSString* network_path = FilePathForResourceName(@"tensorflow_flower_graph", @"pb");
  • ラベルのファイル名
NSString* labels_path = FilePathForResourceName(@"flowers_comp_graph_label_strings", @"txt");
  • テスト画像のファイル名
NSString* image_path = FilePathForResourceName(@"flowers", @"png");
  • tensorflow::Tensor 作成時に利用する画像サイズやピクセル値再計算用のパラメータ
const int wanted_width = 299;
const int wanted_height = 299;
const int wanted_channels = 3;
const float input_mean = 128.0f;
const float input_std = 128.0f;
  • session->Run の引数に渡す入力・出力ノードの名前
std::string input_layer = "Mul";
std::string output_layer = "final_result";

ちなみにもちろん、モデルファイル(.pb)、ラベルファイル(.txt)、テスト画像への参照をプロジェクトに追加する必要はあります。

実行結果

こういう画像を入力して、

flowers.png

認識結果はこう出ました。

0.994 sunflowers

当たってますね!

事例2: YOLOモデル

YOLOというのは"You only look once"の略みたいです。

これは Pascal VOC 2012 データセットに対して物体認識を行う手法で、20種類(クラス)のオブジェクトを分類可能だそうです。

  • person
  • bird, cat, cow, dog, horse, sheep
  • aeroplane, bicycle, boat, bus, car, motorbike, train
  • bottle, chair, dining table, potted plant, sofa, tv/monitor

で、この学習済みモデルが公開されていて、それをTensorFlowで使えるようにした人がいて、それをさらに別の人がiOSで使えるようにしたのが下記リポジトリ。

YOLOモデルの .pb ファイルを作成して、これをTensorFlowの公式リポジトリの ios_examples 配下にあるcameraサンプルで使えるようにした、というのがこのリポジトリです。

もうiOSで動くサンプルが用意されてるのでここでは利用方法については書きませんが、使ってみたところ、メモリの使用量がエグいです。メモリ要2GB、つまり現行機種では iPhone 6s or 6s Plusでのみ動作します。3

ちゃんとREADMEにもその旨が書いてあります。

Despite I have already use YOLO tiny model, at runtime it still require at lease 850M memory, so only iPhone 6s or later which get at lease 2GB of memory can make it running, otherwise it will be killed immediately when loading the model.

実行結果

Google画像検索で適当に牛とか馬とか犬とか猫を表示してモニタにカメラをかざしてリアルタイム認識させてみました。以下その結果です。

IMG_0003_r1_c1.jpg

(cow 0.44)

IMG_0004_r1_c1.jpg

(horse 0.26)

IMG_0006_r1_c1.jpg

(dog 0.24 / cat 0.28)

事例3: 手書き数字を識別するモデル

学習済みモデルをAndroidで実行するという記事がありまして、

ディープラーニングを利用した手書き数字認識のモデルを Protobuf (Protocol Buffers) 形式で作成して、その .pb ファイルごとGitHubにアップされていました。

冒頭のFlowersモデル同様、simpleサンプルに組み込み、

NSString* network_path = FilePathForResourceName(@"expert-graph", @"pb");
const int wanted_width = 28;
const int wanted_height = 28;
const int wanted_channels = 1;
std::string input_layer = "input";
std::string output_layer = "output";

試しにMNISTのテストデータから持ってきたこういう画像を与えてみると、

結果はこう出ました。

Prediction: 5

ちゃんと動いてそうです。

TensorFlowを用いないアプローチ - TensorSwift

本記事のタイトルを見て、koherさんのこの記事を思い浮かべた方も多いかもしれません。

やりたいことは同じなのですが、上記記事は、TensorFlowのiOSサポートの入った0.9.0がリリースされるよりも前に書かれた記事であり、iOS側ではTensorFlowを使っていない、というのが大きく違う点です。TensorFlowで学習させたモデルを読み込み、Swiftで書かれた TensorSwift という独自ライブラリでテンソルの計算を行う、というものです。

本家TensorFlow(のiOSサポート版)を用いることと比較して、TensorSwiftのアプローチは以下の点がメリットかと思います。

  • Swiftで書かれている
  • 軽量である
  • BLAS(Accelerate.frameworkに入っている線形代数ライブラリ)を利用した高速化がなされている

逆に、以下の点はデメリットになりそうです。

  • できることが限られている

現状ではまだα版くらいの完成度なので TensorFlow の API のごく一部しか再現できておらず、 Deep MNIST for Experts の畳み込みニューラルネットワークが再現できるくらいの段階

  • 独自の方法で書き出したモデルデータを利用する

本当は TensorFlow で書きだした Checkpoint ファイルを読み込めればいいのですが今のところそのような機能はありません。

まとめと今後の展望

今回は基本的に「iOSで使えますよ」と明示して公開されている学習済みモデルを利用させていただいたわけですが、実は結構ググったりGitHub検索したにもかかわらず、そういうものはなかなか見つかりませんでした。

ただ、

  • フォーマットの違う(っぽい)TensorFlow用モデルが公開されている
  • 学習済みモデルは置いていないが、学習データと学習スクリプトが公開されている

というケースは多々あったので、もうちょっとちゃんとモデルについて理解して、自分でiOSでも利用可能な形で書き出すなり、学習させるなりすることができれば、できることも広がりそうです。

そんなわけで次のステップとしては、「TensorFlow iOSで使えるモデルを作成する」ということを色々参照しつつやってみたいと思っています。

追記

TensorFlow for iOS でモデルをどのように利用しているか、コードを追ってみて記事を書きました。


  1. 全部サーバー側で計算してると、ユーザーが増えればそれだけサーバー負荷も上がりますし。。 

  2. モデルの種類を増やしていって欲しいところですが、モデルファイルは一般的にサイズが大きく、GitHubでその他ソースを公開しているプロジェクトでも、モデルファイルは別のところに置いてあって別途ダウンロードするようになっているケースも多いので、今後もそんなに集まることは期待できないかもしれませんね。。 

  3. iPhone 6でも試してみましたが、メモリが足りず実行時に100%クラッシュしました。。