TensorFlow Lite と Firebase を使用してアプリにレコメンデーションを追加する - Android Codelab

1。概要

TensorFlow Lite と Firebase コードラボの推奨事項へようこそ。このコードラボでは、TensorFlow Lite と Firebase を使用してアプリにレコメンデーション モデルをデプロイする方法を学びます。このコードラボは、この TensorFlow Liteサンプルに基づいています。

レコメンデーションにより、アプリは機械学習を使用して、各ユーザーに最も関連性の高いコンテンツをインテリジェントに提供できるようになります。これらは、他の多数のユーザーの集合的な行動に基づいてトレーニングされたモデルを使用して、過去のユーザーの行動を考慮して、ユーザーが将来インタラクションする可能性のあるアプリのコンテンツを提案します。

このチュートリアルでは、Firebase Analytics を使用してアプリのユーザーからデータを取得し、そのデータからレコメンデーション用の機械学習モデルを構築し、そのモデルを Android アプリで使用して推論を実行してレコメンデーションを取得する方法を説明します。特に、当社の推奨事項は、ユーザーが以前に気に入った映画のリストを考慮して、ユーザーが視聴する可能性が最も高い映画を提案します。

学べること

  • Firebase Analytics を Android アプリに統合してユーザー行動データを収集する
  • そのデータを Google Big Query にエクスポートします
  • データを前処理し、TF Lite 推奨モデルをトレーニングする
  • TF Lite モデルを Firebase ML にデプロイし、アプリからアクセスします
  • モデルを使用してデバイス推論を実行し、ユーザーに推奨事項を提案します

必要なもの

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

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

あくまで通読してくださいそれを読んで演習を完了してください

Android アプリの構築に関するあなたの経験をどう評価しますか?

初心者中級熟練した

2. サンプルコードを入手する

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

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

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

