將 Firebase 添加到基於 TFLite 的 Android 應用

一、概述

cd824ecfd05a2822.png

Firebase ML 使您能夠通過無線方式部署模型。這使您可以保持應用程序較小,僅在需要時下載 ML 模型、試驗多個模型或更新您的 ML 模型,而無需重新發​​布整個應用程序。

在此 Codelab 中,您將使用靜態 TFLite 模型的 Android 應用程序轉換為使用 Firebase 動態提供的模型的應用程序。

你會學到什麼

  • 將 TFLite 模型部署到 Firebase ML 並從您的應用訪問它們
  • 使用 Firebase Analytics 跟踪用戶反饋以衡量模型的準確性
  • 通過 Firebase 性能分析模型性能
  • 選擇通過遠程配置加載多個部署模型中的哪一個
  • 通過 Firebase A/B 測試試驗不同的模型

你需要什麼

  • 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-digitclassifier-android.git

如果您沒有安裝 git,您也可以從其 GitHub 頁面或單擊此鏈接下載示例項目。

3. 導入入門應用

在 Android Studio 中,選擇codelab-digitclassifier-android目錄( android_studio_folder.png )從示例代碼下載(文件>打開> .../codelab-digitclassifier-android/start)。

您現在應該在 Android Studio 中打開了啟動項目。

4. 運行入門應用

現在您已將項目導入 Android Studio,您已準備好首次運行該應用程序。連接您的 Android 設備,然後單擊運行( 執行.png ) 在 Android Studio 工具欄中。

該應用程序應在您的設備上啟動。此時,如果您嘗試繪製一個數字,應用程序應該能夠識別它。

6e36e1b947b395f2.png

5. 創建 Firebase 控制台項目

將 Firebase 添加到項目中

  1. 轉到Firebase 控制台
  2. 選擇添加項目
  3. 選擇或輸入項目名稱。
  4. 按照 Firebase 控制台中的其餘設置步驟操作,然後點擊創建項目(或添加 Firebase,如果您使用的是現有的 Google 項目)。

6. 添加火力基地

  1. 在新項目的概覽​​屏幕中,單擊 Android 圖標以啟動設置工作流程。
  2. 輸入codelab的包名: org.tensorflow.lite.examples.digitclassifier

將 google-services.json 文件添加到您的應用

註冊包名稱並選擇下一步後,單擊下載 google-services.json以獲取您的 Firebase Android 配置文件,然後將 google-services.json 文件複製到項目中的app目錄中。下載文件後,您可以跳過控制台中顯示的後續步驟(它們已經在 build-android-start 項目中為您完成)。

將 google-services 插件添加到您的應用

google-services 插件使用 google-services.json 文件將您的應用程序配置為使用 Firebase。將以下行添加到項目app目錄中 build.gradle 文件的頂部:

應用程序/build.gradle

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

然後將以下行添加到項目中 build.gradle 文件的dependencies項部分:

項目/build.gradle

classpath 'com.google.gms:google-services:4.3.3'

將您的項目與 gradle 文件同步

為確保您的應用程序可以使用所有依賴項,此時您應該將項目與 gradle 文件同步。從 Android Studio 工具欄中選擇File > Sync Project with Gradle Files

7. 使用 Firebase 運行應用

現在您已經使用 JSON 文件配置了google-services插件,您可以使用 Firebase 運行該應用程序了。連接您的 Android 設備,然後單擊運行( 執行.png ) 在 Android Studio 工具欄中。

該應用程序應在您的設備上啟動。此時,您的應用程序應該仍然可以成功構建。

8. 將模型部署到 Firebase ML

將模型部署到 Firebase ML 非常有用,主要有兩個原因:

  1. 我們可以保持應用程序安裝大小較小,僅在需要時下載模型
  2. 該模型可以定期更新,並且發布週期與整個應用程序不同

在我們可以將應用中的靜態模型替換為從 Firebase 動態下載的模型之前,我們需要將其部署到 Firebase ML。該模型可以通過控制台部署,也可以使用 Firebase Admin SDK 以編程方式部署。在這一步中,我們將通過控制台進行部署。

為簡單起見,我們將使用我們應用中已有的 TensorFlow Lite 模型。首先,打開 Firebase 控制台並單擊左側導航面板中的機器學習。如果您是第一次打開,請單擊“開始”。然後導航到“自定義”並單擊“添加自定義模型”按鈕。

出現提示時,給模型起一個描述性名稱,例如mnist_v1 ,然後從 codelab 項目目錄的start/app/src/main/assets/mnist.tflite下上傳文件。然後你可以從 Android 項目中刪除這個 TF Lite 模型文件。

