使用 TensorFlow Lite 和 Firebase 將推薦添加到您的應用程式 - Android Codelab

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版本。
  • 範例程式碼。
  • 配備 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 Analytics」。
  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.kts 檔案(檢查以確認):

應用程式/build.grade.kts

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

建造.等級.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 工具列中。

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

7. 將 Firebase Analytics 新增至應用程式

在此步驟中,您將向應用程式新增 Firebase Analytics 以記錄使用者行為資料(在本例中為使用者喜歡的影片)。這些數據將在未來的步驟中匯總使用來訓練推薦模型。

新增 Firebase 物料清單和分析依賴項

要將 Firebase Analytics 新增至您的應用,需要以下相依性。它們應該已經包含在 app/build.gradle.kts 檔案中(驗證)。

應用程式/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。出於調試目的,我們可以透過在 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」Analytics 事件。

至此,您已成功將 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. 選擇“項目概述”旁邊的“設定”齒輪圖標,然後選擇“項目設定”
  3. 選擇整合選項卡。
  4. BigQuery區塊內選擇「連結」 (或「管理」)。
  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' 作為資料集 ID ,然後選擇建立資料集
  6. 新資料集將顯示在項目名稱下的左側選單中。點擊它。
  7. 選擇建立表格以開啟表格建立面板。
  8. 對於建立表,請選擇「Google 雲端儲存」。
  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 事件資料。

建立服務帳戶憑證

現在,我們將在 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 ML API

前往 Google Cloud Console 上的Firebase ML API 頁面,然後按一下啟用。

使用Colab筆記本訓練和部署模型

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

在 Colab 中打開

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

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

新增 Firebase ML 依賴項

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

應用程式/build.grade.kts

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

使用 Firebase Model Manager 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 在您的應用程式中建立了推薦功能。請注意,此 Codelab 中顯示的技術和流程也可以推廣並用於提供其他類型的推薦。

我們涵蓋的內容

  • Firebase 機器學習
  • Firebase 分析
  • 將分析事件匯出到 BigQuery
  • 預處理分析事件
  • 訓練推薦 TensorFlow 模型
  • 匯出模型並部署到 Firebase 控制台
  • 在應用程式中提供電影推薦

下一步

  • 在您的應用程式中實作 Firebase ML 建議。

了解更多

有一個問題?

報告問題