カスタムモデルをアプリに統合する

1. 始める前に

このシリーズの最初の Codelab では、画像ラベル付けを使用して画像の内容を解析する非常にシンプルなアプリを作成しました。このアプリにヒナギクの写真を渡すと、花びらや空などのものが写っていることが返されました。次に、2 番目の Codelab では Python に切り替えて、5 種類の花を認識する新しいカスタムモデルをトレーニングしました。

この Codelab では、最初のラボのアプリを 2 番目のラボのモデルで更新します。

このコードラボの完全なソースコードは、 この リポジトリのクローンを作成して取得できます。Android と iOS のサブディレクトリが表示されます。前の Codelab のコードは、必要に応じて ImageClassifierStep1 として入手できます。この Codelab の完成したコードは、ImageClassifierStep2 として入手できます。

前提条件

  • この学習プログラムの最初の 2 つの Codelab を完了していること

作成するものと学習内容

  • 前のラボでトレーニングしたカスタムモデルを Android または iOS アプリに統合する

必要なもの

  • ラボの Android 部分用の Android Studio(developer.android.com/studio で入手可能)
  • ラボの iOS 部分用の Xcode(Apple App Store で入手可能)

2. スターター アプリを入手する

まず、「Android または iOS で初めてのコンピュータ ビジョン アプリを作成する」Codelab のアプリが必要です。ラボを完了している場合は、ImageClassifierStep1 という名前になります。ラボを完了していない場合は、 リポジトリから完成版のクローンを作成できます。

Android Studio で開き、必要な更新を行い、準備ができたらアプリを実行して動作を確認します。次のように表示されます。

f3703d45d1332d1d.png

かなりプリミティブなアプリですが、わずかなコードで非常に強力な機能を示しています。ただし、この花を単なる花としてではなくヒナギクとして認識させるには、「画像分類用のカスタムモデルを作成する」Codelab のカスタムモデルを使用するようにアプリを更新する必要があります。

3. カスタム ML Kit モデルを使用するように build.gradle を更新する

  1. Android Studio を使用して、アプリレベルの build.gradle ファイルを見つけます。最も簡単な方法は、プロジェクト エクスプローラを使用することです。 上部で [Android] が選択されていることを確認すると、下部に [Gradle Scripts] フォルダが表示されます。
  2. 次の例のように、アプリ名の後に「.app」が付いたモジュール用のものを開きます(Module: ImageClassifierStep1.app)。

8fe1d04b40610047.png

  1. ファイルの下部にある [dependencies] 設定を見つけます。次の行が表示されます。
implementation 'com.google.mlkit:image-labeling:17.0.1'

バージョン番号は異なる場合があります。最新のバージョン番号は、ML Kit サイト(https://developers.google.com/ml-kit/vision/image-labeling/android)で確認してください。

  1. これをカスタム画像ラベル付けライブラリの参照に置き換えます。このバージョン番号は、https://developers.google.com/ml-kit/vision/image-labeling/custom-models/android で確認できます。
implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
  1. また、前のラボで作成した .tflite モデルを追加します。Android Studio でアプリをコンパイルするときにこのモデルを圧縮しないようにするには、同じ build.gradle ファイルの [Android] セクションで次の設定を使用します。
aaptOptions{
    noCompress "tflite"
}

他の設定内にないことを確認してください。android タグの直下にネストする必要があります。次の例をご覧ください。

62d546bff11d2a50.png

4. TFLite モデルを追加する

前の Codelab でカスタムモデルを作成し、model.tflite としてダウンロードしました。

プロジェクトで、現在 flower1.jpg が含まれている [assets] フォルダを見つけます。次のようにして、モデルをそのフォルダにコピーします。

  1. Android Studio で [Assets] フォルダを右クリックします。表示されたメニューで [Reveal in Finder] を選択します(Windows の場合は [Show in Explorer]、Linux の場合は [Show in Files])。

db30b47e419a326b.png

  1. ファイル システムのディレクトリに移動します。flower1.jpg. と並べて、model.tflite ファイルをそのディレクトリにコピーします。

36de0c51bec1c19e.png

Android Studio が更新され、アセット フォルダに両方のファイルが表示されます。

e9f4e9f394d9b357.png

これで、コードを更新する準備ができました。

5. カスタムモデルのコードを更新する

まず、カスタムモデルを読み込むコードを追加します。

  1. MainActivity ファイルで、setContentView(R.layout.activity_main) という行の直下の onCreate に次のコードを追加します。

これにより、LocalModel を使用して model.tflite アセットからビルドされます。Android Studio で「LocalModel」が赤色で表示される場合は、ALT + Enter を押してライブラリをインポートします。これにより、com.google.mlkit.common.model.LocalModel へのインポートが追加されます。

val localModel = LocalModel.Builder()
        .setAssetFilePath("model.tflite")
        .build()

以前は、btn.setOnClickListener ハンドラでデフォルトのモデルを使用していました。次のコードで設定されていました。

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

これをカスタムモデルを使用するように置き換えます。

  1. カスタム オプション オブジェクトを設定します。
val options = CustomImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.7f)
        .setMaxResultCount(5)
        .build()

