使用 TensorFlow Lite 和 Firebase 向您的應用添加推薦 - Android Codelab

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

一、概述

歡迎使用 TensorFlow Lite 和 Firebase 代碼實驗室的建議。在此 Codelab 中,您將學習如何使用 TensorFlow Lite 和 Firebase 將推薦模型部署到您的應用。此代碼實驗室基於此 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 Analytics”。
  5. 按照 Firebase 控制台中的其餘設置步驟操作,然後點擊創建項目(或添加 Firebase,如果您使用的是現有的 Google 項目)。

5. 添加火力基地

  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 文件中(檢查以確認):

應用程序/build.grade

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

構建等級

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 設備,然後單擊運行( 執行.png ) 在 Android Studio 工具欄中。

該應用程序應在您的設備上啟動。此時,您可以看到一個正常運行的應用程序,該應用程序顯示一個帶有電影列表的選項卡、一個喜歡的電影選項卡和一個推薦選項卡。您可以單擊電影列表中的電影將其添加到您的喜歡列表中。完成 codelab 的其餘步驟後,我們將能夠在 Recommendations 選項卡中生成電影推薦。

7. 將 Firebase Analytics 添加到應用程序

在此步驟中,您將向應用添加 Firebase Analytics 以記錄用戶行為數據(在本例中,即用戶喜歡哪些電影)。這些數據將在未來的步驟中匯總用於訓練推薦模型。

添加 Firebase Analytics 依賴項

將 Firebase Analytics 添加到您的應用需要以下依賴項。它應該已經包含在 app/build.gradle 文件中(驗證)。

應用程序/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 集成

在這一步中,我們將在應用程序中生成分析事件並驗證它們是否被發送到 Firebase 控制台。

啟用分析調試日誌

Firebase Analytics 旨在最大限度地延長用戶電池壽命,並將在設備上批量處理事件,並且僅偶爾將它們發送到 Firebase。出於調試目的,我們可以通過在 shell 中運行以下命令來禁用此行為以查看實時記錄的事件。

終端

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

驗證是否生成了 Analytics 事件

  1. 在 Android Studio 中,打開 Logcat 窗口以檢查應用程序的日誌記錄。
  2. 將 Logcat 過濾器設置為字符串“Logging event”。
  3. 驗證每次您喜歡應用中的電影時都會發出“select_item”分析事件。

至此,您已成功將 Firebase Analytics 集成到您的應用中。當用戶使用您的應用並喜歡電影時,他們的喜歡將被匯總記錄。我們將在本 Codelab 的其餘部分中使用這些匯總數據來訓練我們的推薦模型。以下是一個可選步驟,用於查看您在 Logcat 中看到的相同 Analytics 事件也流式傳輸到 Firebase 控制台。隨意跳到下一頁。

可選:在 Firebase 控制台中確認 Analytics 事件

  1. 轉到Firebase 控制台
  2. 在 Analytics 下選擇DebugView
  3. 在 Android Studio 中,選擇運行以啟動應用程序並將一些電影添加到您的喜歡列表中。
  4. 在 Firebase 控制台的 DebugView 中,驗證這些事件是否在您在應用中添加電影時被記錄。

9. 將 Analytics 數據導出到 Big Query

Big Query 是一款 Google Cloud 產品,可讓您檢查和處理大量數據。在此步驟中,您會將 Firebase 控制台項目連接到 Big Query,以便您的應用生成的 Analytics 數據會自動導出到 Big Query。

啟用 Big Query 導出

  1. 轉到Firebase 控制台
  2. 選擇Project Overview旁邊的 Settings 齒輪圖標,然後選擇Project settings
  3. 選擇集成選項卡。
  4. BigQuery塊中選擇Link (或Manage )。
  5. 關於將 Firebase 鏈接到 BigQuery步驟中選擇下一步
  6. 配置集成部分下,單擊開關以啟用發送 Google Analytics 數據並選擇鏈接到 BigQuery

