iOS で TensorFlow Lite を使用して花を認識する

1. はじめに

657431be3173fa86.png

TensorFlow は多目的の ML フレームワークです。TensorFlow は、クラウド上のクラスタをまたいで巨大なモデルをトレーニングすることから、スマートフォンなどの組み込みシステムでモデルをローカルで実行することまで、あらゆる用途に使用できます。

この Codelab では、TensorFlow Lite を使用して iOS デバイスで画像認識モデルを実行します。

学習内容

  • TFLite コンバータを使用してモデルを最適化する方法。
  • TFLite インタープリタを使用して、既製の iOS アプリでアプリを実行する方法

作業内容

TensorFlow 画像認識プログラムを実行して花を識別するシンプルなカメラアプリ。

前提条件

この Codelab を独自のハードウェアで行う場合は、次のものがインストールされていることを確認してください。

  • Xcode 10 以降
  • CocoaPods 1.8.0 以降

c45ecd122998622e.png

ライセンス: 無料で使用できる

2. Colab を使用して花認識機能をトレーニングする

この Codelab では、Colaboratory と Xcode を使用します。

TensorFlow Lite Model Maker を使用して Colab を開き、転移学習を使用して花を認識する分類器をトレーニングし、モバイルアプリで使用する TFLite モデルをエクスポートします。

3. 作業ディレクトリを設定する

Git リポジトリのクローンを作成する

次のコマンドは、この Codelab に必要なファイルを含む Git リポジトリのクローンを作成します。

git clone https://github.com/tensorflow/examples.git

cd で、作成したクローンの Xcode プロジェクトのルートに移動します。この Codelab の残りの部分は、ここで作業します。

cd examples/lite/examples/image_classification/ios

4. iOS アプリを設定する

依存関係のインストール

CocoaPods を使用して、iOS アプリの依存関係(TensorFlow Lite を含む)をインストールします。インストール コマンドが完了したら、ImageClassification.xcworkspace を開いて Xcode でプロジェクトを開きます。

pod install --repo-update
open ImageClassification.xcworkspace

5. アプリのテスト実行

iOS Simulator は Mac のカメラにアクセスできないため、カメラを使用するにはアプリを実際のデバイスで実行する必要があります。iOS デバイス向けにビルドするには、Apple Developer Program に登録されているか、他のユーザーによってプロビジョニングされたデバイスにアクセスできる必要があります。

この Codelab をシミュレータで実行する場合は、シミュレータ自体で Safari からペーストボードに画像をコピーする必要があります。シミュレータで画像を処理する手順は次のとおりです。

  1. 任意のシミュレータ ターゲットにアプリをビルドします。
  2. iOS シミュレータで、Cmd+Shift+H キーを押してアプリを最小化します。
  3. ホーム画面の下部にある Safari をタップして、画像を検索します。
  4. Google 画像検索の検索結果で検索結果をタップし、画像を長押しします。ポップアップ表示されたダイアログで、[コピー] を選択します。
  5. TFL Classify アプリに戻ります。コピーした画像が推論結果とともに自動的に表示されます。存在しない場合は、画像の URL ではなく、画像データ自体をコピーしていることを確認してください。

アプリのビルドとインストールをテスト

アプリに変更を加える前に、リポジトリに付属のバージョンを実行しましょう。左上のプルダウン メニューから、ご使用の iOS デバイスを選択します。

275753d3a77a0df3.png

次に、Cmd+R キーを押すか、Xcode で [再生] f96cf117245c0fa6.png ボタンをクリックして、デバイスにアプリをビルドします。アプリがデバイスにインストールされると、自動的に起動します。

このバージョンのアプリは、1, 000 の ImageNet カテゴリで事前にトレーニングされた標準の MobileNet を使用します。次のようになります。

d11436f0bb5a75db.jpeg

6. カスタマイズしたアプリを実行する

デフォルトのアプリ設定では、標準の MobileNet を使用して、画像を 1, 000 個の ImageNet クラスのいずれかに分類します。

次に、Colab でトレーニングされたカスタム画像カテゴリに、再トレーニングされたモデルを使用するようにアプリを変更します。

7. アプリを変換してモデルを実行する

モデルファイルをプロジェクトに追加する

プロジェクトのモデルリソースは、Xcode プロジェクト ナビゲータの ImageClassification > Model にあります。これらを置き換えるには、まず Model グループ内の 2 つの既存のファイルを削除します。メッセージが表示されたら、[ゴミ箱に移動] を選択します。

