TFLite を利用した Android アプリに Firebase を追加する

1. 概要

cd824ecfd05a2822.png

Firebase ML を使用すると、モデルを無線でデプロイできます。これにより、アプリサイズを小さく抑え、必要なときにのみ ML モデルをダウンロードしたり、複数のモデルをテストしたり、ML モデルを更新したりできます。アプリ全体を再公開する必要はありません。

この Codelab では、静的 TFLite モデルを使用する Android アプリを、Firebase から動的に提供されるモデルを使用するアプリに変換します。

学習内容

  • TFLite モデルを Firebase ML にデプロイしてアプリからアクセスする
  • ユーザー フィードバックを追跡し、Firebase 向け Google アナリティクスでモデルの精度を測定する
  • Firebase Performance を使用してモデルのパフォーマンスをプロファイリングする
  • デプロイされた複数のモデルのうち、Remote Config を介して読み込むものを選択する
  • Firebase A/B Testing でさまざまなモデルを試す

必要なもの

  • Android Studio の最新バージョン。
  • サンプルコード。
  • Android 5.0 以降と Google Play 開発者サービス 9.8 以降を搭載したテストデバイス、または Google Play 開発者サービス 9.8 以降を搭載したエミュレータ
  • デバイスを使用する場合は接続ケーブル。

このチュートリアルをどのように使用されますか?

通読のみ 通読して演習を行う

Android アプリの作成に関するご経験について、満足度をお知らせください。

初心者 中級 上達

2. サンプルコードを取得する

コマンドラインから GitHub リポジトリのクローンを作成します。

$ git clone https://github.com/FirebaseExtended/codelab-digitclassifier-android.git

git がインストールされていない場合は、GitHub ページから、またはこちらのリンクをクリックして、サンプル プロジェクトをダウンロードすることもできます。

3. スターター アプリをインポートする

Android Studio で、ダウンロードしたサンプルコード([File] > [Open] > .../codelab-digitclassifier-android/start)から codelab-digitclassifier-android ディレクトリ(android_studio_folder.png)を選択します。

Android Studio で [Start Project] が開いたはずです。

4. スターター アプリを実行する

これで Android Studio にプロジェクトがインポートされたので、アプリを初めて実行する準備が整いました。Android デバイスを接続して、Android Studio ツールバーの実行アイコン(実行.png)をクリックします。

デバイスでアプリが起動するはずです。この時点で数字を描画しようとすると、アプリは数字を認識できるはずです。

6e36e1b947b395f2.png

5. Firebase コンソール プロジェクトを作成する

プロジェクトに Firebase を追加する

  1. Firebase コンソールに移動します。
  2. [プロジェクトを追加] を選択します。
  3. プロジェクト名を選択または入力します。
  4. Firebase コンソールで残りの設定手順を行い、[プロジェクトを作成](既存の Google プロジェクトを使用する場合は [Firebase を追加])をクリックします。

6. Firebase を追加

  1. 新しいプロジェクトの概要画面で、Android アイコンをクリックして設定ワークフローを起動します。
  2. Codelab のパッケージ名(org.tensorflow.lite.examples.digitclassifier)を入力します。

アプリに google-services.json ファイルを追加する

パッケージ名を登録して [次へ] を選択したら、[google-services.json をダウンロード] をクリックして Firebase Android 構成ファイルを入手し、google-services.json ファイルをプロジェクトの app ディレクトリにコピーします。ファイルがダウンロードされたら、コンソールに表示される次のステップをスキップできます(build-android-start プロジェクトですでに実行されています)。

アプリに google-services プラグインを追加する

google-services プラグインは、google-services.json ファイルを使用して、Firebase を使用するようにアプリケーションを構成します。プロジェクトの app ディレクトリにある build.gradle.kts ファイルの上部にある plugins ブロックに、次の行を追加します。

app/build.gradle.kts

id("com.google.gms.google-services")

次に、プロジェクトの build.gradle.kts ファイルの plugins ブロックに次の行を追加します。

project/build.gradle.kts

id("com.google.gms.google-services") version "4.3.15" apply false

プロジェクトと Gradle ファイルを同期する

アプリですべての依存関係を使用できるようにするには、この時点でプロジェクトを Gradle ファイルと同期する必要があります。[ファイル >Sync Project with Gradle Files] をクリックします。

7. Firebase でアプリを実行する

