透過 TensorFlow Lite 和 Firebase 將建議新增至應用程式 - iOS 程式碼研究室

1. 總覽

歡迎來到「TensorFlow Lite 和 Firebase 的推薦功能」程式碼研究室。在本程式碼研究室中,您將瞭解如何使用 TensorFlow Lite 和 Firebase 在應用程式中部署建議模型。本程式碼研究室是以這個 TensorFlow Lite 範例為基礎。

推薦功能可讓應用程式運用機器學習技術,以智慧的方式為每位使用者提供最相關的內容。演算法會將使用者過往的行為納入考量,以根據大量其他使用者的匯總行為訓練而成的模型,推薦他們日後可能會與應用程式互動的內容。

本教學課程說明如何使用 Firebase Analytics 向應用程式使用者取得資料、根據這些資料建立建議的機器學習模型,然後在 iOS 應用程式中使用該模型進行推論並取得建議。具體而言,系統會根據使用者先前喜歡的電影清單,推薦使用者最有可能觀看哪些電影。

課程內容

  • 將 Firebase Analytics 整合至 Android 應用程式,收集使用者行為資料
  • 將資料匯出至 Google BigQuery
  • 預先處理資料並訓練 TF Lite 建議模型
  • 將 TF Lite 模型部署至 Firebase ML,並透過應用程式存取
  • 使用模型在裝置端進行推論,以便向使用者提供建議

事前準備

  • Xcode 11 (或更高版本)
  • CocoaPods 1.9.1 (或更高版本)

您會如何使用這個教學課程?

僅供閱讀 閱讀並完成練習

針對開發 iOS 應用程式的經驗,你會給予什麼評價?

新手 中級 還算容易

2. 建立 Firebase 控制台專案

將 Firebase 新增至專案

  1. 前往 Firebase 控制台
  2. 選取「Create New Project」,然後將專案命名為「Firebase ML iOS Codelab」。

3. 取得範例專案

下載程式碼

請先複製範例專案,然後在專案目錄中執行 pod update

git clone https://github.com/FirebaseExtended/codelab-contentrecommendation-ios.git
cd codelab-contentrecommendation-ios/start
pod install --repo-update

如果您尚未安裝 Git,也可以從其 GitHub 頁面下載範例專案,或點選這個連結。下載專案後,請在 Xcode 中執行專案,並嘗試根據建議來操作專案。

設定 Firebase

請按照說明文件建立新的 Firebase 專案。取得專案後,請從 Firebase 控制台下載專案的 GoogleService-Info.plist 檔案,然後拖曳至 Xcode 專案的根目錄。

4a923d5c7ae0d8f3.png

將 Firebase 新增至 Podfile,然後執行 Pod 安裝作業。

pod 'FirebaseAnalytics'
pod 'FirebaseMLModelDownloader', '9.3.0-beta'
pod 'TensorFlowLiteSwift'

AppDelegatedidFinishLaunchingWithOptions 方法中,於檔案頂端匯入 Firebase

import FirebaseCore

新增用來設定 Firebase 的呼叫。

FirebaseApp.configure()

再次執行專案,確認應用程式設定正確無誤,且在啟動時不會異常終止。

  1. 確定「為這項專案啟用 Google Analytics」
  2. 按照 Firebase 控制台中的其餘設定步驟操作,然後按一下「建立專案」(如果您使用現有的 Google 專案,請按一下「新增 Firebase」)。

4. 將 Firebase Analytics 加入應用程式

在這個步驟中,您需要在應用程式中新增 Firebase Analytics,以便記錄使用者行為資料 (在本例中,使用者喜歡的電影)。這類資料會在後續步驟中匯總,用來訓練建議模型。

在應用程式中設定 Firebase Analytics

LikedMoviesViewModel 包含用來儲存使用者喜歡的電影的函式。每當使用者喜歡一部新電影時,我們也想傳送分析記錄事件,以便記錄這類情況。

新增以下程式碼,即可在使用者點按「喜歡」電影時登錄 Analytics 事件。

AllMoviesCollectionViewController.swift

import FirebaseAnalytics
//


override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//

if movie.liked == nil {
      movie.liked = true
      Analytics.logEvent(AnalyticsEventSelectItem, parameters: [AnalyticsParameterItemID: movie.id])
    } else {
      movie.liked?.toggle()
    }
       
}

5. 測試 Analytics 整合

在這個步驟中,我們會在應用程式中產生 Analytics 事件,並驗證這些事件是否傳送至 Firebase 控制台。

