1. 概要
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 で [Start Project] が開いたはずです。
4. スターター アプリを実行する
これで Android Studio にプロジェクトがインポートされたので、アプリを初めて実行する準備が整いました。Android デバイスを接続して、Android Studio ツールバーの実行アイコン()をクリックします。
デバイスでアプリが起動するはずです。この時点で数字を描画しようとすると、アプリは数字を認識できるはずです。
5. Firebase コンソール プロジェクトを作成する
プロジェクトに Firebase を追加する
- Firebase コンソールに移動します。
- [プロジェクトを追加] を選択します。
- プロジェクト名を選択または入力します。
- Firebase コンソールで残りの設定手順を行い、[プロジェクトを作成](既存の Google プロジェクトを使用する場合は [Firebase を追加])をクリックします。
6. Firebase を追加
- 新しいプロジェクトの概要画面で、Android アイコンをクリックして設定ワークフローを起動します。
- 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 ツールバーの実行アイコン()をクリックします。
デバイスでアプリが起動するはずです。この時点では、アプリは正常にビルドされるはずです。
8. Firebase ML にモデルをデプロイする
Firebase ML へのモデルのデプロイは、主に次の 2 つの理由で有用です。
- アプリのインストール サイズを小さく抑え、必要な場合にのみモデルをダウンロードできる
- モデルは定期的に、アプリ全体とは異なるリリース サイクルで更新できる
アプリの静的モデルを Firebase から動的にダウンロードされたモデルに置き換えるには、その前にモデルを Firebase ML にデプロイする必要があります。このモデルは、コンソールを介してデプロイすることも、Firebase Admin SDK を使用してプログラムによってデプロイすることもできます。このステップでは、コンソールからデプロイします。
問題をシンプルにするため、ここではすでにアプリに組み込まれている TensorFlow Lite モデルを使用します。まず、Firebase コンソールを開き、左側のナビゲーション パネルで [ML] をクリックします。[使ってみる] をクリックします選択します[カスタム]を選択します[カスタムモデルを追加]を クリックします] ボタンを離します。
プロンプトが表示されたら、モデルにわかりやすい名前(mnist_v1
など)を付けて、start/app/src/main/assets/mnist.tflite
の下にある Codelab プロジェクト ディレクトリからファイルをアップロードします。その後、この TF Lite モデルファイルを Android プロジェクトから削除します。
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 にアクセスすることもできます。
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)
}
}
}
パフォーマンス イベントのログメッセージを表示する
- 次のように、アプリの
AndroidManifest.xml
ファイルに<meta-data>
要素を追加して、ビルド時に Performance Monitoring のデバッグ ロギングを有効にします。
AndroidManifest.xml
<application>
<meta-data
android:name="firebase_performance_logcat_enabled"
android:value="true" />
</application>
- ログ メッセージにエラー メッセージがないか確認します。
- Performance Monitoring は、ログ メッセージに
FirebasePerformance
のタグを付けます。logcat フィルタリングを使用すると、次のコマンドを実行すると、実行時間のトレースと HTTP/S ネットワーク リクエストのロギングを表示できます。
adb logcat -s FirebasePerformance
- 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] に移動し、[使ってみる] をクリックします。
ダイアログに沿ってバケットを設定します。
Firebase ML API を有効にする
Google Cloud コンソールの Firebase ML API ページに移動し、[有効にする] をクリックします。
求められたら、数字分類器アプリを選択します。
新しいモデルをトレーニングして Firebase ML に公開する
より大きなデータセットを使用して新しいバージョンのモデルをトレーニングし、Firebase Admin SDK を使用してトレーニング ノートブックから直接プログラムでモデルをデプロイします。
サービス アカウントの秘密鍵をダウンロードする
Firebase Admin SDK を使用するには、サービス アカウントを作成する必要があります。こちらのリンクをクリックして Firebase コンソールの [サービス アカウント] パネルを開き、ボタンをクリックして Firebase Admin SDK 用の新しいサービス アカウントを作成します。プロンプトが表示されたら、[Generate New Private Key(新しい秘密鍵を生成)] ボタンをクリックします。サービス アカウント キーを使用して、Colab ノートブックからリクエストを認証します。
これで、新しいモデルをトレーニングしてデプロイできます。
- この Colab ノートブックを開き、自分のドライブの下にコピーを作成します。
- 最初のセル「Train animprove TensorFlow Lite model」を実行します。左側の再生ボタンをクリックしますこれにより新しいモデルがトレーニングされます。これには時間がかかることがあります。
- 2 番目のセルを実行すると、ファイル アップロードのプロンプトが作成されます。サービス アカウントの作成時に Firebase コンソールからダウンロードした JSON ファイルをアップロードします。
- 最後の 2 つのセルを実行します。
Colab ノートブックを実行すると、Firebase コンソールに 2 番目のモデルが表示されます。2 番目のモデルの名前が mnist_v2
であることを確認します。
13. Remote Config でモデルを選択
2 つの異なるモデルが用意できたので、実行時にダウンロードするモデルを選択するためのパラメータを追加します。クライアントが受け取るパラメータの値によって、クライアントがダウンロードするモデルが決まります。
Firebase コンソールで構成ルールを追加する
まず、Firebase コンソールを開き、左側のナビゲーション メニューで [Remote Config] ボタンをクリックします。[パラメータを追加]をクリックし] ボタンを離します。
新しいパラメータの名前を model_name
とし、デフォルト値の "mnist_v1"
を指定します。Remote Config パラメータにモデルの名前を指定することで、テストするモデルごとに新しいパラメータを追加することなく、複数のモデルをテストできます。[変更を公開] をクリックして更新を適用します。
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 をテストする
- [
実行] ボタンをクリックします。
- mnist_v1 モデルがダウンロードされたことを示すトースト メッセージが表示されていることを確認します。
- Firebase コンソールに戻り、デフォルト値を mnist_v2 に変更し、[変更を公開] を選択して更新を適用します。
- アプリを再起動し、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] の [その他のオプション] メニューにあるボタン先ほど追加したパラメータです
続くメニューで、デフォルトの名前を受け入れます。
プルダウンからアプリを選択し、ターゲティング条件をアクティブ ユーザーの 50% に変更します。
すでに「correct_inference
」イベントをコンバージョンとして設定できていた場合は、このイベントをトラッキング用のメインの指標として使用します。アナリティクスにイベントが表示されるまで待たない場合は、correct_inference
manually
を追加します。
最後に、[パターン] 画面で、コントロール グループのバリアントでは「mnist_v1
」を使用し、パターン A のグループで「mnist_v2
」を使用します。
右下にある [確認] ボタンをクリックします。
これで、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 を実装します。