3c3c50e6ef12b3b.png

9. 從 Firebase ML 下載模型

選擇何時將遠程模型從 Firebase 下載到您的應用中可能會很棘手,因為 TFLite 模型可能會變得相對較大。理想情況下,我們希望避免在應用程序啟動時立即加載模型,因為如果我們的模型僅用於一個功能並且用戶從不使用該功能,我們將無緣無故下載大量數據。我們還可以設置下載選項,例如僅在連接到 wifi 時獲取模型。如果您想確保模型在沒有網絡連接的情況下也可用,那麼在沒有應用程序的情況下捆綁它作為備份也很重要。

為簡單起見,我們將刪除默認捆綁模型,並始終在應用啟動時從 Firebase 下載模型。這樣,在運行數字識別時,您可以確保推理正在使用 Firebase 提供的模型運行。

在 app/build.gradle 文件中,添加 Firebase 機器學習依賴項

應用程序/build.gradle

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

然後添加邏輯以從 Firebase 下載模型。

我們將digitClassifier.initialize(loadModelFile())替換為downloadModel("mnist_v1")並實現此方法。

MainActivity.kt

  private fun setupDigitClassifier() {
    downloadModel("mnist_v1")
  }

  private fun downloadModel(modelName: String): Task<Void> {
    val remoteModel = FirebaseCustomRemoteModel.Builder(modelName).build()
    val firebaseModelManager = FirebaseModelManager.getInstance()
    return 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("Failed to get model file.")
            } else {
              showToast("Downloaded remote model: $model")
              digitClassifier.initialize(model)
            }
          }
      }
      .addOnFailureListener {
        showToast("Model download failed for digit classifier, please check your connection.")
      }
  }

重新運行您的應用程序並在數字分類器中繪製一個數字。下載完成後,您應該會看到一條提示遠程模型已下載的 Toast 消息,以及指示您的新模型正在使用的日誌。

10.跟踪用戶反饋和轉換以衡量模型準確性

Google Analytics for Firebase 為您提供了一種方法,讓您了解用戶在您的應用程序中的移動方式、他們在哪裡成功以及他們在哪里卡住並返回。它還可用於了解應用程序中最常用的部分。

我們將通過跟踪用戶對模型預測的反饋來衡量模型的準確性。如果用戶單擊“是”,則表明預測是準確的。

我們可以記錄一個分析事件來跟踪我們模型的準確性。首先,我們必須將 Analytics 添加到依賴項中,然後才能在項目中使用:

添加 Firebase Analytics 依賴項

應用程序/build.gradle

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

記錄事件

然後在onCreate函數中,我們將設置 onclick 偵聽器以將correct_inference事件記錄到 Firebase。

MainActivity.kt (onCreate)

// Setup YES button
yesButton?.setOnClickListener {
  Firebase.analytics.logEvent("correct_inference", null)
}

再次運行應用程序並繪製一個數字。按下“是”按鈕幾次以發送推斷是準確的反饋。

調試分析

通常,您的應用程序記錄的事件會在大約一小時的時間內一起批處理並一起上傳。這種方法可以節省最終用戶設備的電池電量並減少網絡數據使用量。但是,為了驗證您的分析實施(以及為了在 DebugView 報告中查看您的分析),您可以在開發設備上啟用調試模式以最小延遲上傳事件。

要在 Android 設備上啟用分析調試模式,請執行以下命令:

adb shell setprop debug.firebase.analytics.app org.tensorflow.lite.examples.digitclassifier

再次運行應用程序並繪製一個數字。按下“是”按鈕幾次以發送推斷是準確的反饋。現在,您可以通過 Firebase 控制台中的調試視圖近乎實時地查看日誌事件。從左側導航欄中單擊 Analytics > DebugView。

5276199a086721fd.png

11. 分析模型的性能

Firebase 性能監控是一項服務,可幫助您深入了解 iOS、Android 和 Web 應用的性能特徵。

您可以使用性能監控 SDK 從您的應用收集性能數據,然後在 Firebase 控制台中查看和分析這些數據。性能監控可幫助您了解可以在何處以及何時改進應用程序的性能,以便您可以使用該信息來解決性能問題。

在這裡,我們在推理和下載周圍添加性能跟踪

這很重要,因為深度學習中使用的較大模型可能更準確,但它們也可能需要更長的時間才能返迴響應。在我們的實驗中,我們試圖在準確性和速度之間找到適當的平衡。

添加 Firebase 性能依賴項

項目/build.gradle

buildscript {

  // ...

    dependencies {
      // ...

      // Add the dependency for the Performance Monitoring plugin
      classpath 'com.google.firebase:perf-plugin:1.3.1'  // Performance Monitoring plugin
    }
}