您現在已啟用 Firebase 控制台項目以自動將 Firebase Analytics 事件數據發送到 Big Query。這會在沒有任何進一步交互的情況下自動發生,但是,在 BigQuery 中創建分析數據集的第一次導出可能不會在 24 小時內發生。創建數據集後,Firebase 會不斷將新的 Analytics 事件導出到 Big Query 到日內表中,並將過去幾天的事件分組到事件表中。

訓練推薦模型需要大量數據。由於我們還沒有生成大量數據的應用,因此在下一步中,我們會將示例數據集導入 BigQuery 以用於本教程的其餘部分。

10、使用BigQuery獲取模型訓練數據

現在我們已連接 Firebase 控制台以導出到 BigQuery,我們的應用分析事件數據將在一段時間後自動顯示在 BigQuery 控制台中。為了為本教程的目的獲取一些初始數據,在此步驟中,我們會將現有示例數據集導入您的 BigQuery 控制台,以用於訓練我們的推薦模型。

將示例數據集導入 BigQuery

  1. 轉到 Google 雲控制台中的BigQuery儀表板。
  2. 在菜單中選擇您的項目名稱。
  3. 在 BigQuery 左側導航的底部選擇您的項目名稱以查看詳細信息。
  4. 選擇創建數據集以打開數據集創建面板。
  5. 輸入 'firebase_recommendations_dataset' 作為Dataset ID並選擇Create dataset
  6. 新數據集將顯示在項目名稱下的左側菜單中。點擊它。
  7. 選擇創建表以打開表創建面板。
  8. 對於從選擇“谷歌云存儲”創建表
  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 模型管理 API,以便 Colab 可以將訓練後的模型部署到我們的 Firebase 控制台。

啟用 Firebase 模型管理 API

創建一個存儲桶來存儲您的 ML 模型

在您的 Firebase 控制台中,轉到存儲並單擊開始。 fbbea78f0eb3dc9f.png

按照對話設置您的存儲桶。

19517c0d6d2aa14d.png

啟用 Firebase 機器學習 API

轉到 Google Cloud Console 上的Firebase ML API 頁面,然後單擊啟用。

使用 Colab notebook 訓練和部署模型

使用以下鏈接打開 colab 筆記本並完成其中的步驟。完成 Colab 筆記本中的步驟後,您將有一個 TF lite 模型文件部署到 Firebase 控制台,我們可以將其同步到我們的應用程序。

在 Colab 中打開

12. 在您的應用中下載模型

在這一步中,我們將修改我們的應用程序以下載我們剛剛從 Firebase 機器學習訓練的模型。

添加 Firebase ML 依賴項

為了在您的應用中使用 Firebase 機器學習模型,需要以下依賴項。它應該已經被添加(驗證)。

應用程序/build.grade

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

使用 Firebase 模型管理器 API 下載模型

將以下代碼複製到RecommendationClient.kt以設置發生模型下載的條件並創建下載任務以將遠程模型同步到我們的應用程序。

推薦客戶端.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文件中。複製以下代碼以加載這些候選者。

推薦客戶端.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.")
        }
    }

實施預處理

在預處理步驟中,我們更改輸入數據的形式以匹配我們模型的預期。在這裡,如果我們還沒有產生很多用戶喜歡,我們用佔位符值填充輸入長度。複製以下代碼:

推薦客戶端.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
        }
    }


運行解釋器以生成推薦

在這裡,我們使用我們在上一步中下載的模型來對我們的預處理輸入進行推理。我們為我們的模型設置輸入和輸出的類型並運行推理來生成我們的電影推薦。將以下代碼複製到您的應用程序中。

推薦客戶端.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()
            }
        }
    }



實施後處理

最後,在這一步中,我們對模型的輸出進行後處理,選擇置信度最高的結果並刪除包含的值(用戶已經喜歡的電影)。將以下代碼複製到您的應用程序中。

推薦客戶端.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 機器學習
  • Firebase 分析
  • 將分析事件導出到 BigQuery
  • 預處理分析事件
  • 訓練推薦 TensorFlow 模型
  • 導出模型並部署到 Firebase 控制台
  • 在應用程序中提供電影推薦

下一步

  • 在您的應用中實施 Firebase ML 建議。

學到更多

有一個問題?

報告問題