Androidで始める機械学習(TensorFlow Lite, ML Kit)

みなさんAndroidで機械学習やってますか？
[Android 11 Meetups(GDG)](https://developersonair.withgoogle.com/events/a11meetups-jp)に参加し、私はつい最近入門しました。

Android 11 Meetupsで学んだ内容と、自分で調べた内容を元に、Androidでの機械学習を使った機能を実装するにはどうすればいいか、まとめてみました。

# クライアント側で機械学習

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96747/530aa70a-5855-8e34-6771-d34bfb6e553c.png)

まずそもそもですが、図のようにサーバ側で推論や学習を行うか、クライアントで推論や学習[^1]を行うかの違いで、それぞれ特徴があり、要件を考慮して決める必要があります。他にもいろいろあると思いますが、以下のようなことが考えられるでしょう。

- クライアント
    - リアルタイムに処理したい
    - データをサーバにあげたくない
    - ネットワークに繋げられない
- サーバ
    - マシンパワーが必要
    - 常に最新のモデルを使う必要がある
    - 学習済みモデルを守りたい
 
図はスマホ端末っぽいものしか記載されていませんが、もちろん車やIoT機器でも同様でしょう。
「エッジAI」だったり、「エッジ機械学習」、「オンデバイス」といったワードで耳にしたりします。

# エッジで機械学習させるためのフレームワーク

エッジで機械学習する上で、どんな選択肢があるのかですが、主にTensorFlow Liteと、MLKitがあります。（ちまたにはPytorch mobileや、AppleだとCoreMLなどがあるらしい）

## TensorFlow Lite

[TensorFlow Lite](https://www.tensorflow.org/lite)は、モバイル端末上で推論するためのフレームワークです。
TensorFlowで作ったモデルをTensorFlow Liteのモデルに変換できます。
モデルの作り方は、後述する他の方法でも作成することができます。
Android, iOS, IoTデバイスで利用することができます。

利用するモデルによっては、推論時にGPUやTPUなどを利用できます。(MLKitだとできない)
既に学習済みのモデルも[TensorFlow Hubで公開](https://tfhub.dev/s?deployment-format=lite)されています。

## MLKit

[ML Kit](https://developers.google.com/ml-kit)は、よくある機械学習のユースケースと学習済みモデルをラップして、使いやすくしたものです。
下はTensorFlowLiteが使われています。
こちらは、Android, iOSで利用可能です。

以前はML Kit for Firebaseとして、Firebaseのサービスの中にありましたが、6月にFirebaseから分離し、on-deivice向けに変更（ベータ版）されました。

https://developers.google.com/ml-kit/guides

> ML Kit's on-device APIs are now available as a standalone SDK. Learn more about this change in our migration guide. Cloud APIs, AutoML Vision Edge, and custom model deployment are still available via Firebase Machine Learning.

FirebaseとMLKitは、以下のような住み分けになったようです。

- Firebase ML
    - CloudAPI(text recognition, image labeling, landmark recognition)
    - Auto ML Vision Edge
    - manage custom model deployment
- ML Kit
    - on-deivce API

現在、ML Kitで提供されているAPIは以下になります。

- Barcode scanning
- Face detection
- Image labeling
- Object detection and tracking
- Text recognition [^2]
- Language ID
- On-device translation
- Smart Reply

また、MLKitでは、利用するモデルはラップされていますが、image labeling、object detectionだけ、カスタムモデルを利用できるようです。

# 作ってみた

実際どうやねんということで、実機で試してみることにしました。

## TensorFlow Lite

以下のAndroid11 MeetUpsの動画の通りに作成しました。
[Build an Android app to recognize flowers(YouTube)](https://www.youtube.com/watch?v=s_XOVkjXQbU&list=PLWz5rJ2EKKc9znUgvI7lFPE-v5Vw4mGwG&index=4)

TensorFlow Lite Model Makerを利用して、花を分類するモデルを作成し、AndroidStudio4.1(プレビュー)のプラグインを利用して、AndroidアプリにTensorFlow Liteのモデルを組み込みました。

TensorFlow Lite Model Makerは、転移学習を用いて、TensorFlow Liteのモデルを作成できるライブラリです。
思ったよりも少ない画像[^3]で、短時間でモデルを作成することができます。精度も結構良く、作りたいモデルによっては十分使えそうな印象でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96747/2dd3b05c-9b6e-86de-8264-31afc630aea4.png)

## ML Kit

ML KitはFace Detectionを試しました。
[ガイド](https://developers.google.com/ml-kit/vision/face-detection/android)を見ればこれぐらいは簡単に実装できます。

CameraXとともに実装しましたが、取得した画像をMLKitに渡すだけです。顔の検出、トラッキングだけであれば驚くほど簡単に実装できます。むしろCameraXの実装（プレビューや検出した顔のOverlay）の方が時間がかかりました。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96747/bd6906f7-137f-8cd5-e067-22c2b326f9a5.gif)

複数の顔も同時に検出できたり、顔のランドマーク（目や口、鼻など）の検出もできるので、そちらも試して見ると面白そうです。

# TensorFlow Lite or MLKit?

どちらを使うかですが、まずはMLKitを試して、要件を見たさないならTensorFlow Liteを検討するのが良さそうです。
TensorFlow Liteの方がより柔軟ですが、想定するユースケースを十分満たすのであれば、ML Kitの方が面倒を見ることが少ないです。

# TensorFlow Liteのモデルを作るには？

3つ選択肢があります。後者はより蔵人向けかと。

- AutoML Vision Edge
  - GUI操作(ノンプログラミング)で、ラベル付されたイメージのアップロードするだけで、モデルが作れる。
- TensorFlow Lite Model Maker
  - 転移学習を用いて、on-device向けにモデルを作成できるライブラリ。
- TensorFlowでモデルを作り、TensorFlow Liteに変換

# まとめ

利用する用途によっては、手の込んだモデルを作ったり、自作するより、これで十分なんじゃないかという印象でした。
より難易度が高いことをするにしても、まずはプロトタイプとして利用するのにも有用だと思います。

# 参考

- [Android 11 Meetups(GDG)](https://developersonair.withgoogle.com/events/a11meetups-jp)
- [ML Kit](https://developers.google.com/ml-kit)
- [TensorFlow Lite](https://www.tensorflow.org/lite)

[^1]: クライアント側で学習することがあるのかですが、実際はマシンパワーなどが必要になったりするようで、ユースケースは限定的になるようです。
[^2]: 現在英語のみ。日本語を対象にする場合は、CloudAPIを利用する必要があります。
[^3]: このサンプルで用意されている画像は、1つのラベルで500枚を超えています。主観で思ったよりも少ないと思っただけです。