Android Studio から、 codelab-recommendations-androidディレクトリ ( android_studio_folder.png ) サンプル コードをダウンロードします ( [ファイル] > [開く] > [.../codelab-recommendations-android/start)。

これで、Android Studio で開始プロジェクトが開いたはずです。

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

新しいプロジェクトを作成する

  1. Firebase コンソールに移動します。
  2. [プロジェクトの追加]を選択します (または、最初のプロジェクトの場合はプロジェクトを作成します)。
  3. プロジェクト名を選択または入力し、 [続行]をクリックします。
  4. 「このプロジェクトに対して Google アナリティクスを有効にする」が有効になっていることを確認します。
  5. Firebase コンソールで残りのセットアップ手順に従い、[プロジェクトの作成] (既存の Google プロジェクトを使用している場合は [Firebase を追加]) をクリックします。

5. Firebaseを追加する

  1. 新しいプロジェクトの概要画面で、Android アイコンをクリックしてセットアップ ワークフローを起動します。
  2. コードラボのパッケージ名を入力します: com.google.firebase.codelabs.recommendations
  3. [アプリの登録]を選択します。

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

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

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

google-services プラグインは、google-services.json ファイルを使用して、アプリケーションが Firebase を使用するように設定します。次の行がプロジェクトの build.gradle.kts ファイルにすでに追加されているはずです (確認のためにチェックしてください)。

app/build.grade.kts

plugins {
    id("com.google.gms.google-services")
}

build.grade.kts

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

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

すべての依存関係をアプリで確実に利用できるようにするには、この時点でプロジェクトを Gradle ファイルと同期する必要があります。 Android Studio ツールバーから[ファイル] > [プロジェクトを Gradle ファイルと同期]を選択します。

6.スターターアプリを実行します

プロジェクトを Android Studio にインポートし、JSON ファイルを使用してgoogle-servicesプラグインを構成したので、アプリを初めて実行する準備が整いました。 Android デバイスを接続し、 「実行」( 実行.png )Android Studio ツールバー。

アプリがデバイス上で起動するはずです。この時点で、映画のリストを含むタブ、「いいね!」タブ、および「おすすめ」タブを表示するアプリケーションが機能していることがわかります。映画のリストで映画をクリックして、お気に入りリストに追加できます。コードラボの残りの手順を完了すると、[おすすめ] タブで映画のおすすめを生成できるようになります。

7. Firebase Analytics をアプリに追加する

このステップでは、アプリに Firebase Analytics を追加して、ユーザーの行動データ (この場合、ユーザーがどの映画を好むか) を記録します。このデータは、推奨モデルをトレーニングするための今後のステップで集合的に使用されます。

Firebase の部品表と分析の依存関係を追加する

Firebase Analytics をアプリに追加するには、次の依存関係が必要です。これらはすでに app/build.gradle.kts ファイルに含まれているはずです (確認してください)。

app/build.grade.kts

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

アプリで Firebase Analytics を設定する

LikedMoviesViewModel には、ユーザーが好きな映画を保存する関数が含まれています。ユーザーが新しい映画を「いいね!」するたびに、その「いいね!」を記録する分析ログ イベントも送信したいと考えています。

以下のコードで onMovieLiked 関数を追加して、ユーザーがムービーをクリックしたときに分析イベントを登録します。

LikedMoviesViewModel.kt

import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase


class LikedMoviesViewModel internal constructor (application: Application) : AndroidViewModel(application) {

    ...

    fun onMovieLiked(movie: Movie) {
        movies.setLike(movie, true)
        logAnalyticsEvent(movie.id.toString())
    }
       
}

次のフィールドと関数を追加して、映画がユーザーの「いいね!」リストに追加されたときに Analytics イベントを記録します。

LikedMoviesViewModel.kt

import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase


class LikedMoviesViewModel internal constructor (application: Application) : AndroidViewModel(application) {
    ...
    private val firebaseAnalytics = Firebase.analytics

    ...

    /**
     * Logs an event in Firebase Analytics that is used in aggregate to train the recommendations
     * model.
     */
    private fun logAnalyticsEvent(id: String) {
        firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
            param(FirebaseAnalytics.Param.ITEM_ID, id)
        }
    }

8. Analytics の統合をテストする

このステップでは、アプリで Analytics イベントを生成し、それらが Firebase コンソールに送信されていることを確認します。

分析デバッグログを有効にする

Firebase Analytics は、ユーザーのバッテリー寿命を最大限に高めるように設計されており、イベントをデバイス上でバッチ処理し、Firebase に時々のみ送信します。デバッグの目的で、シェルで次のコマンドを実行することで、この動作を無効にして、ログに記録されるイベントをリアルタイムで確認できます。

ターミナル

adb shell setprop debug.firebase.analytics.app com.google.firebase.codelabs.recommendations

Analytics イベントが生成されることを確認する

  1. Android Studio で Logcat ウィンドウを開いて、アプリからのログを調べます。
  2. Logcat フィルターを文字列「ログ イベント」に設定します。
  3. アプリで映画を「いいね!」するたびに、「select_item」Analytics イベントが生成されることを確認します。

この時点で、Firebase Analytics がアプリに正常に統合されました。ユーザーがアプリを使用して映画を「いいね!」すると、そのいいね数がまとめて記録されます。このコードラボの残りの部分ではこの集計データを使用して、レコメンデーション モデルをトレーニングします。以下は、Logcat で表示されたのと同じ Analytics イベントが Firebase コンソールにもストリーミングされることを確認するためのオプションの手順です。次のページに進んでください。

オプション: Firebase コンソールでアナリティクス イベントを確認する

  1. Firebase コンソールに移動します。
  2. Analytics の下のDebugViewを選択します
  3. Android Studio で、 [実行]を選択してアプリを起動し、いくつかの映画を「いいね」リストに追加します。
  4. Firebase コンソールの DebugView で、アプリにムービーを追加するときにこれらのイベントが記録されていることを確認します。

9. Analytics データを Big Query にエクスポートする

Big Query は、大量のデータを調査して処理できる Google Cloud プロダクトです。このステップでは、アプリによって生成されたアナリティクス データが自動的に Big Query にエクスポートされるように、Firebase コンソール プロジェクトを Big Query に接続します。

BigQuery エクスポートを有効にする

  1. Firebase コンソールに移動します。
  2. [プロジェクトの概要]の横にある [設定] 歯車アイコンを選択し、 [プロジェクト設定]を選択します。
  3. 「統合」タブを選択します。
  4. BigQueryブロック内の[リンク] (または[管理]) を選択します。
  5. 「Firebase と BigQuery のリンクについて」ステップで「次へ」を選択します。
  6. [統合の構成]セクションで、スイッチをクリックして Google アナリティクス データの送信を有効にし、 [BigQuery へのリンク]を選択します。

これで、Firebase コンソール プロジェクトが Firebase Analytics イベント データを Big Query に自動的に送信できるようになりました。これは追加の操作を行わなくても自動的に行われますが、BigQuery で分析データセットを作成する最初のエクスポートは 24 時間行われない場合があります。データセットの作成後、Firebase は継続的に新しいアナリティクス イベントを Big Query の日中テーブルにエクスポートし、過去の日のイベントをイベント テーブルにグループ化します。

レコメンデーション モデルのトレーニングには大量のデータが必要です。大量のデータを生成するアプリがまだないため、次のステップでは、このチュートリアルの残りの部分で使用するサンプル データセットを BigQuery にインポートします。

10. BigQuery を使用してモデルのトレーニング データを取得する

Firebase コンソールを接続して BigQuery にエクスポートしたので、アプリ分析イベント データはしばらくすると BigQuery コンソールに自動的に表示されます。このチュートリアルの目的で初期データを取得するために、このステップでは既存のサンプル データセットを BigQuery コンソールにインポートし、レコメンデーション モデルのトレーニングに使用します。

サンプル データセットを BigQuery にインポートする

  1. Google Cloud コンソールでBigQueryダッシュボードに移動します。
  2. メニューでプロジェクト名を選択します。
  3. BigQuery の左側のナビゲーションの下部でプロジェクト名を選択すると、詳細が表示されます。
  4. [データセットの作成]を選択して、データセット作成パネルを開きます。
  5. データセット IDに「firebase_recommendations_dataset」と入力し、 [データセットの作成]を選択します。
  6. 新しいデータセットが、左側のメニューのプロジェクト名の下に表示されます。クリックして。
  7. [テーブルの作成]を選択して、テーブル作成パネルを開きます。
  8. [テーブルの作成元] で[Google Cloud Storage] を選択します。
  9. [GCS バケットからファイルを選択]フィールドに、「gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt」と入力します。
  10. ファイル形式ドロップダウンで「JSONL」を選択します。
  11. [テーブル名]に「recommendations_table」と入力します。
  12. [スキーマ] > [自動検出] > [スキーマと入力パラメータ]の下のボックスをオンにします。
  13. 「テーブルの作成」を選択します

サンプル データセットを探索する

この時点で、必要に応じてスキーマを探索し、このデータセットをプレビューすることができます。

  1. 左側のメニューでfirebase-recommendations-datasetを選択して、そこに含まれるテーブルを展開します。
  2. Recommendations-tableテーブルを選択して、テーブル スキーマを表示します。
  3. [プレビュー]を選択すると、このテーブルに含まれる実際の Analytics イベント データが表示されます。

サービスアカウントの資格情報を作成する

次に、Google Cloud コンソール プロジェクトでサービス アカウントの認証情報を作成します。これは、次の手順で Colab 環境で使用して、BigQuery データにアクセスして読み込むことができます。

  1. Google Cloud プロジェクトの課金が有効になっていることを確認してください。
  2. BigQuery および BigQuery Storage API API を有効にします。 <ここをクリック>
  3. 「サービス アカウント キーの作成」ページに移動します。
  4. [サービス アカウント]リストから、 [新しいサービス アカウント]を選択します。
  5. [サービス アカウント名]フィールドに名前を入力します。
  6. 「役割」リストから、 「プロジェクト」 > 「所有者」を選択します。
  7. 「作成」をクリックします。キーを含む JSON ファイルがコンピューターにダウンロードされます。

次のステップでは、Google Colab を使用してこのデータを前処理し、レコメンデーション モデルをトレーニングします。

11. データの前処理と推奨モデルのトレーニング

このステップでは、Colab ノートブックを使用して次の手順を実行します。

  1. BigQuery データを Colab ノートブックにインポートする
  2. データを前処理してモデルのトレーニングに備えます
  3. 分析データに基づいて推奨モデルをトレーニングする
  4. モデルを TF lite モデルとしてエクスポートします
  5. モデルを Firebase コンソールにデプロイして、アプリで使用できるようにします

Colab トレーニング ノートブックを起動する前に、まず Firebase Model Management API を有効にして、Colab がトレーニング済みモデルを Firebase コンソールにデプロイできるようにします。

Firebase モデル管理 API を有効にする

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

Firebase コンソールで、[ストレージ] に移動し、[開始する] をクリックします。 fbbea78f0eb3dc9f.png

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

19517c0d6d2aa14d.png

Firebase ML API を有効にする

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

Colab ノートブックを使用してモデルをトレーニングおよびデプロイする

次のリンクを使用して colab ノートブックを開き、その中の手順を完了します。 Colab ノートブックの手順を完了すると、アプリと同期できる TF lite モデル ファイルが Firebase コンソールにデプロイされます。

コラボで開く

12. アプリにモデルをダウンロードする

このステップでは、Firebase Machine Learning からトレーニングしたばかりのモデルをダウンロードするようにアプリを変更します。

Firebase ML 依存関係を追加する

アプリで Firebase Machine Learning モデルを使用するには、次の依存関係が必要です。すでに追加されているはずです (確認)。

app/build.grade.kts

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

Firebase Model Manager API を使用してモデルをダウンロードする

以下のコードをRecommendationClient.ktにコピーして、モデルのダウンロードが行われる条件を設定し、リモート モデルをアプリに同期するダウンロード タスクを作成します。

RecommendationClient.kt

    private fun downloadModel(modelName: String) {
        val conditions = CustomModelDownloadConditions.Builder()
            .requireWifi()
            .build()
        FirebaseModelDownloader.getInstance()
            .getModel(modelName, DownloadType.LOCAL_MODEL, conditions)
            .addOnCompleteListener {
                if (!it.isSuccessful) {
                    showToast(context, "Failed to get model file.")
                } else {
                    showToast(context, "Downloaded remote model: $modelName")
                    GlobalScope.launch { initializeInterpreter(it.result) }
                }
            }
            .addOnFailureListener {
                showToast(context, "Model download failed for recommendations, please check your connection.")
            }
    }

13. Tensorflow Lite 推奨モデルをアプリに統合する

Tensorflow Lite ランタイムを使用すると、アプリ内でモデルを使用して推奨事項を生成できます。前のステップでは、ダウンロードしたモデル ファイルを使用して TFlite インタープリターを初期化しました。このステップでは、まず推論ステップでモデルに付随する辞書とラベルをロードします。次に、モデルへの入力を生成する前処理と、推論から結果を抽出する後処理を追加します。 。

辞書とラベルをロードする

推奨モデルによって推奨候補を生成するために使用されるラベルは、res/assets フォルダー内のファイルsorted_movie_vocab.jsonにリストされています。次のコードをコピーして、これらの候補をロードします。

RecommendationClient.kt

    /** Load recommendation candidate list.  */
    private suspend fun loadCandidateList() {
        return withContext(Dispatchers.IO) {
            val collection = MovieRepository.getInstance(context).getContent()
            for (item in collection) {
                candidates[item.id] = item
            }
            Log.v(TAG, "Candidate list loaded.")
        }
    }

前処理の実装

前処理ステップでは、モデルが期待するものに一致するように入力データの形式を変更します。ここで、まだ多くのユーザーの「いいね!」を生成していない場合は、入力長にプレースホルダー値を埋め込みます。以下のコードをコピーします。

RecommendationClient.kt

    /** Given a list of selected items, preprocess to get tflite input.  */
    @Synchronized
    private suspend fun preprocess(selectedMovies: List<Movie>): IntArray {
        return withContext(Dispatchers.Default) {
            val inputContext = IntArray(config.inputLength)
            for (i in 0 until config.inputLength) {
                if (i < selectedMovies.size) {
                    val (id) = selectedMovies[i]
                    inputContext[i] = id
                } else {
                    // Padding input.
                    inputContext[i] = config.pad
                }
            }
            inputContext
        }
    }


インタープリターを実行して推奨事項を生成する

ここでは、前のステップでダウンロードしたモデルを使用して、前処理された入力に対して推論を実行します。モデルの入力と出力のタイプを設定し、推論を実行して映画の推奨事項を生成します。次のコードをアプリにコピーします。

RecommendationClient.kt

    /** Given a list of selected items, and returns the recommendation results.  */
    @Synchronized
    suspend fun recommend(selectedMovies: List<Movie>): List<Result> {
        return withContext(Dispatchers.Default) {
            val inputs = arrayOf<Any>(preprocess(selectedMovies))

            // Run inference.
            val outputIds = IntArray(config.outputLength)
            val confidences = FloatArray(config.outputLength)
            val outputs: MutableMap<Int, Any> = HashMap()
            outputs[config.outputIdsIndex] = outputIds
            outputs[config.outputScoresIndex] = confidences
            tflite?.let {
                it.runForMultipleInputsOutputs(inputs, outputs)
                postprocess(outputIds, confidences, selectedMovies)
            } ?: run {
                Log.e(TAG, "No tflite interpreter loaded")
                emptyList()
            }
        }
    }



後処理の実装

最後に、このステップではモデルからの出力を後処理し、最も信頼性の高い結果を選択し、含まれる値 (ユーザーがすでに気に入っている映画) を削除します。次のコードをアプリにコピーします。

RecommendationClient.kt

    /** Postprocess to gets results from tflite inference.  */
    @Synchronized
    private suspend fun postprocess(
        outputIds: IntArray, confidences: FloatArray, selectedMovies: List<Movie>
    ): List<Result> {
        return withContext(Dispatchers.Default) {
            val results = ArrayList<Result>()

            // Add recommendation results. Filter null or contained items.
            for (i in outputIds.indices) {
                if (results.size >= config.topK) {
                    Log.v(TAG, String.format("Selected top K: %d. Ignore the rest.", config.topK))
                    break
                }
                val id = outputIds[i]
                val item = candidates[id]
                if (item == null) {
                    Log.v(TAG, String.format("Inference output[%d]. Id: %s is null", i, id))
                    continue
                }
                if (selectedMovies.contains(item)) {
                    Log.v(TAG, String.format("Inference output[%d]. Id: %s is contained", i, id))
                    continue
                }
                val result = Result(
                    id, item,
                    confidences[i]
                )
                results.add(result)
                Log.v(TAG, String.format("Inference output[%d]. Result: %s", i, result))
            }
            results
        }
    }


アプリをテストしてみよう!

アプリを再実行します。いくつかの映画を選択すると、新しいモデルが自動的にダウンロードされ、推奨事項の生成が開始されます。

14. おめでとうございます!

TensorFlow Lite と Firebase を使用して、アプリにレコメンデーション機能を組み込みました。このコードラボで示されている手法とパイプラインは一般化して、他の種類の推奨事項を提供するためにも使用できることに注意してください。

私たちがカバーした内容

  • Firebase ML
  • Firebase アナリティクス
  • 分析イベントを BigQuery にエクスポートする
  • 分析イベントの前処理
  • 推奨事項 TensorFlow モデルをトレーニングする
  • モデルをエクスポートして Firebase コンソールにデプロイする
  • アプリで映画のおすすめを提供する

次のステップ

  • Firebase ML の推奨事項をアプリに実装します。

もっと詳しく知る

質問があります?

問題を報告する