應用程序/build.gradle

// Apply the Performance Monitoring plugin
apply plugin: 'com.google.firebase.firebase-perf'

// ...

dependencies {
  // ...

  // Add the dependency for the Performance Monitoring library
  implementation 'com.google.firebase:firebase-perf:19.0.7'
}

添加自定義跟踪

setupDigitClassifier()函數中創建一個新的 downloadTrace,並在下載模型之前立即啟動它。然後添加一個 onsuccess 偵聽器停止跟踪。

classifyDrawing()函數中創建一個新的classifyTrace,並在分類之前啟動它。然後在 onsuccess 監聽器中停止跟踪。

MainActivity.kt

class MainActivity : AppCompatActivity() {
  // ...
  
  private val firebasePerformance = FirebasePerformance.getInstance()
  
  // ...

  private fun setupDigitClassifier() {
    // Add these lines to create and start the trace
    val downloadTrace = firebasePerformance.newTrace("download_model")
    downloadTrace.start()
    downloadModel("mnist_v1")
      // Add these lines to stop the trace on success
      .addOnSuccessListener {
        downloadTrace.stop()
      }
  }

// ...

  private fun classifyDrawing() {
    val bitmap = drawView?.getBitmap()

    if ((bitmap != null) && (digitClassifier.isInitialized)) {
      // Add these lines to create and start the trace
      val classifyTrace = firebasePerformance.newTrace("classify")
      classifyTrace.start()
      digitClassifier
        .classifyAsync(bitmap)
        .addOnSuccessListener { resultText -> 
          // Add this line to stop the trace on success
          classifyTrace.stop()
          predictedTextView?.text = resultText
        }
        .addOnFailureListener { e ->
          predictedTextView?.text = getString(
            R.string.tfe_dc_classification_error_message,
            e.localizedMessage
          )
          Log.e(TAG, "Error classifying drawing.", e)
        }
    }
  }

查看性能事件的日誌消息

  1. 通過將<meta-data>元素添加到應用的AndroidManifest.xml文件中,在構建時啟用性能監控的調試日誌記錄,如下所示:

AndroidManifest.xml

<application>
    <meta-data
      android:name="firebase_performance_logcat_enabled"
      android:value="true" />
</application>
  1. 檢查您的日誌消息中是否有任何錯誤消息。
  2. 性能監控使用FirebasePerformance標記其日誌消息。使用 logcat 過濾,您可以通過運行以下命令來專門查看持續時間跟踪和 HTTP/S 網絡請求日誌記錄:
adb logcat -s FirebasePerformance
  1. 檢查以下類型的日誌,這些日誌表明性能監控正在記錄性能事件:
  • Logging TraceMetric
  • Logging NetworkRequestMetric

12. 將第二個模型部署到 Firebase ML

當提出模型的新版本時,例如具有更好模型架構的模型或在更大或更新的數據集上訓練的模型,我們可能會想用新版本替換我們當前的模型。但是,在測試中表現良好的模型不一定在生產中表現同樣好。因此,讓我們在生產中進行 A/B 測試來比較我們的原始模型和新模型。

啟用 Firebase 模型管理 API

在這一步中,我們將啟用 Firebase 模型管理 API 以使用 Python 代碼部署新版本的 TensorFlow Lite 模型。

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

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

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

19517c0d6d2aa14d.png

啟用 Firebase 機器學習 API

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

2414fd5cced6c984.png詢問時選擇數字分類器應用程序。

訓練新模型並發佈到 Firebase ML

現在,我們將使用更大的數據集訓練模型的新版本,然後使用 Firebase Admin SDK 直接從訓練筆記本以編程方式部署它。

下載服務帳戶的私鑰

在我們可以使用 Firebase Admin SDK 之前,我們需要創建一個服務帳戶。單擊此鏈接打開 Firebase 控制台的服務帳戶面板,然後單擊按鈕為 Firebase Admin SDK 創建一個新的服務帳戶。出現提示時,單擊“生成新私鑰”按鈕。我們將使用服務帳戶密鑰來驗證來自 colab 筆記本的請求。

c3b95de1e5508516.png

現在我們可以訓練和部署新模型了。

  1. 打開這個colab notebook並在你自己的 Drive 下複製一份。
  2. 通過單擊左側的播放按鈕運行第一個單元格“訓練改進的 TensorFlow Lite 模型”。這將訓練一個新模型,可能需要一些時間。
  3. 運行第二個單元格將創建一個文件上傳提示。上傳您在創建服務帳戶時從 Firebase 控制台下載的 json 文件。

71e847c6a85423b3.png

