2018の24日目の記事です。2.0の変更点」でした。Liteまわりを重点的に取り組んでいます。Lite)は使えるのか」に書かれているように、TensorFlowのモデルをAndroid端末で動かすことに関しては「使える」レベルになってきていると筆者も思います。APIを使うように設定すると「動かない」という話をします。「使えるレベルになってきている」と、言った直後にこんなことを言ってごめんね。Liteそのものの制約に加えて、量子化済みモデルの制約。APIの制約の「3つの制約」を最大公約数的にクリアする必要がある。モデルの作成を進め、いざAndroidアプリに組み込もうとしたときに制約に引っかかると、大きな手戻りが発生したり、当初予定されていた性能が出ないなどの問題が起こる可能性がある。APIを使ったときに問題なく動作するかを確認するプロセスを設けることを強く推奨する。LiteモデルのAndroidアプリへの組み込みが増えていくに従い、Androidアプリエンジニアと機械学習エンジニアは、より緊密にコミュニケーションをしていく必要があると筆者は考えている。8.1から追加された、モバイル端末上で機械学習の計算処理を実行するためのAPIです。Core)上で実行したり、それらがない場合はCPUにオフロードしたりすることで、高速な実行が期待できます。APIは、Cで提供されています。提供されているサンプルアプリはJNIを使っています。JavaとKotlinでアプリ作ってるマンには厳しい世界です。Liteは、TensorFlowで作成した機械学習のモデルをモバイル端末や組み込みデバイスで動作させる仕組みです。2017で発表されました。LiteをAndroidアプリ開発で使うには、tensorflow-liteライブラリを使います。Changes入り)を同時リリースするという男気あふれるライブラリです。皆さんも是非使ってみてください。Mobileというライブラリも提供されていました。現在も提供されていて、メンテナンスもされているのですが、2019年のはじめにはdeprecated(非推奨)になることがアナウンスされています。Mobileを使っていたので、こちらが完全に死亡宣告を受けた感じです。足が早いものになるであろうことは承知していましたし、評判が良ければ改訂もできるので、皆さん是非買ってください。レビュー平均が1.5とか、逆に珍しいと思います。興味がわいたことでしょう。皆さん是非買ってください。Lite用にモデルを出力する必要があります。LiteではFlatBuffersが採用されています。これは、FlatBuffersはデータにアクセスする際にパースを必要とせず、メモリのフットプリント(占有容量)が小さいと言う特徴があり、モバイル端末や組み込みデバイスに適しているためです。APIが提供されています。Lite用に変換する行程になります。APIも、Windowsでは動作しませんが、UbuntuとかmacOSではちゃんと動くからなんの問題もない。APIを使って実行できます。LiteのInterpreterクラスをインスタンス化するときにOptionsオブジェクトを渡します。APIを利用する設定です。APIを利用したら、それまで普通に使えていたモデルが動かなくなったという話です。Lite(tflite)の量子化モデルに対応したコードです。このコードをベースにsetUseNNAPI(true)を設定して実行すると、モデルの初期化時にエラーになりました。1.11.0からエラーの内容がきちんと表示されるようになりました。0のTensorをサポートしていないとエラーが出ています。ランク0のTensorはスカラー型を意味します。量子化モデルの制約ここで、モデルを出力したPythonスクリプトを見てみます。255.0)を乗算しています。255.0)これは入力画像の値(0-255)を0.0-1.0に正規化する処理です。Lite形式に変換する際、パラメーターを量子化しようとすると「Divをサポートしていない」エラーが発生するためです。op).\n"量子化モデルでは単純な除算(Div)が使えません(量子化しなければ使えます)。255.0)の結果を乗算することで、255.0で除算するのと同じ結果にしています。そもそもなんで255.0で除算するのか。tf.image.per_image_standardizationという便利なものがあるだろうと思ったあなた。Liteの量子化モデルではtf.image.per_image_standardizationは使えません。op).\n"あと筆者の知るかぎりではtf.expand_dimsが使えなかったりと、普通にtflite_convertを使っていて問題なく変換できるモデルでも、量子化するときに制約に引っかかるということは珍しくありません。APIの制約スカラーをサポートしない除算をサポートしていない件については乗算に置き換えて解決しました。APIでエラーが発生します。Liteのモデルでも、同様のエラーが発生します。APIを使わなければ普通に動いてしまうということです)スカラーをサポートしていないなら、要素数1の配列として計算するように調整します。APIを使う設定で実行した結果が次の通りです。45は現状は使えないと言ったエラーになりました。45といわれても、かいもく見当が付きませんね。Liteのオペレーションは、TensorFlowのGitHubリポジトリに定義されています。これを見ると45に対応するオペレーション名がkTfLiteBuiltinStridedSliceだとわかります。前述のスクリプトにはスライス処理をしている部分がありました。:3]これは、RGBAの4chの画像のアルファチャンネルを捨てる処理です。Androidアプリ側で画像をscaledBitmapを使ってモデルの入力に適したサイズに縮小しているのですが、サイズ変更処理後にcopyPixelsToBufferでバイト列を取ると、得られるバイト列がRGBA8888となります。RGB888のデータです(最初の足はミニバッチサイズを表しています)。公式のサンプルでは、アプリ側で縦横2重のfor文と、ビットシフトを使ってRGBを取り出しています。APIの制約に対応するためにこのような処理にしているのだとわかりました。そこで、非常に不本意ではありますが、モデルに入力するデータをRGBの3チャンネルと定義して、スライスの処理を取り除きました。アプリ側でアルファチャンネルを除去するように調整しました。APIを有効にした状態でモデルが動作するようになりました。APIでは、このほかにもtf.tanhなど、重要な処理(と、筆者は考えている)をサポートしていなかったりします。APIを使わなければ動作します。評価プログラムを次に示します。小さなモデルを使っているため、ナノ秒単位で計測しています。elapsed.toString())評価結果それぞれで推論を11回実行し、初回を除いた(理由は後述)10回分の推論にかかった時間の平均を性能として表に示します。APIを使うと実行時間が大幅に短縮されるという結果になりました。(茶色いトイプーは食べ物じゃないっ!?))。API以外の選択は考えられません。2より性能が低いという結果になっていますが、実際にはそうではなく、十分な性能のGPUで小さなモデルを動かすときに性能が生かし切れないのと同様のことが起こっているのだと筆者は考えています。APIを使った場合、初回の推論に時間がかかります。PH-1で計測した生データを次に示します。APIを使う場合、モデルをロードするタイミングではなく、実際にrunするタイミングでグラフを構築していると推測できます。今後のバージョンアップなどで挙動が変わる可能性は多分にありますが、現時点では、ダミーデータなどを使って初回のrunを実行しておくことで、初回の実行時間を短縮する手法が考えられるでしょう。APIを使ったときに問題なく動作するかを確認するプロセスを設けることを強くオススメします。学習を進めて、いざ組み込もうとしたときにいずれかの制約に引っかかれば、前処理やモデルの変更などによる学習プロセスのやり直しなど、大きな手戻りが発生したり、当初予定されていた性能(実行時間)が出ないなどの問題の引き金になる可能性があります。パラメーターは初期値でいいのです。モデルの精度はひとまず問題ではありません。制約をクリアしているか、性能は十分に出るかの評価を優先しましょう。そのためには今後、Androidアプリエンジニアと機械学習エンジニアは、より緊密にコミュニケーションをしていく必要があると筆者は考えています。2018の24日目の記事です。25日目の記事は「natsutan」さんによる「GCPでTPU動かしました」です。