Test A/B dwóch wersji modelu

Po wytrenowaniu nowego modelu niestandardowego lub modelu AutoML Vision Edge możesz użyć Testów A/B, aby sprawdzić skuteczność nowego modelu w warunkach rzeczywistych w porównaniu z modelem, którego już używasz. Po potwierdzeniu, że nowy model jest ulepszony, możesz go łatwo wdrożyć dla wszystkich użytkowników bez konieczności aktualizowania aplikacji.

Na tej stronie dowiesz się, jak można przeprowadzić test A/B oceniający 2 wersje modelu, na którym działa hipotetyczna funkcja wizualnego wyszukiwania roślin. Funkcja ta wykorzystuje niestandardowy model oznaczania obrazów, aby ułatwić użytkownikom rozpoznawanie gatunków roślin na ich zdjęciach.

Załóżmy, że właśnie opublikowano nowy model oznaczania roślinami plant_labeler_v2 i chcesz przeprowadzić eksperyment, który porównuje go z obecnym modelem o nazwie plant_labeler_v1. Poniżej opisujemy, jak skonfigurować eksperyment, przeprowadzić go i podejmować działania na podstawie jego wyników.

1. Umożliwiaj zdalne konfigurowanie modelu

Pierwszym krokiem do testowania modeli A/B jest zmodyfikowanie aplikacji tak, aby wykorzystywała parametr Zdalnej konfiguracji do określania, którego modelu używa. Początkowo jako wartość domyślną tego parametru będzie ustawiony model używany przez aplikację. Nazwę modelu możesz jednak kontrolować za pomocą zdalnie konfigurowanego parametru, dzięki czemu możesz zmieniać modele i eksperymentować z nimi bez konieczności każdorazowego przekazywania aktualizacji aplikacji użytkownikom.

Jeśli więc bieżący model został opublikowany pod nazwą plant_labeler_v1, ustaw w kodzie inicjowania aplikacji plant_labeler_v1 jako wartość domyślną parametru plant_labeler_model, jak w tym przykładzie:

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.
                  // ...
                }
            }
        });

Następnie zmień kod konfiguracji modelu, aby wczytać model określony przez parametr 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

Gdy Twoja aplikacja użyje parametru Zdalnej konfiguracji do określenia, który model zostanie załadowany, możesz zmienić model – wystarczy opublikować nowy model i przypisać jego nazwę do parametru Zdalnej konfiguracji. Ta funkcja pozwala przypisywać różne modele różnym użytkownikom, aby można było je porównać.

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

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);
                }
            }
        });

Powyższy kod rejestruje niestandardowe zdarzenie Analytics, którego będziesz później używać jako zdarzenia aktywacji w eksperymencie. Zdarzenie aktywacji to zdarzenie, które użytkownik musi aktywować, aby został uznany za część eksperymentu. Dzięki temu użytkownicy nie zostaną przypisani do testu A/B, dopóki ich urządzenie nie zakończy pobierania niestandardowego modelu ML.

2. Wyznacz wskaźnik celu

Następnym krokiem jest określenie, jak będziesz mierzyć sukces modelu i zadbanie o to, aby aplikacja gromadziła dane niezbędne do testowania skuteczności różnych wersji modelu na podstawie tych danych.

Testy A/B mają kilka wbudowanych danych, m.in. przychody, codzienne zaangażowanie i utrzymanie użytkowników. Wskaźniki te są często przydatne przy testowaniu różnych przepływów UX lub dostrajaniu parametrów, ale mogą nie mieć sensu przy ocenie modelu i przypadku użycia. W takiej sytuacji możesz zamiast tego spróbować zoptymalizować stawki pod kątem niestandardowego zdarzenia Analytics.

Na przykładzie hipotetycznego wizualnego wyszukiwania roślin załóżmy, że użytkownik przedstawia wyniki wyszukiwania zgodnie z wiarygodnością modelu dla każdego z nich. Jednym ze sposobów oceny 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ęć najlepszych wyników, zarejestruj zdarzenie niestandardowe za każdym razem, gdy użytkownik kliknie pierwszy element na liście wyników.