啟用 Analytics 偵錯記錄

一般來說,應用程式記錄的事件會在約一小時內以批次方式上傳,然後一起上傳。這個方式能節省使用者並減少網路數據用量但為了驗證分析導入結果 (以及為了在 DebugView 報表中查看分析),您可以在開發裝置上啟用偵錯模式,以最短的延遲時間上傳事件。

如要在開發裝置上啟用 Analytics 偵錯模式,請在 Xcode 中指定下列指令列引數:

-FIRDebugEnabled

此時,您已成功將 Firebase Analytics 整合至應用程式。隨著使用者使用您的應用程式及對電影表示喜歡,系統會匯總他們對這些歌曲的喜歡記錄。我們會在本程式碼研究室的其餘部分,使用這些匯總資料訓練推薦模型。您可以透過下列選用步驟,查看在 Logcat 中看到的相同 Analytics 事件也會串流至 Firebase 控制台。您可以跳到下一頁。

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

  1. 前往 Firebase 控制台
  2. 選取 Analytics 下方的「DebugView」
  3. 在 Xcode 中,選取「Run」啟動應用程式,並將一些電影加入「已按讚」清單。
  4. 在 Firebase 控制台的 DebugView 中,確認當您在應用程式中新增電影時,系統會記錄這些事件。

6. 將 Analytics 資料匯出至 BigQuery

BigQuery 是 Google Cloud 產品,可讓您檢查及處理大量資料。在這個步驟中,您將將 Firebase 控制台專案連結至 BigQuery,讓系統將應用程式產生的 Analytics 資料自動匯出至 BigQuery。

啟用 BigQuery 匯出功能

  1. 前往 Firebase 控制台
  2. 選取「Project Overview」旁邊的「設定」齒輪圖示,然後選取「專案設定」
  3. 選取「Integrations」分頁標籤。
  4. 在「BigQuery」區塊中選取「Link」或「Manage」
  5. 在「關於將 Firebase 連結至 BigQuery」步驟中,選取「下一步」。
  6. 在「設定整合」部分下方,按一下切換按鈕來啟用傳送 Google Analytics 資料的功能,然後選取「連結至 BigQuery」

您現已啟用 Firebase 控制台專案,可自動將 Firebase Analytics 事件資料傳送至 BigQuery。系統會自動執行這項程序,您不需要進行任何進一步的互動,但首次在 BigQuery 中建立數據分析資料集的匯出作業,可能不會在 24 小時內發生。建立資料集後,Firebase 會持續將新的 Analytics 事件匯出至 BigQuery,並彙整到當日資料表,並在事件資料表中將過去幾天的事件分組。

訓練建議模型需要大量資料。由於我們還沒有應用程式產生大量資料,因此我們會在下一個步驟中將範例資料集匯入 BigQuery,以便在本教學課程的後續部分中使用。

7. 使用 BigQuery 取得模型訓練資料

我們已將 Firebase 控制台連結至 BigQuery,應用程式分析事件資料會在一段時間後自動顯示在 BigQuery 控制台中。為了達成本教學課程的目的而取得一些初始資料,在這個步驟中,我們會將現有的範例資料集匯入您的 BigQuery 控制台,用來訓練建議模型。

將範例資料集匯入 BigQuery

  1. 前往 Google Cloud 控制台的 BigQuery 資訊主頁。
  2. 在選單中選取專案名稱。
  3. 在 BigQuery 左側導覽面板的底部選取專案名稱即可查看詳細資料。
  4. 選取「建立資料集」,開啟資料集建立面板。
  5. 輸入「firebase_recommendations_dataset」「資料集 ID」並選取「建立資料集」
  6. 新資料集會顯示在左選單中的專案名稱下方。請點選該服務。
  7. 選取「建立資料表」,開啟資料表建立面板。
  8. 在「Create table from」(使用下列資料建立資料表) 部分,選取「Google Cloud Storage」。
  9. 在「Select file from GCS bucket」(從 GCS 值區選取檔案) 欄位中,輸入「gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt」。
  10. 選取「JSONL」[檔案格式] 下拉式選單中。
  11. 輸入「recommendations_table」「Table name」(資料表名稱) 區段。
  12. 勾選「結構定義 > 下方的」方塊自動偵測 >結構定義和輸入參數
  13. 選取「建立資料表」

探索範例資料集

此時,您可以選擇探索結構定義,並預覽這個資料集。

  1. 選取左選單中的「firebase-recommendations-dataset」,展開內含的資料表。
  2. 選取 recommendations-table 資料表來查看資料表結構定義。
  3. 選取「預覽」即可查看這個表格包含的實際 Analytics 事件資料。

