A/B 測試模型的兩個版本

訓練新的自訂模型或 AutoML Vision Edge 模型後,您可以使用 A/B 測試來查看新模型與您已使用的模型相比在現實條件下的表現如何。確認新模型有所改進後,您可以輕鬆向所有使用者推出新模型,而無需更新應用程式。

本頁展示如何進行 A/B 測試,以評估支持假設視覺植物搜尋功能的模型的兩個版本。此功能使用自訂圖像標籤模型來幫助使用者從圖像中識別植物物種。

假設您剛剛發布了一個新的植物標籤模型plant_labeler_v2 ,並且您想要運行一個實驗,將其與名為plant_labeler_v1的當前模型進行比較。以下步驟展示如何設定實驗、運行實驗並對結果採取行動。

1. 使您的模型可遠端配置

對模型進行 A/B 測試的第一步是修改您的應用程式以使用遠端配置參數來確定它使用哪個模型。最初,您將將此參數的預設值設為應用程式已使用的模型,但由於模型名稱由遠端可配置參數控制,因此您可以變更和試驗不同的模型,而無需將應用程式更新推送到您的應用程式。用戶每次。

因此,如果您以名稱plant_labeler_v1發布目前模型,則可以在應用程式初始化程式碼中將plant_labeler_v1設定為plant_labeler_model參數的預設值,如下例所示:

Kotlin+KTX

val remoteConfig = FirebaseRemoteConfig.getInstance()

val remoteConfigDefaults = HashMap<String, Any>()
remoteConfigDefaults["plant_labeler_model"] = "plant_labeler_v1"
Tasks.await(remoteConfig.setDefaultsAsync(remoteConfigDefaults))

remoteConfig.fetchAndActivate().addOnSuccessListener { success ->
    if (success) {
      // Okay to get remote values.
      // ...
    }
}

Java

final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.getInstance();

Map<String, Object> remoteConfigDefaults = new HashMap<>();
remoteConfigDefaults.put("plant_labeler_model", "plant_labeler_v1");
Tasks.await(remoteConfig.setDefaultsAsync(remoteConfigDefaults));

remoteConfig.fetchAndActivate().addOnSuccessListener(
        new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean success) {
                if (success) {
                  // Okay to get remote values.
                  // ...
                }
            }
        });

然後,更改模型設定程式碼以載入plant_labeler_model參數指定的模型:

Kotlin+KTX

val rcValue = remoteConfig.getValue("plant_labeler_model")
val remoteModelName = rcValue.asString()

// ...

val remoteModel = FirebaseRemoteModel.Builder(remoteModelName)
        .enableModelUpdates(true)
        .setInitialDownloadConditions(initialConditions)
        .setUpdatesDownloadConditions(updateConditions)
        .build()
FirebaseModelManager.getInstance().registerRemoteModel(remoteModel)

// Optionally configure a local model:
// https://firebase.google.com/docs/ml/android/label-images-with-automl#configure-a-local-model-source
// https://firebase.google.com/docs/ml/android/use-custom-models#configure_a_local_model

Java

FirebaseRemoteConfigValue rcValue = remoteConfig.getValue("plant_labeler_model");
String remoteModelName = rcValue.asString();

// ...

FirebaseRemoteModel remoteModel = new FirebaseRemoteModel.Builder(remoteModelName)
        .enableModelUpdates(true)
        .setInitialDownloadConditions(initialConditions)
        .setUpdatesDownloadConditions(updateConditions)
        .build();
FirebaseModelManager.getInstance().registerRemoteModel(remoteModel);

// Optionally configure a local model:
// https://firebase.google.com/docs/ml/android/label-images-with-automl#configure-a-local-model-source
// https://firebase.google.com/docs/ml/android/use-custom-models#configure_a_local_model

現在您的應用程式使用遠端配置參數來確定要載入的模型,您只需發布新模型並將其名稱指派給遠端配置參數即可變更模型。此功能允許 A/B 測試將不同的模型分配給不同的用戶,以便進行比較。

在繼續之前,也要在模型下載程式碼中加入以下內容:

Kotlin+KTX

FirebaseModelManager.getInstance().downloadRemoteModelIfNeeded(remoteModel)
    .addOnSuccessListener {
        // If the model downloaded was specified by a remote parameter, log an
        // event, which will be our experiment's activation event.
        if (rcValue.source == FirebaseRemoteConfig.VALUE_SOURCE_REMOTE) {
            FirebaseAnalytics.getInstance(this).logEvent("nondefault_model_downloaded", null)
        }
    }

Java