cf2f7fefb2e5075f.png

次に、Colab からダウンロードした model.tflite ファイルと labels.txt ファイルを [モデル] グループにドラッグします。プロンプトが表示されたら、Copy items if neededAdd to targets が両方とも選択されていることを確認します。

281d7eb72635bb5f.png

アプリのコードを変更する

アプリを機能させるには、追加した新しいモデルを指すように、モデル読み込みロジックのパスを更新する必要があります。

ModelDataHandler.swift を開き(Xcode ナビゲータ パス: ImageClassification -> ModelDataHandler -> ModelDataHandler.swift)、36 行目を次のように変更します。

// before
static let modelInfo: FileInfo = (name: "mobilenet_quant_v1_224", extension: "tflite")

// after
static let modelInfo: FileInfo = (name: "model", extension: "tflite")

変更内容はすべて保存してください。

8. カスタマイズしたアプリを実行する

Xcode で Cmd+B キーを押すか Play f96cf117245c0fa6.png ボタンをクリックして、デバイスにアプリをビルドします。アプリが起動すると、次のように表示されます。

c45ecd122998622e.png

電源ボタンと音量大ボタンを同時に長押しすると、スクリーンショットを撮ることができます。

次に、ウェブで「花」を検索して、パソコンの画面にカメラを向けて、画像が正しく分類されたかどうかを確認します。

友人に写真を撮ってもらい、TensorFlower の種類を確認しましょう\\uf339 \\uf33b \\uf337

9. どのような仕組みですか?

アプリを実行したので、TensorFlow Lite 固有のコードを見てみましょう。

TensorFlowLiteSwift

このアプリは、CocoaPods を介して TensorFlowLite Swift ライブラリを使用します。Swift ライブラリは TFLite C API のシンラッパーです。TFLite C API 自体は TFLite C++ ライブラリのラッパーです。

モジュールの Podfile ファイルの以下の行により、最新バージョンの Pod グローバル CocoaPods 仕様リポジトリがプロジェクトに pull されます。

Podfile

target 'ImageClassification' do
  use_frameworks!

  # Pods for ImageClassification
   pod 'TensorFlowLiteSwift'
end

TensorFlow Lite Swift API を使用する

TensorFlow Lite とやり取りするコードは、すべて ModelDataHandler.swift に含まれています。

セットアップ

最初のブロックは、ModelDataHandler のイニシャライザです。

ModelDataHandler.swift

/// A failable initializer for `ModelDataHandler`. A new instance is created if the model and
/// labels files are successfully loaded from the app's main bundle. Default `threadCount` is 1.
init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int = 1) {
  let modelFilename = modelFileInfo.name

  // Construct the path to the model file.
  guard let modelPath = Bundle.main.path(
    forResource: modelFilename,
    ofType: modelFileInfo.extension
  ) else {
    print("Failed to load the model file with name: \(modelFilename).")
    return nil
  }

  // Specify the options for the `Interpreter`.
  self.threadCount = threadCount
  var options = InterpreterOptions()
  options.threadCount = threadCount
  do {
    // Create the `Interpreter`.
    interpreter = try Interpreter(modelPath: modelPath, options: options)
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()
  } catch let error {
    print("Failed to create the interpreter with error: \(error.localizedDescription)")
    return nil
  }
  // Load the classes listed in the labels file.
  loadLabels(fileInfo: labelsFileInfo)
}

いくつかの行について、さらに詳しく説明します。

次の行は、TFLite インタープリタを作成します。

ModelDataHandler.swift

interpreter = try Interpreter(modelPath: modelPath, options: options)

インタープリタは、TensorFlow グラフを介して元データの入力を渡す役割を担います。ディスク上のモデルへのパスをインタープリタに渡すと、インタープリタがそれを FlatBufferModel として読み込みます。

最後の行でラベルリストが読み込まれます。

loadLabels(fileInfo: labelsFileInfo)

これは、テキスト ファイルからメモリに文字列を読み込むだけです。

モデルを実行する

2 つ目のブロックは runModel メソッドです。これは入力として CVPixelBuffer を受け取り、インタープリタを実行して、アプリで出力するテキストを返します。

ModelDataHandler.swift

try interpreter.copy(rgbData, toInputAt: 0)
// ...
try interpreter.invoke()
// ...
outputTensor = try interpreter.output(at: 0)

10. 次のステップ

詳しくは、以下のリンクをご覧ください。