Kotlin+KTX

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

Java

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

Ostateczny wskaźnik, który testujesz, zależy od tego, jak aplikacja używa modelu.

Na tym etapie możesz wdrożyć aplikację w Sklepie Play. Twoja aplikacja nadal będzie używać oryginalnego modelu, ale dodany kod Zdalnej konfiguracji i Analytics pozwoli Ci eksperymentować z różnymi modelami tylko za pomocą konsoli Firebase.

3. Przeprowadź eksperyment A/B

Teraz gdy użytkownicy mają już aplikację w swoich rękach i zbierają dane analityczne, utwórz eksperyment A/B, który przetestuje efekty zastosowania 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.

    Aplikacja musi zarejestrować każde zdarzenie co najmniej raz, zanim pojawi się ono w konsoli Firebase.

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

  3. Utwórz nowy eksperyment:

    1. Kliknij Utwórz eksperyment > Zdalna konfiguracja.

    2. W sekcji Kierowanie:

      • Wybierz aplikację z listy
      • Określ, ilu użytkowników chcesz objąć eksperymentem
      • Wybierz zdarzenie aktywacji, które rozpoczęło się logowanie (w tym przykładzie jest to nondefault_model_downloaded).
    3. Z listy danych celu w sekcji Cele wybierz dane celu określone w poprzedniej sekcji (w tym przykładzie jest to first_result_opened) i wskaż dodatkowe dane, które chcesz śledzić, np. przychody z zakupów lub liczbę użytkowników, u których nie wystąpiła awaria.

    4. W sekcji Wersje określ 2 warianty:

      • Grupa kontrolna (utworzona automatycznie)
      • Eksperymentalne narzędzie do oznaczania roślin

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

      W przypadku wariantu Funkcja oznaczania etykietami roślin eksperymentalnych ustaw parametr plant_labeler_model na plant_labeler_v2 (zakładając, że nowy model został opublikowany pod tą nazwą). Nowy model będzie używany przez użytkowników przypisanych do tego wariantu.

    Ekran konfiguracji testu A/B

Rozpocznij eksperyment i prowadź przez kilka dni lub dłużej, aż test A/B wyłoni najlepszy wariant. Jeśli eksperyment nie wyłoni zwycięzcy, konieczne może być objęcie eksperymentem większej liczby użytkowników.

4. Udostępnienie zwycięskiego wariantu wszystkim użytkownikom

Karta wyniku testu A/B

Gdy Testy A/B zbiorą wystarczającą ilość informacji do wskazania najlepszego wariantu – w tym przypadku wariantu, który zmaksymalizował liczbę kliknięć u góry strony w wynikach wyszukiwania, możesz zdecydować, czy udostępnić wszystkim użytkownikom zwycięski wariant (lub inny wariant).

W sekcji Testy A/B w konsoli Firebase otwórz widok szczegółów ukończonego eksperymentu. W tym widoku możesz sprawdzić skuteczność poszczególnych wariantów na podstawie danych celu i wybranych danych dodatkowych. Dzięki tym informacjom możesz zdecydować, czy wdrożyć najlepszy wariant, czy też inny.

Aby udostępnić wariant dla wszystkich użytkowników, na stronie z informacjami o eksperymencie kliknij > Wdróż wariant. Gdy to zrobisz, parametr plant_labeler_model będzie mieć wartość plant_labeler_v2 dla wszystkich użytkowników.

W przyszłej aktualizacji aplikacji zmień domyślną wartość parametru plant_labeler_model na plant_labeler_v2 i zaktualizuj model w pakiecie, jeśli z niego korzystasz. Użytkownicy korzystają już z najnowszego modelu, dlatego możesz przekazać tę aktualizację jako część opublikowanej aplikacji, gdy jest to dogodne, na przykład przy następnej aktualizacji funkcji.