JSON ファイルで google-services プラグインを構成したので、Firebase でアプリを実行する準備ができました。Android デバイスを接続して、Android Studio ツールバーの実行アイコン(実行.png)をクリックします。

デバイスでアプリが起動するはずです。この時点では、アプリは正常にビルドされるはずです。

8. Firebase ML にモデルをデプロイする

Firebase ML へのモデルのデプロイは、主に次の 2 つの理由で有用です。

  1. アプリのインストール サイズを小さく抑え、必要な場合にのみモデルをダウンロードできる
  2. モデルは定期的に、アプリ全体とは異なるリリース サイクルで更新できる

アプリの静的モデルを Firebase から動的にダウンロードされたモデルに置き換えるには、その前にモデルを Firebase ML にデプロイする必要があります。このモデルは、コンソールを介してデプロイすることも、Firebase Admin SDK を使用してプログラムによってデプロイすることもできます。このステップでは、コンソールからデプロイします。

問題をシンプルにするため、ここではすでにアプリに組み込まれている TensorFlow Lite モデルを使用します。まず、Firebase コンソールを開き、左側のナビゲーション パネルで [ML] をクリックします。[使ってみる] をクリックします選択します[カスタム]を選択します[カスタムモデルを追加]を クリックします] ボタンを離します。

プロンプトが表示されたら、モデルにわかりやすい名前(mnist_v1 など)を付けて、start/app/src/main/assets/mnist.tflite の下にある Codelab プロジェクト ディレクトリからファイルをアップロードします。その後、この TF Lite モデルファイルを Android プロジェクトから削除します。

3c3c50e6ef12b3b.png

9. Firebase ML からモデルをダウンロードする

TFLite モデルは比較的大きくなる可能性があるため、Firebase からアプリにリモートモデルをダウンロードするタイミングの選択は簡単ではありません。アプリの起動時にすぐにモデルを読み込まないようにするのが理想的です。モデルが 1 つの特徴にしか使用されておらず、ユーザーがその特徴を使用することはないと、理由もなく大量のデータがダウンロードされることになります。また、ダウンロード オプション(Wi-Fi に接続されているときにのみモデルを取得するなど)を設定することもできます。ネットワーク接続がなくてもモデルを利用できるようにしたい場合は、アプリなしでもバックアップとしてモデルをバンドルすることが重要です。

わかりやすくするために、デフォルトのバンドルモデルを削除し、アプリの起動時に常に Firebase からモデルをダウンロードします。このようにして、数字認識を実行するときに、Firebase から提供されるモデルで推論が実行されるようにできます。

app/build.gradle.kts ファイルで、Firebase Machine Learning の依存関係を追加する

app/build.gradle.kts

implementation("com.google.firebase:firebase-ml-modeldownloader:24.1.2")

次に、Firebase からモデルをダウンロードするロジックを追加します。

digitClassifier.initialize(loadModelFile())downloadModel("mnist_v1") に置き換えて、このメソッドを実装します。

MainActivity.kt

  private fun downloadModel(modelName: String): Task<CustomModel> {
    val conditions = CustomModelDownloadConditions.Builder()
    .requireWifi()
    .build()
    return FirebaseModelDownloader.getInstance()
        .getModel(modelName, DownloadType.LOCAL_MODEL, conditions)
        .addOnCompleteListener {
          val model = it.result
          if (model == null) {
            showToast("Failed to get model file.")
          } else {
            showToast("Downloaded remote model: $modelName")
            digitClassifier.initialize(model)
          }
        }
      .addOnFailureListener {
        showToast("Model download failed for $modelName, please check your connection.")
      }
  }

アプリを再実行し、数字分類器に数字を描画します。ダウンロードが完了すると、リモートモデルがダウンロードされたというトースト メッセージと、新しいモデルが使用されていることを示すログが表示されます。

10. ユーザー フィードバックとコンバージョンを追跡してモデルの精度を測定する

Firebase 向け Google アナリティクスでは、ユーザーがアプリケーション内でどのように行動し、どこで成功し、どこで離脱して離脱したかを把握できます。また、アプリケーションで最も使用される部分を把握するためにも使用できます。

モデル予測に対するユーザー フィードバックを追跡して、モデルの精度を測定します。ユーザーが [はい] をクリックすると、予測が正確であったことが示されます。

