1. 總覽
歡迎參加「使用 TensorFlow Lite 和 Firebase 進行推薦」程式碼研究室。在本程式碼研究室中,您將瞭解如何使用 TensorFlow Lite 和 Firebase,將建議模型部署至應用程式。本程式碼研究室以這個 TensorFlow Lite 範例為基礎。
應用程式可透過建議功能,運用機器學習技術,為每位使用者放送最相關的內容。系統會考量過去的使用者行為,並運用以大量其他使用者匯總行為訓練的模型,建議使用者未來可能感興趣的應用程式內容。
本教學課程說明如何使用 Firebase Analytics 取得應用程式使用者的資料、根據這些資料建構機器學習模型以提供建議,然後在 Android 應用程式中使用該模型執行推論並取得建議。具體來說,我們會根據使用者先前喜歡的電影清單,推薦他們最有可能觀看的電影。
課程內容
- 在 Android 應用程式中整合 Firebase Analytics,收集使用者行為資料
- 將該資料匯出至 Google BigQuery
- 預先處理資料並訓練 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
目錄 ( ) (依序點選「File」 >「Open」 > .../codelab-recommendations-android/start)。
您現在應該已在 Android Studio 中開啟起始專案。
4. 建立 Firebase 控制台專案
建立新專案
- 前往 Firebase 控制台。
- 選取「新增專案」 (如果是第一個專案,則選取「建立專案」)。
- 選取或輸入專案名稱,然後按一下「繼續」。
- 確認已啟用「為這項專案啟用 Google Analytics」。
- 按照 Firebase 控制台中的剩餘設定步驟操作,然後按一下「建立專案」(如果您使用現有的 Google 專案,則為「新增 Firebase」)。
5. 新增 Firebase
- 在新的專案總覽畫面中,按一下 Android 圖示來啟動設定工作流程。
- 輸入程式碼研究室的套件名稱:
com.google.firebase.codelabs.recommendations
- 選取「註冊應用程式」。
將 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 工具列中,依序選取「File」>「Sync Project with Gradle Files」。
6. 執行範例應用程式
將專案匯入 Android Studio 並使用 JSON 檔案設定 google-services
外掛程式後,即可首次執行應用程式。連線至 Android 裝置,然後按一下 Android Studio 工具列中的「Run」 ( )。
應用程式應會在裝置上啟動。此時,您會看到一個運作中的應用程式,其中包含顯示電影清單的分頁、顯示喜愛電影的分頁,以及顯示推薦內容的分頁。只要按一下電影清單中的電影,即可將其加入「喜歡」清單。完成本程式碼研究室的其餘步驟後,我們就能在「建議」分頁中產生電影建議。
7. 在應用程式中新增 Firebase Analytics
在這個步驟中,您會在應用程式中加入 Firebase Analytics,記錄使用者行為資料 (在本例中,是指使用者喜歡的電影)。在後續步驟中,系統會彙整這些資料,用於訓練建議模型。
新增 Firebase Bill of Materials 和 Analytics 依附元件
如要將 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 函式和下列程式碼,在使用者按讚電影時註冊 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) {
...
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。為了進行偵錯,我們可以停用這項行為,在 Shell 中執行下列指令,即可即時查看記錄的事件。
航廈
adb shell setprop debug.firebase.analytics.app com.google.firebase.codelabs.recommendations
確認是否已產生 Analytics 事件
- 在 Android Studio 中開啟 Logcat 視窗,檢查應用程式的記錄。
- 將 Logcat 篩選器設為「Logging event」字串。
- 確認每次在應用程式中對電影按讚時,系統都會發出「select_item」Analytics 事件。
到目前為止,您已成功將 Firebase Analytics 整合至應用程式。使用者使用應用程式並喜歡電影時,系統會記錄他們喜歡的電影。在本程式碼研究室的其餘部分,我們會使用這項匯總資料訓練建議模型。以下為選用步驟,可讓您在 Firebase 控制台中,看到與 Logcat 中相同的 Analytics 事件串流。請直接跳到下一頁。
選用:在 Firebase 控制台中確認 Analytics 事件
- 前往 Firebase 控制台。
- 在「Analytics」下方選取「DebugView」
- 在 Android Studio 中選取「Run」,啟動應用程式並將一些電影加入「喜歡」清單。
- 在 Firebase 主控台的 DebugView 中,確認系統會在您於應用程式中新增電影時記錄這些事件。
9. 將 Analytics 資料匯出至 BigQuery
BigQuery 是 Google Cloud 產品,可供您檢查及處理大量資料。在這個步驟中,您會將 Firebase 控制台專案連結至 BigQuery,以便將應用程式產生的 Analytics 資料自動匯出至 BigQuery。
啟用 BigQuery Export
- 前往 Firebase 控制台。
- 選取「專案總覽」旁的「設定」齒輪圖示,然後選取「專案設定」。
- 選取「整合」分頁標籤。
- 在「BigQuery」方塊中選取「連結」 (或「管理」)。
- 在「瞭解如何將 Firebase 連結至 BigQuery」步驟中,選取「下一步」。
- 在「設定整合」部分下方,按一下切換鈕,啟用傳送 Google Analytics 資料的功能,然後選取「連結至 BigQuery」。
您已啟用 Firebase 控制台專案,可自動將 Firebase Analytics 事件資料傳送至 BigQuery。系統會自動執行這項操作,不需要任何進一步互動,但首次匯出作業 (在 BigQuery 中建立 Analytics 資料集) 可能需要 24 小時。建立資料集後,Firebase 會持續將新的 Analytics 事件匯出至 BigQuery 的當日資料表,並將過去幾天的事件歸入事件資料表。
訓練推薦模型需要大量資料。由於我們還沒有產生大量資料的應用程式,因此在下一個步驟中,我們會將範例資料集匯入 BigQuery,以供本教學課程的其餘部分使用。
10. 使用 BigQuery 取得模型訓練資料
Firebase 主控台已連結至 BigQuery,因此過一段時間後,應用程式的 Analytics 事件資料就會自動顯示在 BigQuery 主控台中。為了取得本教學課程的初始資料,我們將在本步驟中,將現有的範例資料集匯入 BigQuery 控制台,用於訓練建議模型。
將範例資料集匯入 BigQuery
- 前往 Google Cloud 控制台的「BigQuery」資訊主頁。
- 在選單中選取專案名稱。
- 在 BigQuery 左側導覽列底部選取專案名稱,即可查看詳細資料。
- 選取「建立資料集」,開啟資料集建立面板。
- 在「資料集 ID」中輸入「firebase_recommendations_dataset」,然後選取「建立資料集」。
- 新資料集會顯示在左側選單的專案名稱下方。請點選該服務。
- 選取「建立資料表」,開啟資料表建立面板。
- 在「Create table from」(使用下列資料建立資料表) 區段,選取「Google Cloud Storage」。
- 在「Select file from GCS bucket」(從 GCS bucket 選取檔案) 欄位中,輸入「gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt」。
- 在「File format」(檔案格式) 下拉式選單中選取「JSONL」。
- 在「Table name」(資料表名稱) 輸入「recommendations_table」。
- 勾選「結構定義」>「自動偵測」>「結構定義和輸入參數」下方的方塊
- 選取「建立資料表」
探索範例資料集
此時,您可以選擇探索結構定義並預覽這個資料集。
- 選取左選單中的「firebase-recommendations-dataset」,展開其中包含的表格。
- 選取「recommendations-table」資料表,即可查看資料表結構定義。
- 選取「預覽」,即可查看這個表格實際包含的 Analytics 事件資料。
建立服務帳戶憑證
接下來,我們會在 Google Cloud 控制台專案中建立服務帳戶憑證,以便在下個步驟中,於 Colab 環境存取及載入 BigQuery 資料。
- 請確認 Google Cloud 專案已啟用計費功能。
- 啟用 BigQuery 和 BigQuery Storage API。<按這裡>
- 前往「Create Service Account Key」(建立服務帳戶金鑰) 頁面。
- 從「Service account」(服務帳戶) 清單中選取「New service account」(新增服務帳戶)。
- 在 [Service account name] (服務帳戶名稱) 欄位中輸入一個名稱。
- 從 [Role] (角色) 清單中,選取 [Project] (專案) > [Owner] (擁有者)。
- 按一下「建立」,系統就會將含有金鑰的 JSON 檔案下載至您的電腦。
在下一個步驟中,我們會使用 Google Colab 預先處理這項資料,並訓練建議模型。
11. 預先處理資料並訓練推薦模型
在本步驟中,我們將使用 Colab 筆記本執行下列步驟:
- 將 BigQuery 資料匯入 Colab 筆記本
- 預先處理資料,準備用於模型訓練
- 根據 Analytics 資料訓練建議模型
- 將模型匯出為 TF Lite 模型
- 將模型部署至 Firebase 控制台,以便在應用程式中使用
在啟動 Colab 訓練筆記本之前,請先啟用 Firebase Model Management API,這樣 Colab 才能將訓練好的模型部署到 Firebase 控制台。
啟用 Firebase Model Management API
建立 bucket 來儲存機器學習模型
在 Firebase 控制台中前往「儲存空間」,然後按一下「開始使用」。
按照對話框的指示設定值區。
啟用 Firebase ML API
前往 Google Cloud 控制台的 Firebase ML API 頁面,然後按一下「啟用」。
使用 Colab 筆記本訓練及部署模型
使用下列連結開啟 Colab 筆記本,然後完成其中的步驟。完成 Colab 筆記本中的步驟後,您會將 TF Lite 模型檔案部署至 Firebase 控制台,我們可以將該檔案同步到應用程式。
在 Colab 中開啟
12. 在應用程式中下載模型
在這個步驟中,我們會修改應用程式,從 Firebase 機器學習下載剛訓練的模型。
新增 Firebase ML 依附元件
如要在應用程式中使用 Firebase 機器學習模型,必須加入下列依附元件 (應已新增,請確認)。
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 Analytics
- 將 Analytics 事件匯出至 BigQuery
- 預先處理 Analytics 事件
- 訓練建議事項 TensorFlow 模型
- 匯出模型並部署至 Firebase 控制台
- 在應用程式中提供電影推薦
後續步驟
- 在應用程式中導入 Firebase ML 建議。