Google は、黒人コミュニティのための人種的公平の促進に取り組んでいます。詳細をご覧ください。

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

TensorFlowLiteとFirebasecodelabの推奨事項へようこそ。このコードラボでは、TensorFlowLiteとFirebaseを使用して推奨モデルをアプリにデプロイする方法を学習します。このコードラボは、このTensorFlowLiteの例に基づいています。

推奨事項により、アプリは機械学習を使用して、各ユーザーに最も関連性の高いコンテンツをインテリジェントに提供できます。過去のユーザーの行動を考慮に入れて、他の多数のユーザーの集合的な行動についてトレーニングされたモデルを使用して、ユーザーが将来対話したいアプリのコンテンツを提案します。

このチュートリアルでは、Firebase Analyticsを使用してアプリのユーザーからデータを取得し、そのデータから推奨事項の機械学習モデルを構築し、Androidアプリでそのモデルを使用して推論を実行し、推奨事項を取得する方法を示します。特に、私たちの推奨事項は、ユーザーが以前に気に入った映画のリストを考えると、ユーザーが最も見そうな映画を提案します。

あなたが学ぶこと

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

必要なもの

  • AndroidStudioバージョン3.4以降。
  • サンプルコード。
  • Android2.3以降およびGooglePlayサービス9.8以降を搭載したテストデバイス、またはGooglePlayサービス9.8以降を搭載したエミュレーター
  • デバイスを使用する場合は、接続ケーブル。

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

読むだけそれを読んで、演習を完了してください

Androidアプリの作成経験をどのように評価しますか?

初心者中級熟練している

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

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

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

これで、AndroidStudioで開始プロジェクトを開く必要があります。

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

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

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

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

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

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

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

FirebaseAnalyticsの依存関係を追加する

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

app / build.grade

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

アプリでFirebaseAnalyticsを設定する

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)
        }
    }

このステップでは、アプリでアナリティクスイベントを生成し、それらがFirebaseConsoleに送信されていることを確認します。

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

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

ターミナル

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

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

  1. Android Studioで、Logcatウィンドウを開いて、アプリからのログを調べます。
  2. Logcatフィルターを文字列「Loggingevent」に設定します。
  3. アプリで映画が好きになるたびに、「select_item」アナリティクスイベントが発行されることを確認します。

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

オプション: FirebaseConsoleでアナリティクスイベントを確認する

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

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

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

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

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

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

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

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

  1. GoogleクラウドコンソールのBigQueryダッシュボードに移動します。
  2. メニューでプロジェクト名を選択します。
  3. 詳細を表示するには、BigQueryの左側のナビゲーションの下部でプロジェクト名を選択します。
  4. [データセットの作成]を選択して、データセット作成パネルを開きます
  5. データセットIDに「firebase_recommendations_dataset」と入力し、[データセットの作成]を選択します
  6. 新しいデータセットは、左側のメニューのプロジェクト名の下に表示されます。クリックして。
  7. [テーブルの作成]を選択して、テーブル作成パネルを開きます
  8. [テーブルの作成]で、 [Google CloudStorage]選択します。
  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. GoogleCloudプロジェクトで課金が有効になっていることを確認してください。
  2. BigQueryおよびBigQueryStorage APIAPIを有効にします。 <ここをクリック>
  3. [サービスアカウントキー作成]ページに移動します
  4. [サービスアカウント]リストから、[新しいサービスアカウント]を選択します
  5. サービスアカウント名」フィールドに名前を入力します。
  6. [役割]リストから、[プロジェクト] > [所有者]を選択します。
  7. [作成]をクリックします。コンピューターへのキーのダウンロードを含むJSONファイル。

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

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

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

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

Firebase Model ManagementAPIを有効にする

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

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

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

19517c0d6d2aa14d.png

Firebase MLAPIを有効にする

Google CloudConsoleのFirebaseML APIページに移動し、[有効にする]をクリックします。

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

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

Colabで開く

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

FirebaseMLの依存関係を追加する

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

app / build.grade

implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.4'

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

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

RecommendationClient.kt

    private fun downloadModel(modelName: String) {
        val remoteModel = FirebaseCustomRemoteModel.Builder(modelName).build()
        val firebaseModelManager = FirebaseModelManager.getInstance()
        firebaseModelManager
            .isModelDownloaded(remoteModel)
            .continueWithTask { task ->
                // Create update condition if model is already downloaded, otherwise create download
                // condition.
                val conditions = if (task.result != null && task.result == true) {
                    FirebaseModelDownloadConditions.Builder()
                        .requireWifi()
                        .build() // Update condition that requires wifi.
                } else {
                    FirebaseModelDownloadConditions.Builder().build(); // Download condition.
                }
                firebaseModelManager.download(remoteModel, conditions)
            }
            .addOnSuccessListener {
                firebaseModelManager.getLatestModelFile(remoteModel)
                    .addOnCompleteListener {
                        val model = it.result
                        if (model == null) {
                            showToast(context, "Failed to get model file.")
                        } else {
                            showToast(context, "Downloaded remote model")
                            GlobalScope.launch { initializeInterpreter(model) }
                        }
                    }
            }
            .addOnFailureListener {
                showToast(context, "Model download failed for recommendations, please check your connection.")
            }
    }



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
        }
    }


アプリをテストしてください!

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

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

私たちがカバーしたこと

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

次のステップ

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

もっと詳しく知る

質問があります?

問題を報告する