FirebaseModelManager.getInstance().downloadRemoteModelIfNeeded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                // If the model downloaded was specified by a remote parameter, log an
                // event, which will be our experiment's activation event.
                if (rcValue.getSource() == FirebaseRemoteConfig.VALUE_SOURCE_REMOTE) {
                    FirebaseAnalytics.getInstance(YourActivity.this)
                            .logEvent("nondefault_model_downloaded", null);
                }
            }
        });

上面的程式碼記錄了一個自訂 Analytics 事件,您稍後將使用該事件作為您的實驗啟動事件。激活事件是使用者在被視為實驗的一部分之前必須觸發的事件。這可以確保使用者在裝置完成下載自訂 ML 模型之前不會被記錄在 A/B 測試中。

2. 確定目標指標

下一步是決定如何衡量模型的成功,並確保您的應用程式正在收集必要的數據來測試模型的不同版本根據該指標的執行情況。

A/B 測試有幾個內建指標,包括收入、每日參與度和用戶保留率。這些指標通常可用於測試不同的使用者體驗流程或微調參數,但對於評估模型和用例可能沒有意義。在這種情況下,您可以嘗試針對自訂 Analytics 事件進行最佳化。

以假設的視覺植物搜尋功能為例,假設您按照模型對每個結果的置信度順序向使用者呈現搜尋結果。了解模型準確性的一種方法是查看用戶打開第一個搜尋結果的頻率。

要測試哪個模型最能實現最大化頂部結果點擊的目標,​​每當使用者點擊結果清單中的第一項時,您都將記錄自訂事件。

Kotlin+KTX

FirebaseAnalytics.getInstance(this).logEvent("first_result_opened", null)

Java

FirebaseAnalytics.getInstance(YourActivity.this).logEvent("first_result_opened", null);

您測試的指標最終取決於您的應用程式如何使用您的模型。

此時,您可以將應用程式部署到 Play 商店。您的應用程式將繼續使用您的原始模型,但您新增的遠端設定和分析程式碼將允許您僅使用 Firebase 控制台嘗試不同的模型。

3. 執行 A/B 測試實驗

現在您的應用程式已掌握在使用者手中並且正在收集分析數據,請建立一個 A/B 測試實驗來測試使用新模型而不是當前模型的效果。

創建實驗:

  1. 在 Firebase 控制台的「事件」頁面上,驗證您正在記錄相關的 Analytics 事件:啟動事件和目標指標。

    您的應用程式需要在每個事件出現在 Firebase 控制台中之前至少記錄一次。

  2. 在 Firebase 控制台中,開啟A/B 測試部分。

  3. 建立一個新實驗:

    1. 按一下建立實驗 > 遠端配置

    2. “定位”部分:

      • 從清單中選擇您的應用程式
      • 指定您想要在實驗中包含多少用戶
      • 選擇您開始記錄的啟動事件(在此範例中為nondefault_model_downloaded
    3. 在「目標」部分中,從目標指標清單中選擇您在上一部分中確定的目標指標(在本範例中為 first_result_opened ),然後選擇您想要追蹤的任何其他指標,例如購買收入或無崩潰用戶。

    4. 變體部分中,定義兩個變體:

      • 對照組(自動創建)
      • 實驗植物貼標機

      對於控制組,建立plant_labeler_model參數並將其設定為plant_labeler_v1 。分配到對照組的使用者將使用舊模型。 (不要將參數設為(no change) ,因為在您的應用程式中,您正在測試是否正在使用遠端值。)

      對於實驗植物貼標機變體,將plant_labeler_model參數設為plant_labeler_v2 (假設您以該名稱發布了新模型)。分配到此變體的使用者將使用新模型。

    A/B 測試配置畫面

開始實驗並讓它運行幾天或更長時間,直到 A/B 測試宣布領先者。如果實驗無法確定領導者,您可能需要將實驗擴展到更多用戶

4.向所有用戶推出獲勝變體

A/B 測試結果卡

在A/B 測試收集了足夠的資訊來宣布領先者(在本例中,即最大化頂部搜尋結果點擊的變體)後,您可以決定是否向所有用戶推出獲勝變體(或另一個變體)。

Firebase 控制台A/B 測試部分中,開啟已完成實驗的詳細資料檢視。從此視圖中,您可以根據您的目標指標和您選擇的任何輔助指標來了解每個變體的執行情況。利用此訊息,您可以決定是否推出主要變體或其他變體。

若要向所有使用者推出變體,請按一下實驗詳細資料頁面上的 > 推出變體。執行此操作後,所有使用者的plant_labeler_model參數的值都將為plant_labeler_v2

在將來的應用程式更新中,您應該將plant_labeler_model參數的預設值變更為plant_labeler_v2並更新捆綁模型(如果您使用該模型)。不過,您的用戶已經在使用最新的模型,因此您可以在方便的時候(例如下次進行功能更新時)將此更新作為已發布應用程式的一部分推送。