Test A/B dwóch wersji modelu

Po wytrenowaniu nowego modelu niestandardowego możesz użyć A/B Testing aby sprawdzić, jak nowy model działa w rzeczywistych warunkach, w porównaniu z modelem, którego już używasz. Gdy potwierdzisz, że nowy model jest lepszy, możesz łatwo udostępnić go wszystkim użytkownikom bez konieczności aktualizowania aplikacji.

Na tej stronie dowiesz się, jak przeprowadzić test A/B, który ocenia 2 wersje modelu obsługującego hipotetyczną funkcję wyszukiwania wizualnego roślin. Ta funkcja używa niestandardowego modelu etykietowania obrazów, aby pomóc użytkownikom w identyfikowaniu gatunków roślin na podstawie ich zdjęć.

Załóżmy, że właśnie opublikowałeś nowy model etykietowania roślin plant_labeler_v2 i chcesz przeprowadzić eksperyment, który porówna go z obecnym modelem o nazwie plant_labeler_v1. Poniższe instrukcje pokazują, jak skonfigurować eksperyment, przeprowadzić go i podjąć działania na podstawie wyników.

1. Ustaw zdalną konfigurację modelu

Pierwszym krokiem do przeprowadzenia testu A/B modeli jest zmodyfikowanie aplikacji, aby używała parametru Remote Config do określania, którego modelu ma używać. Początkowo ustawisz domyślną wartość tego parametru na model, którego aplikacja już używa, ale ponieważ nazwa modelu jest kontrolowana przez parametr konfigurowany zdalnie, możesz zmieniać modele i eksperymentować z nimi bez konieczności wysyłania aktualizacji aplikacji do użytkowników.

Jeśli więc opublikujesz obecny model pod nazwą plant_labeler_v1, w kodzie inicjowania aplikacji ustawisz plant_labeler_v1 jako domyślną wartość parametru plant_labeler_model, jak w tym przykładzie:

Swift

let remoteConfig = RemoteConfig.remoteConfig()
let defaults = [
    "plant_labeler_model": "plant_labeler_v1" as NSObject,
    // ...
]
remoteConfig.setDefaults(defaults)
remoteConfig.fetchAndActivate()

Objective-C

FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig];
NSDictionary<NSString *, NSObject *> *defaults = @{
  @"plant_labeler_model" : (NSObject *)@"plant_labeler_v1",
  // ...
};
[remoteConfig setDefaults:defaults];
[remoteConfig fetchAndActivateWithCompletionHandler:nil];

Następnie zmień kod konfiguracji modelu, aby wczytywał model określony przez parametr plant_labeler_model:

Swift

let rcValue = remoteConfig.configValue(forKey: "plant_labeler_model")
guard let remoteModelName = rcValue.stringValue else { return }

// ...

let remoteModel = RemoteModel(
    name: remoteModelName,
    allowsModelUpdates: true,
    initialConditions: initialConditions,
    updateConditions: updateConditions
)
ModelManager.modelManager().register(remoteModel)

// Optionally configure a local model:
// https://firebase.google.com/docs/ml/ios/use-custom-models#configure_a_local_model

Objective-C

FIRRemoteConfigValue *rcValue = [remoteConfig configValueForKey:@"plant_labeler_model"];
NSString *remoteModelName = [rcValue stringValue];

// ...

FIRRemoteModel *remoteModel = [[FIRRemoteModel alloc] initWithName:remoteModelName
                                                allowsModelUpdates:YES
                                                 initialConditions:initialConditions
                                                  updateConditions:updateConditions];
[[FIRModelManager modelManager] registerRemoteModel:remoteModel];

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

Teraz, gdy aplikacja używa parametru Remote Config do określania, który model ma wczytać, możesz zmienić model, publikując nowy model i przypisując jego nazwę do parametru Remote Config. Dzięki tej funkcji A/B Testing mogą przypisywać różne modele do różnych użytkowników w celu ich porównania.

Zanim przejdziesz dalej, dodaj też do kodu pobierania modelu te elementy:

Swift

NotificationCenter.default.addObserver(
    forName: .firebaseMLModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let _ = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == remoteModelName
        else { return }
    // If the model downloaded was specified by a remote parameter, log an
    // event, which will be our experiment's activation event.
    if rcValue.source == .remote {
        Analytics.logEvent("nondefault_model_downloaded", parameters: nil)
    }
}

Objective-C

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:FIRModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }

              FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:remoteModelName] &&
                  rcValue.source == FIRRemoteConfigSourceRemote) {
                // If the model downloaded was specified by a remote parameter, log an
                // event, which will be our experiment's activation event.
                [FIRAnalytics logEventWithName:@"nondefault_model_downloaded" parameters:nil];
              }
            }];

Powyższy kod rejestruje niestandardowe zdarzenie Analytics, którego użyjesz później jako swojego zdarzenia aktywacji eksperymentu. Zdarzenie aktywacji to zdarzenie, które użytkownik musi wywołać, zanim zostanie uznany za uczestnika eksperymentu. Dzięki temu użytkownicy nie będą rejestrowani w teście A/B, dopóki ich urządzenie nie pobierze niestandardowego modelu ML.

2. Określ dane celu

Następnym krokiem jest określenie, jak będziesz mierzyć skuteczność modelu, i upewnienie się, że aplikacja zbiera dane niezbędne do sprawdzenia, jak różne wersje modelu działają zgodnie z tymi danymi.