これにより、デフォルトのオプションがカスタマイズされたセットに置き換えられます。信頼度しきい値は、返される予測の品質の基準を設定します。この Codelab の冒頭のサンプル(画像がヒナギク)では、4 つの予測があり、それぞれに値が付いています(「Sky」は 0.7632 など)。

信頼度しきい値を高く設定することで、品質の低い結果を効果的に除外できます。たとえば、これを 0.9 に設定すると、それより優先度の低いラベルは返されません。setMaxResultCount() はクラス数の多いモデルで役立ちますが、このモデルには 5 つしかないため、5 のままにします。

ラベラーのオプションが用意できたので、ラベラーのインスタンス化を次のように変更できます。

val labeler = ImageLabeling.getClient(options)

残りのコードは変更せずに実行されます。やってみましょう

dd40c36c4edbb33.png

この花がヒナギクとして識別され、確率が 0 .959 になりました。

2 つ目の花の画像を追加して、もう一度実行してみましょう。

8556a5fbea487842.png

バラとして識別されます。

「rose」ではなく「roses 」と表示されるのはなぜでしょうか。データセットでは、ラベルはフォルダ名で指定されます。残念ながら、これらのフォルダ名は一貫性がなく、単数形(「daisy」など)を使用する場合と複数形(「roses」など)を使用する場合があります。これを、画像内のアイテムをカウントしようとするモデルと混同しないでください。このモデルはそれよりもはるかにプリミティブで、花の種類しか識別できません。

6. iOS スターター アプリを入手する

  1. まず、最初の Codelab のアプリが必要です。ラボを完了している場合は、ImageClassifierStep1 という名前になります。ラボを完了していない場合は、リポジトリから完成版のクローンを作成できます。リポジトリには Pod と .xcworkspace がないため、次のステップに進む前に、.xcproject と同じディレクトリから「pod install」を実行してください。
  2. Xcode で ImageClassifierStep1.xcworkspace を開きます。Pod を使用して ML Kit をバンドルしているため、.xcproject ではなく .xcworkspace を使用してください。ワークスペースにこれらが読み込まれます。

このラボの残りの部分では、Codelab のビルドターゲットをサポートする iPhone シミュレータでアプリを実行します。独自のデバイスを使用する場合は、プロジェクト設定でビルドターゲットを iOS バージョンに合わせて変更する必要があります。

実行すると、次のように表示されます。

9e151ed18f99fb98.png

非常に一般的な分類(花びら、花、空)に注意してください。前の Codelab で作成したモデルは、このモデル(ヒナギク)を含む 5 種類の花を検出するようにトレーニングされています。

この Codelab の残りの部分では、カスタムモデルを使用してアプリをアップグレードするために必要な作業について説明します。

7. カスタム ML Kit 画像ラベラー Pod を使用する