建立服務帳戶憑證

現在,我們會在 Google Cloud 控制台專案中建立服務帳戶憑證,以便在後續步驟中使用 Colab 環境存取及載入 BigQuery 資料。

  1. 請確認 Google Cloud 專案已啟用計費功能。
  2. 啟用 BigQuery 和 BigQuery Storage API。<按這裡>
  3. 前往「建立服務帳戶金鑰」頁面
  4. 在「服務帳戶」清單中,選取「新增服務帳戶」
  5. 在 [Service account name] (服務帳戶名稱) 欄位中輸入一個名稱。
  6. 從 [Role] (角色) 清單中,選取 [Project] (專案) > [Owner] (擁有者)
  7. 點選「建立」。系統會將包含金鑰的 JSON 檔案下載到電腦。

在下一個步驟中,我們會使用 Google Colab 預先處理這類資料並訓練推薦模型。

8. 預先處理資料並訓練建議模型

在這個步驟中,我們會使用 Colab 筆記本執行下列步驟:

  1. 將 BigQuery 資料匯入 Colab 筆記本
  2. 預先處理資料,以便進行模型訓練
  3. 根據數據分析資料訓練建議模型
  4. 將模型匯出為 TF lite 模型
  5. 將模型部署至 Firebase 控制台,以便我們在應用程式中使用

推出 Colab 訓練筆記本前,我們會先啟用 Firebase Model Management API,讓 Colab 將經過訓練的模型部署至 Firebase 控制台。

啟用 Firebase Model Management API

建立值區來儲存機器學習模型

在 Firebase 控制台中,前往「儲存空間」並點選「開始使用」。fbbea78f0eb3dc9f.png

按照對話方塊的指示設定值區。

19517c0d6d2aa14d.png

啟用 Firebase ML API

前往 Google Cloud 控制台的 Firebase ML API 頁面,然後按一下「啟用」。

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

使用下方連結開啟 Colab 筆記本,並完成其中中的步驟。完成 Colab 筆記本中的步驟後,系統會將 TF lite 模型檔案部署至 Firebase 主控台,以便同步至應用程式。

在 Colab 中開啟

9. 在應用程式中下載模型

在這個步驟中,我們會修改應用程式,以下載剛剛透過 Firebase 機器學習訓練的模型。

新增 Firebase ML 依附元件

您必須具備下列依附元件,才能在應用程式中使用 Firebase 機器學習模型。系統應已新增過該轉換 (需進行驗證)。

Podfile

import FirebaseCore
import FirebaseMLModelDownloader

使用 Firebase Model Manager API 下載模型

將下方程式碼複製到 ModelLoader.swift,設定模型下載作業的執行條件並建立下載工作,將遠端模型同步到應用程式。

ModelLoader.swift

static func downloadModel(named name: String,
                            completion: @escaping (CustomModel?, DownloadError?) -> Void) {
    guard FirebaseApp.app() != nil else {
      completion(nil, .firebaseNotInitialized)
      return
    }
    guard success == nil && failure == nil else {
      completion(nil, .downloadInProgress)
      return
    }
    let conditions = ModelDownloadConditions(allowsCellularAccess: false)
    ModelDownloader.modelDownloader().getModel(name: name, downloadType: .localModelUpdateInBackground, conditions: conditions) { result in
            switch (result) {
            case .success(let customModel):
                    // Download complete.
                    // The CustomModel object contains the local path of the model file,
                    // which you can use to instantiate a TensorFlow Lite classifier.
                    return completion(customModel, nil)
            case .failure(let error):
                // Download was unsuccessful. Notify error message.
              completion(nil, .downloadFailed(underlyingError: error))
            }
    }
  }

10. 在應用程式中整合 Tensorflow Lite 推薦模型

你可以透過 Tensorflow Lite 執行階段,在應用程式中使用模型來產生建議。在上一步中,我們使用下載的模型檔案初始化了 TFlite 翻譯器。在這個步驟中,我們會先載入字典和標籤,以在推論步驟中搭配我們的模型,然後加入預先處理作業,為模型產生輸入內容並進行後續處理,接著從推論中擷取結果。

載入字典和標籤

建議模型用來產生建議模型的建議標籤會列在素材資源資料夾中的 sorted_movie_vocab.json 檔案。複製下列程式碼即可載入這些候選項目。