A/B Testing ma kilka wbudowanych danych, w tym przychody, codzienne zaangażowanie i utrzymanie użytkowników. Te dane są często przydatne do testowania różnych ścieżek użytkownika lub dostrajania parametrów, ale mogą nie być odpowiednie do oceny modelu i przypadku użycia. W takiej sytuacji możesz zamiast tego spróbować zoptymalizować aplikację pod kątem niestandardowego zdarzenia Analytics.

Na przykładzie hipotetycznej funkcji wyszukiwania wizualnego roślin załóżmy, że wyświetlasz użytkownikowi wyniki wyszukiwania w kolejności zgodnej z pewnością modelu co do każdego wyniku. Jednym ze sposobów na sprawdzenie dokładności modelu jest sprawdzenie, jak często użytkownicy otwierali pierwszy wynik wyszukiwania.

Aby sprawdzić, który model najlepiej osiągnął cel, jakim jest maksymalizacja liczby kliknięć pierwszego wyniku, zarejestruj zdarzenie niestandardowe za każdym razem, gdy użytkownik kliknie pierwszy element na liście wyników.

Swift

Analytics.logEvent("first_result_opened", parameters: nil)

Objective-C

[FIRAnalytics logEventWithName:@"first_result_opened" parameters:nil];

Dane, które testujesz, zależą ostatecznie od tego, jak aplikacja używa modelu.

W tym momencie możesz wdrożyć aplikację w App Store. Aplikacja będzie nadal używać oryginalnego modelu, ale dodany kod Remote Config i Analytics pozwoli Ci eksperymentować z różnymi modelami tylko za pomocą konsoli Firebase.

3. Przeprowadź eksperyment A/B Testing

Teraz, gdy aplikacja jest już dostępna dla użytkowników i zbiera dane analityczne, utwórz eksperyment A/B Testing, który sprawdzi, jak działa używanie nowego modelu zamiast obecnego.

Aby utworzyć eksperyment:

  1. Na stronie Zdarzenia w konsoli Firebase sprawdź, czy rejestrujesz odpowiednie zdarzenia Analytics: zdarzenie aktywacji i dane celu.

    Zanim zdarzenie pojawi się w Firebase konsoli, aplikacja musi je zarejestrować co najmniej raz.

  2. W konsoli Firebase otwórz sekcję A/B Testing.

  3. Utwórz nowy eksperyment:

    1. Kliknij Utwórz eksperyment > Remote Config.

    2. W sekcji Kierowanie:

      • Wybierz aplikację z listy.
      • Określ, ilu użytkowników chcesz uwzględnić w eksperymencie.
      • Wybierz zdarzenie aktywacji, które zaczęło się rejestrować (w tym przykładzie nondefault_model_downloaded).
    3. W sekcji Cele wybierz z listy danych celu dane, które zostały określone w poprzedniej sekcji (w tym przykładzie first_result_opened), i wybierz dodatkowe dane, które chcesz śledzić, np. przychody z zakupów lub liczbę użytkowników, u których nie wystąpiły awarie.

    4. W sekcji Warianty zdefiniuj 2 warianty:

      • Grupa kontrolna (utworzona automatycznie)
      • Eksperymentalny model etykietowania roślin

      W grupie kontrolnej utwórz parametr plant_labeler_model i ustaw jego wartość na plant_labeler_v1. Użytkownicy przypisani do grupy kontrolnej będą używać starego modelu. (Nie ustawiaj parametru na (no change), ponieważ w aplikacji testujesz, czy używasz wartości zdalnej).

      W przypadku wariantu Eksperymentalny model etykietowania roślin ustaw parametr plant_labeler_model na plant_labeler_v2 (zakładając, że nowy model został opublikowany pod tą nazwą). Użytkownicy przypisani do tego wariantu będą używać nowego modelu.

    Ekran konfiguracji testu A/B

Uruchom eksperyment i pozwól mu działać przez kilka dni lub dłużej, aż A/B Testing wskaże lidera. Jeśli eksperyment nie może określić lidera, być może trzeba będzie rozszerzyć go na większą liczbę użytkowników.

4. Udostępnij zwycięski wariant wszystkim użytkownikom

Karta wyników testu A/B

Gdy A/B Testing zbiorą wystarczającą ilość informacji, aby wskazać najlepszy wariant – w tym przypadku wariant, który zmaksymalizował liczbę kliknięć pierwszego wyniku wyszukiwania – możesz zdecydować, czy chcesz udostępnić zwycięski wariant (lub inny wariant) wszystkim użytkownikom.

W sekcji A/B Testing w konsoli Firebase otwórz widok szczegółów zakończonego eksperymentu. W tym widoku możesz zobaczyć, jak każdy wariant działał zgodnie z danymi celu i wybranymi danymi dodatkowymi. Na podstawie tych informacji możesz zdecydować, czy chcesz udostępnić wariant lidera, czy inny wariant.

Aby udostępnić wariant wszystkim użytkownikom, na stronie z informacjami o eksperymencie kliknij > Udostępnij wariant. Gdy to zrobisz, wartość parametru plant_labeler_model będzie dla wszystkich użytkowników wynosić plant_labeler_v2.

W przyszłej aktualizacji aplikacji zmień domyślną wartość parametru plant_labeler_model na plant_labeler_v2 i zaktualizuj dołączony model, jeśli go używasz. Użytkownicy używają już najnowszego modelu, więc możesz wdrożyć tę aktualizację w ramach opublikowanej aplikacji, kiedy tylko będzie to wygodne, np. przy okazji następnej aktualizacji funkcji.