【実践編】自分のスマホに画像認識AIを実装する方法

デプロイ

こんにちは、ガロガロニーです!

機械学習を実用化するための重要な要素のひとつに、推論を実行する環境があります。Web サービスであればクラウド上で実行することも可能ですが、ネットワーク帯域、リアルタイム性、セキュリティなどの問題で、デバイス側で推論することがあります。例えば、スマホではカメラやテキスト入力、音声入力などで、このようなエッジAI技術 が活用されています。

一方で、限られた計算リソースの中で、Deep Learningなどの演算負荷の高い処理を行うためには、いくつか工夫が必要となります。例えば以下のようなものがあります。

  • 軽くて精度の良い画像認識AIモデルの使用(ex. MobileNet)
  • パラメータのビット幅を削減するなどのモデル圧縮技術の適用(ex. 量子化処理)
  • エッジデバイス上で、軽量かつ高速に推論できるランタイムの使用(ex. TensorFlow Lite

上記のような処理は複雑で実装の難易度も高いと思います。そこで、今回はTensorFlow Liteという推論ランタイムを使用して、私が所有しているAndroidスマホ上に画像認識AIを実装してみました。実装手順と評価結果についてまとめたので、ぜひ参考になればと思います。

準備物

用意するものはハードウェアとソフトウェアで以下の通りです。

ハードウェア

  • Androidスマホ(Android One X2)
    • CPU:Snapdragon™ 630 2.2 GHz (Quad) + 1.8 GHz (Quad)
    • ROM:64GB
    • RAM:4GB
    • Androidバージョン:8.0.0
  • ホストPC(OS:Windows 10)
  • USB 2.0 TYPE-C 充電ケーブル

ソフトウェア

  • Android Studio 3.5.3
  • VMware(OS:Ubuntu18.04)
  • TensorFlow 1.12.0
  • Bazel 0.15.0
  • Python 3.6

画像認識AIモデル

モバイルアプリケーション向けに作られたMobileNetを中心に検証しました。MobileNetは非常に軽量で精度の良いモデルで、今回のような計算リソースの限られた環境でも、リアルタイムで動作させることができます。MobileNetの詳しい内容については、また別記事で紹介したいと思います。

種類 入力サイズ モデル 形式
画像分類 224×224×3 MobileNetV1 float(32bit)
int(8bit)
MobileNetV2 float(32bit)
int(8bit)
オブジェクト検出 300×300×3 MobileNetV1+SSD int(8bit)
MobileNetV2+SSD int(8bit)

推論ランタイム

スマホ上で推論を効率的に行うため、TensorFlow Liteを使用します。 TensorFlow Liteはモバイル端末上で、軽量かつ高速に推論できるように最適化されたTensorFlow用のランタイムです。TensorFlow Liteの実装アーキテクチャは以下のようなイメージとなります。

  1. TensorFlowで学習済モデル(*.pb)を入手または作成します。
  2. Converterで、TensorFlow Liteモデル(*.tflite)に変換します。
  3. 2.の際に、8bit量子化処理とConvolution処理とBatchNormalization処理の最適化を行います。
  4. Androidアプリケーション上で実行します。今回はJava APIを使用します。

実行手順

画像分類とオブジェクト検出の実装手順について、それぞれ下記にまとめました。

画像分類

  1. GithubからTensorFlow Examplesのソースコードを取得します。
    TensorFlow Examplesのソースコード入手先
  2. ホストPC上でAndroid Studioを起動後、「Open an existing Android Studio project」を押下し、「examples/lite/examples/image_classification/android」を選択します。
  3. 以下のURLから、「MobileNetV1・V2」のTensorFlow Liteモデル(*.tflite)を入手します。エッジAI用に8bitに量子化されたモデルや通常の32bit浮動小数点モデルなどが一式あります。
    TensorFlow Liteの画像分類モデル入手先
  4. 「assets」フォルダに、入手したモデルを格納します。
  5. 「ClassifierFloatMobileNet.java」「ClassifierQuantizedMobileNet.java」の「getModelPath()」内を入手したモデルのファイル名に書き換えます。
  6. USBケーブルで、ホストPCとAndroidスマホを接続します。
  7. 「Build」-「Make Project」でビルドします。
  8. 「Run」-「Run ‘app’」でアプリケーションをスマホ上で実行します。
手順2:入手したソースコードから、Android Studioのプロジェクトを開く
手順3・4:MobileNetV1・V2のTensorFlow Liteモデルの入手とassetsフォルダへの格納
手順5・7・8:モデルのファイル名を書き換えた後、ビルドしスマホ上でアプリケーションを実行

オブジェクト検出

  1. Vmwareで、Ubuntu18.04を仮想マシンとして起動します。以下の2~7および9~10の作業は仮想マシン上で実行します。
  2. Githubから「TensorFlow 1.12.0」のソースコードを入手します。
    TensorFlow1.12.0ソースコードの入手先
  3. Githubから「Bazel 0.15.0」のインストーラを入手します。
    Bazelインストーラの入手先
  4. 下記を実行し、必要なパッケージをインストールします。
    sudo apt-get install pkg-config zip g++ zlib1g-dev unzip python3
  5. Bazelインストーラに実行権限を与えます。
    chmod +x bazel-0.15.0-installer-linux-x86_64.sh
  6. Bazelインストーラを実行します。
    ./bazel-0.15.0-installer-linux-x86_64.sh --user
  7. Bazelにパスを通します。(.bashrcに追記しても良いです。)
    export PATH="$PATH:$HOME/bin"
  8. 以下のURLから、「MobileNetV1/2+SSD」のTensorFlow モデル(*.pb)を入手します。
    TensorFlowモデルの入手先
  9. TensorFlowソースコードを置いたディレクトリに移動します。
    cd tensorflow-1.12.0
  10. TensorFlow liteコンバータ(toco)で、入手したProtobufモデル(*.pb)からTensorflow Liteモデル(*.tflite)に変換します。      
    bazel run tensorflow/contrib/lite/toco:toco -- --input_file=/home/android/mb1_ssd_quant.pb --output_file=/home/android/detect.tflite --input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor --output_arrays='TFLite_Detection_PostProcess','TFLite_Detection_PostProcess:1','TFLite_Detection_PostProcess:2','TFLite_Detection_PostProcess:3' --inference_type=QUANTIZED_UINT8 --default_ranges_min=0 --default_ranges_max=6 --mean_values=128.0 --std_values=128.0 --allow_custom_ops
  11. GithubからTensorFlow Examplesのソースコードを取得します。
    TensorFlow Examplesのソースコード入手先
  12. ホストPC上で、「Android Studio」を起動し、「Open an existing Android Studio project」を押下し、「examples/lite/examples/object_detection/android/app」を選択します。
  13. 「build.gradle」の40行目をコメントアウトします。コメントアウトしなかった場合、MobileNetV1+SSDのモデルが自動的にダウンロードされ、上書きされてしまうため、任意のモデルが実行できなくなります。
  14. 「assets」フォルダに、変換したモデルを格納します。
  15. 「DetectorActivity.java」の57行目を変換したモデルのファイル名に書き換えます。
  16. USBケーブルで、ホストPCとAndroidスマホを接続します。
  17. 「Build」ー「Make Project」でビルドします。
  18. 「Run」ー「Run ‘app’」でアプリケーションをスマホ上で実行します。
手順8:学習済みのMobileNet+SSDのモデルをダウンロード
手順13:「build.gradle」の一部の行をコメントアウト
手順15・17・18:Bazelで生成した.tfliteモデルを指定し、Buildした後にRunで実行

アプリ動作例

左が画像分類モデル、右がオブジェクト検出モデルを実行したときの出力結果です。(一部マスキングしています。)スマホ上で画像認識AIをリアルタイムで実行できました。

Androidスマホ上でのアプリケーション実行例(左:画像分類、右:オブジェクト検出)

速度評価

最後に、速度評価の結果についてです。画像分類とオブジェクト検出について、精度や処理時間を下記の表にまとめました。量子化したTensorFlow Liteモデルを使うことで、精度を維持したままモデルサイズを圧縮することができます。また処理時間だけでなく、メモリ使用量や電力消費量も大幅に抑えられることが期待できます。

種類

モデル

形式

Top1/Top5
(%)

COCO mAP
(^1)

サイズ
(MB)

推論時間
(ms)

画像
分類

MobileNetV1

float(32bit)

71.0/89.9

NaN

16.12

156.8

int(8bit)

70.0/89.0

4.08

102.2

MobileNetV2

float(32bit)

71.8/90.6

13.33

116.9

int(8bit)

70.8/89.9

3.41

68.8

オブジェクト検出

MobileNetV1
SSD

int(8bit)

NaN

18

6.58

160.1

MobileNetV2
SSD

int(8bit)

22

5.89

142.6

まとめ

本日はTensorFlow Liteを使ってAndroidスマホに画像認識AIを実装してみました。今回のような方法を使うことで、スマホのようなデバイス上でもAIをリアルタイムで実装することができます。エッジAIに興味を持った方はぜひ試してみてください。それではまた!

コメント

タイトルとURLをコピーしました