アナリティクス イベントをログに記録して、モデルの精度を追跡できます。まず、アナリティクスをプロジェクトで使用する前に、依存関係にアナリティクスを追加する必要があります。

Firebase 向け Google アナリティクスの依存関係を追加する

app/build.gradle.kts

implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-analytics-ktx")

イベントをロギングする

次に、onCreate 関数で、correct_inference イベントを Firebase に記録するように Googlebot リスナーを設定します。

MainActivity.kt(onCreate)

// Setup YES button
yesButton?.setOnClickListener {
  Firebase.analytics.logEvent("correct_inference", null)
}

アプリを再度実行し、数字を描画します。[はい] を押します。ボタンを数回押して、推論が正確だったというフィードバックを送信します。

デバッグ分析

通常、アプリによって記録されたイベントは、約 1 時間にわたってバッチ処理され、まとめてアップロードされます。このアプローチにより、エンドユーザーのネットワーク データ使用量を削減できます。ただし、アナリティクスの実装を検証するため(および DebugView レポートにアナリティクスを表示するため)、開発デバイスでデバッグモードを有効にして、最小限の遅延でイベントをアップロードできます。

Android デバイスでアナリティクスのデバッグモードを有効にするには、次のコマンドを実行します。

adb shell setprop debug.firebase.analytics.app org.tensorflow.lite.examples.digitclassifier

アプリを再度実行し、数字を描画します。[はい] を押します。ボタンを数回押して、推論が正確だったというフィードバックを送信します。Firebase コンソールのデバッグビューを使用して、ログイベントをほぼリアルタイムで表示できるようになりました。[アナリティクス] をクリック >DebugView にアクセスすることもできます。

5276199a086721fd.png

11. モデルのパフォーマンスを分析する

Firebase Performance Monitoring は、iOS、Android、ウェブアプリのパフォーマンス特性に関する分析情報を得るのに役立つサービスです。

Performance Monitoring SDK を使用してアプリからパフォーマンス データを収集し、Firebase コンソールでそのデータの確認と分析を行います。Performance Monitoring を使用すると、アプリのパフォーマンスをいつどこで改善できるかを把握し、その情報を使用してパフォーマンスの問題を解決できます。

ここでは、推論に関連するパフォーマンス トレースを追加し、

ディープ ラーニングで使用されるモデルの規模が大きければ大きいほど、精度は高くなりますが、レスポンスが返されるまでに時間がかかることがあります。そのため、このことは重要です。このテストでは、精度と速度の適切なバランスを見出すことを目指しています。

Firebase Performance の依存関係を追加する

project/build.gradle.kts

plugins {
  // ...

  // Add the dependency for the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf") version "1.4.2" apply false
}

app/build.gradle.kts

plugins {
  // ...

  // Add the Performance Monitoring plugin
  id("com.google.firebase.firebase-perf")
}

// ...

dependencies {
  // ...

  // Add the dependency for the Performance Monitoring library
  implementation("com.google.firebase:firebase-perf")
}

カスタム トレースを追加する

setupDigitClassifier() 関数内で、新しい downloadTrace を作成し、モデルをダウンロードする直前に開始します。次に、トレースを停止する onsuccess リスナーを追加します。

classifyDrawing() 関数で、新しい分類トレースを作成し、分類の直前に開始します。次に、onsuccess リスナーでトレースを停止します。

MainActivity.kt

class MainActivity : AppCompatActivity() {
  // ...
  
  private val firebasePerformance = FirebasePerformance.getInstance()
  
  // ...

  private fun setupDigitClassifier() {
    // Add these lines to create and start the trace
    val downloadTrace = firebasePerformance.newTrace("download_model")
    downloadTrace.start()
    downloadModel("mnist_v1")
      // Add these lines to stop the trace on success
      .addOnSuccessListener {
        downloadTrace.stop()
      }
  }

// ...

  private fun classifyDrawing() {
    val bitmap = drawView?.getBitmap()

    if ((bitmap != null) && (digitClassifier.isInitialized)) {
      // Add these lines to create and start the trace
      val classifyTrace = firebasePerformance.newTrace("classify")
      classifyTrace.start()
      digitClassifier
        .classifyAsync(bitmap)
        .addOnSuccessListener { resultText -> 
          // Add this line to stop the trace on success
          classifyTrace.stop()
          predictedTextView?.text = resultText
        }
        .addOnFailureListener { e ->
          predictedTextView?.text = getString(
            R.string.tfe_dc_classification_error_message,
            e.localizedMessage
          )
          Log.e(TAG, "Error classifying drawing.", e)
        }
    }
  }

パフォーマンス イベントのログメッセージを表示する