RecommendationsViewController.swift

  func getMovies() -> [MovieItem] {
    let barController = self.tabBarController as! TabBarController
    return barController.movies
  }

實作預先處理功能

在預先處理步驟中,我們會變更輸入資料的格式,以符合模型的預期。如果系統尚未產生大量使用者喜歡,這裡會以預留位置值填入輸入長度。複製下方的程式碼:

RecommendationsViewController.swift

  // Given a list of selected items, preprocess to get tflite input.
  func preProcess() -> Data {
    let likedMovies = getLikedMovies().map { (MovieItem) -> Int32 in
      return MovieItem.id
    }
    var inputData = Data(copyingBufferOf: Array(likedMovies.prefix(10)))

    // Pad input data to have a minimum of 10 context items (4 bytes each)
    while inputData.count < 10*4 {
      inputData.append(0)
    }
    return inputData
  }

執行口譯以產生建議

這裡,我們使用上一個步驟下載的模型,對預先處理的輸入內容執行推論。我們會設定模型的輸入和輸出類型,然後進行推論以產生電影推薦內容。將下列程式碼複製到您的應用程式中。

RecommendationsViewController.swift

import TensorFlowLite

RecommendationsViewController.swift

 private var interpreter: Interpreter?

 func loadModel() {
    // Download the model from Firebase
    print("Fetching recommendations model...")
    ModelDownloader.fetchModel(named: "recommendations") { (filePath, error) in
      guard let path = filePath else {
        if let error = error {
          print(error)
        }
        return
      }
      print("Recommendations model download complete")
      self.loadInterpreter(path: path)
    }
  }

 func loadInterpreter(path: String) {
    do {
      interpreter = try Interpreter(modelPath: path)

      // Allocate memory for the model's input `Tensor`s.
      try interpreter?.allocateTensors()

      let inputData = preProcess()

      // Copy the input data to the input `Tensor`.
      try self.interpreter?.copy(inputData, toInputAt: 0)

      // Run inference by invoking the `Interpreter`.
      try self.interpreter?.invoke()

      // Get the output `Tensor`
      let confidenceOutputTensor = try self.interpreter?.output(at: 0)
      let idOutputTensor = try self.interpreter?.output(at: 1)

      // Copy output to `Data` to process the inference results.
      let confidenceOutputSize = confidenceOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let idOutputSize = idOutputTensor?.shape.dimensions.reduce(1, {x, y in x * y})

      let confidenceResults =
        UnsafeMutableBufferPointer<Float32>.allocate(capacity: confidenceOutputSize!)
      let idResults =
        UnsafeMutableBufferPointer<Int32>.allocate(capacity: idOutputSize!)
      _ = confidenceOutputTensor?.data.copyBytes(to: confidenceResults)
      _ = idOutputTensor?.data.copyBytes(to: idResults)

      postProcess(idResults, confidenceResults)

      print("Successfully ran inference")
      DispatchQueue.main.async {
        self.tableView.reloadData()
      }
    } catch {
      print("Error occurred creating model interpreter: \(error)")
    }
  }

實作後續處理

最後,在這個步驟中,我們會對模型的輸出結果進行後續處理,選取可信度最高的結果,並移除包含的值 (使用者已喜歡的電影)。將下列程式碼複製到您的應用程式中。

RecommendationsViewController.swift

  // Postprocess to get results from tflite inference.
  func postProcess(_ idResults: UnsafeMutableBufferPointer<Int32>, _ confidenceResults: UnsafeMutableBufferPointer<Float32>) {
    for i in 0..<10 {
      let id = idResults[i]
      let movieIdx = getMovies().firstIndex { $0.id == id }
      let title = getMovies()[movieIdx!].title
      recommendations.append(Recommendation(title: title, confidence: confidenceResults[i]))
    }
  }

測試應用程式!

重新執行應用程式。當你選取幾部電影時,系統應會自動下載新模型並開始產生推薦內容!

11. 恭喜!

你已使用 TensorFlow Lite 和 Firebase,在應用程式中建構建議功能。請注意,本程式碼研究室提及的技巧和管道可一般化,也可用於提供其他類型的建議。

涵蓋內容

  • Firebase ML
  • Firebase Analytics
  • 將數據分析事件匯出至 BigQuery
  • 預先處理數據分析事件
  • 訓練建議 TensorFlow 模型
  • 匯出模型並部署至 Firebase 控制台
  • 在應用程式中推薦電影

後續步驟

  • 在應用程式中導入 Firebase 機器學習建議。

瞭解詳情

有任何疑問嗎?

回報問題