  1. 運行最後兩個單元格。

運行 colab 筆記本後,您應該會在 Firebase 控制台中看到第二個模型。確保第二個模型名為mnist_v2

c316683bb4d75d57.png

13.通過遠程配置選擇模型

現在我們有兩個獨立的模型,我們將添加一個參數來選擇在運行時下載哪個模型。客戶端接收到的參數值將決定客戶端下載哪個模型。

在 Firebase 控制台中添加配置規則

首先,打開 Firebase 控制台並單擊左側導航菜單中的遠程配置按鈕。然後,單擊“添加參數”按鈕。

將新參數命名為model_name並為其指定默認值"mnist_v1" 。通過將模型的名稱放在遠程配置參數中,我們可以測試多個模型,而無需為要測試的每個模型添加新參數。單擊發布更改以應用更新。

2949cb95c7214ca4.png

添加 Firebase RemoteConfig 依賴項

應用程序/build.gradle

implementation 'com.google.firebase:firebase-config-ktx:19.1.4'

配置 Firebase 遠程配置

MainActivity.kt

  private fun configureRemoteConfig() {
    remoteConfig = Firebase.remoteConfig
    val configSettings = remoteConfigSettings {
      minimumFetchIntervalInSeconds = 3600
    }
    remoteConfig.setConfigSettingsAsync(configSettings)
  }

請求和使用配置

為配置創建一個獲取請求並添加一個完成處理程序以獲取和使用配置參數。

MainActivity.kt

 private fun setupDigitClassifier() {
    configureRemoteConfig()
    remoteConfig.fetchAndActivate()
      .addOnCompleteListener { task ->
        if (task.isSuccessful) {
          val modelName = remoteConfig.getString("model_name")
          val downloadTrace = firebasePerformance.newTrace("download_model")
          downloadTrace.start()
          downloadModel(modelName)
            .addOnSuccessListener {
              downloadTrace.stop()
            }
        } else {
          showToast("Failed to fetch model name.")
        }
      }
  }

測試遠程配置

  1. 點擊98205811bbed9d74.png運行按鈕。
  2. 檢查您是否看到已下載 mnist_v1 模型的 Toast 消息。
  3. 返回 Firebase 控制台,將默認​​值更改為 mnist_v2 並選擇Publish Changes以應用更新。
  4. 重啟應用,查看 Toast 消息,提示本次下載了 mnist_v2 模型。

14. A/B 測試模型的有效性

Firebase A/B 測試可幫助您輕鬆運行、分析和擴展產品和營銷實驗,從而優化您的應用體驗。最後,我們可以使用 Firebase 的內置 A/B 測試行為來查看我們的兩個模型中哪一個表現更好。

轉到 Firebase 控制台中的分析 -> 事件。如果顯示了correct_inference事件,請將其標記為“Conversion event”,如果沒有,您可以轉到Analytics -> Conversion Events並點擊“Create a New Conversion Event”並correct_inference.

現在轉到 Firebase 控制台中的“遠程配置”,從我們剛剛添加的“model_name”參數的更多選項菜單中選擇“A/B 測試”按鈕。

fad5ea36969d2aeb.png

在隨後的菜單中,接受默認名稱。

d7c006669ace6e40.png

在下拉列表中選擇您的應用,並將定位條件更改為 50% 的活躍用戶。

cb72dcc7d2666bd3.png

如果您之前能夠將correct_inference事件設置為轉化,請將此事件用作跟踪的主要指標。否則,如果您不想等待事件顯示在 Analytics 中,您可以manually添加correct_inference

1ac9c94fb3159271.png

最後,在 Variants 屏幕上,將您的控制組變體設置為使用mnist_v1並將您的 Variant A 組設置為使用mnist_v2

e4510434f8da31b6.png

單擊右下角的查看按鈕。

恭喜,您已成功為您的兩個獨立模型創建了 A/B 測試! A/B 測試目前處於草稿狀態,可隨時點擊“開始實驗”按鈕啟動。

要詳細了解 A/B 測試,請查看A/B 測試文檔

15. 恭喜!

在此 Codelab 中,您了解瞭如何使用 Firebase 中動態加載的 TFLite 模型替換應用中靜態捆綁的 tflite 資產。要了解有關 TFLite 和 Firebase 的更多信息,請查看其他 TFLite 示例和 Firebase 入門指南。

我們涵蓋的內容

  • TensorFlow 精簡版
  • Firebase 機器學習
  • Firebase 分析
  • Firebase 性能監控
  • Firebase 遠程配置
  • Firebase A/B 測試

下一步

  • 在您的應用中實施 Firebase ML 部署。

學到更多

有一個問題?

報告問題