  1. 次のように、アプリの AndroidManifest.xml ファイルに <meta-data> 要素を追加して、ビルド時に Performance Monitoring のデバッグ ロギングを有効にします。

AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
</application>
  1. ログ メッセージにエラー メッセージがないか確認します。
  2. Performance Monitoring は、ログ メッセージに FirebasePerformance のタグを付けます。logcat フィルタリングを使用すると、次のコマンドを実行すると、実行時間のトレースと HTTP/S ネットワーク リクエストのロギングを表示できます。
adb logcat -s FirebasePerformance
  1. Performance Monitoring がパフォーマンス イベントをロギングしていることを示す、次の種類のログを確認します。
  • Logging TraceMetric
  • Logging NetworkRequestMetric

12. Firebase ML に 2 番目のモデルをデプロイする

モデル アーキテクチャが改善されたモデルや、より大きなデータセットや更新されたデータセットでトレーニングされたモデルなど、モデルの新しいバージョンを思いついたとき、現在のモデルを新しいバージョンに置き換えたくなるかもしれません。ただし、テストで優れたパフォーマンスを発揮するモデルが、必ずしも本番環境で同じように優れたパフォーマンスを発揮するとは限りません。そこで、本番環境で A/B テストを実施して、元のモデルと新しいモデルを比較してみましょう。

Firebase Model Management API を有効にする

このステップでは、Firebase Model Management API を有効にして、Python コードを使用して新しいバージョンの TensorFlow Lite モデルをデプロイできるようにします。

ML モデルを保存するバケットを作成する

Firebase コンソールで [Storage] に移動し、[使ってみる] をクリックします。fbbea78f0eb3dc9f.png

ダイアログに沿ってバケットを設定します。

19517c0d6d2aa14d.png

Firebase ML API を有効にする

Google Cloud コンソールの Firebase ML API ページに移動し、[有効にする] をクリックします。

2414fd5cced6c984.png求められたら、数字分類器アプリを選択します。

新しいモデルをトレーニングして Firebase ML に公開する

より大きなデータセットを使用して新しいバージョンのモデルをトレーニングし、Firebase Admin SDK を使用してトレーニング ノートブックから直接プログラムでモデルをデプロイします。

サービス アカウントの秘密鍵をダウンロードする

Firebase Admin SDK を使用するには、サービス アカウントを作成する必要があります。こちらのリンクをクリックして Firebase コンソールの [サービス アカウント] パネルを開き、ボタンをクリックして Firebase Admin SDK 用の新しいサービス アカウントを作成します。プロンプトが表示されたら、[Generate New Private Key(新しい秘密鍵を生成)] ボタンをクリックします。サービス アカウント キーを使用して、Colab ノートブックからリクエストを認証します。

c3b95de1e5508516.png

これで、新しいモデルをトレーニングしてデプロイできます。

  1. この Colab ノートブックを開き、自分のドライブの下にコピーを作成します。
  2. 最初のセル「Train animprove TensorFlow Lite model」を実行します。左側の再生ボタンをクリックしますこれにより新しいモデルがトレーニングされます。これには時間がかかることがあります。
  3. 2 番目のセルを実行すると、ファイル アップロードのプロンプトが作成されます。サービス アカウントの作成時に Firebase コンソールからダウンロードした JSON ファイルをアップロードします。

71e847c6a85423b3.png

  1. 最後の 2 つのセルを実行します。

Colab ノートブックを実行すると、Firebase コンソールに 2 番目のモデルが表示されます。2 番目のモデルの名前が mnist_v2 であることを確認します。

c316683bb4d75d57.png

13. Remote Config でモデルを選択

2 つの異なるモデルが用意できたので、実行時にダウンロードするモデルを選択するためのパラメータを追加します。クライアントが受け取るパラメータの値によって、クライアントがダウンロードするモデルが決まります。

Firebase コンソールで構成ルールを追加する

まず、Firebase コンソールを開き、左側のナビゲーション メニューで [Remote Config] ボタンをクリックします。[パラメータを追加]をクリックし] ボタンを離します。

