TensorFlowLiteとFirebaseを使用してアプリに推奨事項を追加する-AndroidCodelab

1。概要

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

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

このチュートリアルでは、Firebase Analytics を使用してアプリのユーザーからデータを取得し、そのデータからレコメンデーション用の機械学習モデルを構築し、そのモデルを Android アプリで使用して推論を実行し、レコメンデーションを取得する方法を示します。特に、私たちのおすすめは、ユーザーが以前に好きだった映画のリストを考慮して、ユーザーが見る可能性が最も高い映画を提案します。

学習内容

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

必要なもの

  • Android Studio バージョン 3.4 以降。
  • サンプルコード。
  • Android 2.3+ および 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. Codelab のパッケージ名を入力します: 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 ファイルに既に追加されているはずです (チェックして確認してください)。

app/build.grade

apply plugin: 'com.google.gms.google-services'

build.grade

classpath 'com.google.gms:google-services:4.3.13'

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

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

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

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

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

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

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

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

アプリに Firebase Analytics を追加するには、次の依存関係が必要です。 app/build.gradle ファイルに既に含まれている必要があります (検証)。

app/build.grade

implementation 'com.google.firebase:firebase-analytics-ktx:21.1.0'

アプリで 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 コンソールに送信されていることを確認します。

Analytics デバッグ ログを有効にする

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

「ターミナル」

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

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

  1. Android Studio で Logcat ウィンドウを開き、アプリからのログを調べます。
  2. Logcat フィルターを文字列 "Logging event" に設定します。
  3. アプリで映画を高く評価するたびに「select_item」Analytics イベントが発行されることを確認します。

この時点で、Firebase Analytics がアプリに正常に統合されました。ユーザーがアプリを使用して映画を好きになると、好きなものが集計されます。この Codelab の残りの部分では、この集計データを使用してレコメンデーション モデルをトレーニングします。以下は、Logcat で見たのと同じ Analytics イベントが Firebase コンソールにもストリーミングされることを確認するためのオプションの手順です。次のページにスキップしてください。

オプション: Firebase コンソールで Analytics イベントを確認する

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

9. アナリティクス データを Big Query にエクスポートする

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

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

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

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

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

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

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

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

  1. Google クラウド コンソールのBigQueryダッシュボードに移動します。
  2. メニューでプロジェクト名を選択します。
  3. 詳細を表示するには、BigQuery の左側のナビゲーションの下部にあるプロジェクト名を選択します。
  4. [データセットの作成] を選択して、データセット作成パネルを開きます
  5. データセット IDに「firebase_recommendations_dataset」と入力し、[ Create 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. レコメンデーション テーブルテーブルを選択して、テーブル スキーマを表示します。
  3. [プレビュー]を選択して、このテーブルに含まれる実際の Analytics イベント データを確認します。

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

ここで、次のステップで Colab 環境で BigQuery データにアクセスして読み込むために使用できる、Google Cloud コンソール プロジェクトでサービス アカウント資格情報を作成します。

  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 コンソールにデプロイされます。

Colab で開く

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

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

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

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

app/build.grade

implementation 'com.google.firebase:firebase-ml-modeldownloader:24.0.4'

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 を使用して、おすすめ機能をアプリに組み込みました。この Codelab で示されている手法とパイプラインは一般化して、他のタイプのレコメンデーションにも使用できることに注意してください。

カバーした内容

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

次のステップ

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

もっと詳しく知る

質問があります?

問題を報告する