最初のアプリでは、Pod ファイルを使用して、ベースの ML Kit 画像ラベラー ライブラリとモデルを取得しました。カスタム画像ラベル付けライブラリを使用するように更新する必要があります。

  1. プロジェクト ディレクトリで podfile というファイルを見つけます。開くと、次のように表示されます。
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. Pod の宣言を ImageLabeling から ImageLabelingCustom に次のように変更します。
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabelingCustom'
end
  1. 完了したら、ターミナルを使用して podfile(および .xcworkspace)を含むディレクトリに移動し、pod install を実行します。

bb5d78eb7c7ab975.png

しばらくすると、MLKitImageLabeling ライブラリが削除され、カスタム ライブラリが追加されます。これで、.xcworkspace を開いてコードを編集できます。

8. TFLite モデルを Xcode に追加する

前の Codelab でカスタムモデルを作成し、model.tflite としてダウンロードしました。手元にない場合は、前の Codelab を実行するか、こちらの Colab コードを 確認してください。Google Colab にアクセスできない場合は、こちらのリンクでノートブックを入手できます。

  1. Xcode でワークスペースを開き、model.tflite をプロジェクトにドラッグします。ViewController.swiftMain.storyboard などの他のファイルと同じフォルダに配置する必要があります。
  2. ダイアログがポップアップ表示され、ファイルを追加するためのオプションが表示されます。[Add to Targets] が選択されていることを確認してください。選択されていない場合、デバイスにデプロイするときにモデルがアプリにバンドルされません。

[Add to Targets] エントリには、ImageClassifierStep1 が表示されます。これは、このラボをステップごとに進めている場合です。完成したコードにスキップした場合は、ImageClassifierStep2(図のとおり)が表示されます。

5b6a7f40c73f0f1f.png

これにより、モデルを読み込むことができます。次のステップでその方法を確認します。

9. カスタムモデルのコードを更新する

  1. ViewController.swift ファイルを開きます。ファイルの上部にある「import MLKitImageLabeling」にエラーが表示されることがあります。これは、Pod ファイルを更新したときに汎用画像ラベル付けライブラリを削除したためです。この行を削除して、次のコードで更新してください。
import MLKitVision
import MLKit
import MLKitImageLabelingCommon
import MLKitImageLabelingCustom

これらを速読して、同じコードが繰り返されていると思われるかもしれません。ただし、末尾は「Common」と「Custom」です。

  1. 次に、前のステップで追加したカスタムモデルを読み込みます。getLabels() 関数を見つけます。visionImage.orientation = image.imageOrientation という行の下に、次の行を追加します。
// Add this code to use a custom model
let localModelFilePath = Bundle.main.path(forResource: "model", ofType: "tflite")
let localModel = LocalModel(path: localModelFilePath!)
  1. 汎用 ImageLabeler のオプションを指定するコードを見つけます。これらのライブラリが削除されたため、エラーが発生している可能性があります。
let options = ImageLabelerOptions()

これを次のコードに置き換えて、CustomImageLabelerOptions を使用し、ローカルモデルを指定します。

let options = CustomImageLabelerOptions(localModel: localModel)

これで完了です。アプリを実行してみましょう。画像を分類しようとすると、精度が向上し、ヒナギクである可能性が高いことがわかります。

238cd21748a97cf4.png

2 つ目の花の画像を追加して、もう一度実行してみましょう。

75f3970a6b509bfe.png

この画像が「roses」というラベルと一致することがアプリによって正常に検出されました。

10. 完了

汎用モデルを使用して画像の内容を認識するアプリの作成から、花などの特定のものを認識する独自の ML モデルの作成、カスタムモデルを使用するようにアプリの更新まで完了しました。

結果として得られるアプリは、バンドルされた画像アセットに依存しているため、非常に限定的です。ただし、ML 部分は正常に動作しています。たとえば、AndroidX Camera を使用してライブフィードからフレームを取得し、それらを分類して、スマートフォンが認識する花を確認できます。

ここから可能性は無限に広がります。花以外の独自のデータがある場合は、コンピュータ ビジョンを使用してそれらを認識するアプリを構築するために必要な基盤が整っています。これらは、はるかに広範な世界への最初のステップにすぎません。この作業を楽しんでいただければ幸いです。