新しいパラメータの名前を model_name とし、デフォルト値の "mnist_v1" を指定します。Remote Config パラメータにモデルの名前を指定することで、テストするモデルごとに新しいパラメータを追加することなく、複数のモデルをテストできます。[変更を公開] をクリックして更新を適用します。

2949cb95c7214ca4.png

Firebase RemoteConfig の依存関係を追加する

app/build.gradle.kts

implementation("com.google.firebase:firebase-config-ktx")

Firebase Remote Config を構成する

MainActivity.kt

  private fun configureRemoteConfig() {
    remoteConfig = Firebase.remoteConfig
    val configSettings = remoteConfigSettings {
      minimumFetchIntervalInSeconds = 3600
    }
    remoteConfig.setConfigSettingsAsync(configSettings)
  }

構成のリクエストと使用

config の取得リクエストを作成し、config パラメータを取得して使用する完了ハンドラを追加します。

MainActivity.kt

 private fun setupDigitClassifier() {
    configureRemoteConfig()
    remoteConfig.fetchAndActivate()
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          val modelName = remoteConfig.getString("model_name")
          val downloadTrace = firebasePerformance.newTrace("download_model")
          downloadTrace.start()
          downloadModel(modelName)
            .addOnSuccessListener {
              downloadTrace.stop()
            }
        } else {
          showToast("Failed to fetch model name.")
        }
      }
  }

Remote Config をテストする

  1. [98205811bbed9d74.png実行] ボタンをクリックします。
  2. mnist_v1 モデルがダウンロードされたことを示すトースト メッセージが表示されていることを確認します。
  3. Firebase コンソールに戻り、デフォルト値を mnist_v2 に変更し、[変更を公開] を選択して更新を適用します。
  4. アプリを再起動し、mnist_v2 モデルが今回はダウンロードされたことを示す Toast メッセージが表示されることを確認します。

14. A/B テストモデルの有効性

Firebase A/B Testing を使用すると、プロダクトとマーケティングのテストを簡単に実行、分析、スケールできるため、アプリのエクスペリエンスの最適化に役立ちます。最後に、Firebase に組み込まれた A/B Testing の動作を使用して、2 つのモデルのどちらのパフォーマンスが優れているかを確認できます。

[アナリティクス] ->Firebase コンソールのイベント。correct_inference イベントが表示されている場合は [コンバージョン イベント] としてマークし、表示されていない場合は、アナリティクス ->[新しいコンバージョン イベントを作成] をクリックします。correct_inference. を下げて

Firebase コンソールの Remote Config に移動し、[A/B テスト] を選択します。[model_name] の [その他のオプション] メニューにあるボタン先ほど追加したパラメータです

fad5ea36969d2aeb.png

続くメニューで、デフォルトの名前を受け入れます。

d7c006669ace6e40.png

プルダウンからアプリを選択し、ターゲティング条件をアクティブ ユーザーの 50% に変更します。

cb72dcc7d2666bd3.png

すでに「correct_inference」イベントをコンバージョンとして設定できていた場合は、このイベントをトラッキング用のメインの指標として使用します。アナリティクスにイベントが表示されるまで待たない場合は、correct_inference manually を追加します。

1ac9c94fb3159271.png

最後に、[パターン] 画面で、コントロール グループのバリアントでは「mnist_v1」を使用し、パターン A のグループで「mnist_v2」を使用します。

e4510434f8da31b6.png

右下にある [確認] ボタンをクリックします。

これで、2 つのモデルの A/B テストを作成できました。A/B テストは現在下書きの状態で、[テストを開始] をクリックしていつでも開始できます。] ボタンを離します。

A/B Testing について詳しくは、A/B Testing のドキュメントをご覧ください。

15. 完了

この Codelab では、アプリ内の静的にバンドルされた tflite アセットを、Firebase から動的に読み込まれる TFLite モデルに置き換える方法を学習しました。TFLite と Firebase の詳細については、他の TFLite サンプルと Firebase スタートガイドをご覧ください。

学習した内容

  • TensorFlow Lite
  • Firebase ML
  • Firebase アナリティクス
  • Firebase Performance Monitoring
  • Firebase Remote Config
  • Firebase A/B Testing

次のステップ

  • アプリに Firebase ML Deployment を実装します。

詳細

質問がある場合

問題を報告する