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

1. 概要

cd824ecfd05a2822.png

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

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

学習内容

  • TFLite モデルを Firebase ML にデプロイしてアプリからアクセス
  • Firebase Analytics でユーザー フィードバックを追跡してモデルの精度を測定する
  • Firebase Performance を使用してモデルのパフォーマンスをプロファイリングする
  • デプロイされた複数のモデルのうち、Remote Config によって読み込まれるモデルから 1 つを選択します
  • 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 で、ダウンロードしたサンプルコードの codelab-digitclassifier-android ディレクトリ(android_studio_folder.png)を選択します([File] > [Open] > .../codelab-digitclassifier-android/start)。

これで、Android Studio で start プロジェクトが開いた状態になります。

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 ファイルと同期する必要があります。Android Studio のツールバーで、[File] > [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.")
      }
  }

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

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

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

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

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

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

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 に記録するように Firestore リスナーを設定します。

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 コンソールのデバッグビューから、ログイベントをほぼリアルタイムで確認できるようになりました。左側のナビゲーション バーで [Analytics] > [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() 関数で、新しい classificationTrace を作成し、分類の直前に開始します。次に、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. ビルド時に Performance Monitoring のデバッグ ロギングを有効にするには、次のようにアプリの AndroidManifest.xml ファイルに <meta-data> 要素を追加します。

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求められたら、Digit Classifier アプリを選択します。

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

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

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

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

c3b95de1e5508516.png

これで、新しいモデルをトレーニングしてデプロイできるようになりました。

  1. この Colab ノートブックを開き、自分のドライブ内にコピーを作成します。
  2. 最初のセルの左にある再生ボタンをクリックして、「トレーニングされた TensorFlow Lite モデルのトレーニング」を実行します。新しいモデルをトレーニングするため、しばらく時間がかかることがあります。
  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)
  }

構成をリクエストして使用する

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

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 [Run] ボタンをクリックします。
  2. mnist_v1 モデルがダウンロードされたことを示す Toast メッセージが表示されていることを確認します。
  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] に移動し、先ほど追加した「model_name」パラメータのその他のオプション メニューから [A/B テスト] ボタンを選択します。

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 を実装します。

詳細

質問がある場合

問題を報告する