Dodawanie rekomendacji do aplikacji za pomocą TensorFlow Lite i Firebase – ćwiczenia z programowania na Androida

1. Przegląd

Witamy w samouczku dotyczącym rekomendacji z użyciem TensorFlow Lite i Firebase. Z tych ćwiczeń z programowania dowiesz się, jak używać TensorFlow Lite i Firebase do wdrażania w aplikacji modelu rekomendacji. Te ćwiczenia z programowania są oparte na tym przykładzie TensorFlow Lite.

Zalecenia umożliwiają aplikacjom korzystanie z uczenia maszynowego w celu inteligentnego wyświetlania najbardziej odpowiednich treści dla każdego użytkownika. Biorą pod uwagę wcześniejsze zachowania użytkowników, aby sugerować treści aplikacji, z którymi użytkownik może chcieć wejść w interakcję w przyszłości. W tym celu korzystają z modelu wytrenowanego na podstawie zbiorczych zachowań dużej liczby innych użytkowników.

Z tego samouczka dowiesz się, jak za pomocą Firebase Analytics uzyskiwać dane o użytkownikach aplikacji, na podstawie tych danych tworzyć model uczenia maszynowego do generowania rekomendacji, a następnie używać tego modelu w aplikacji na Androida do przeprowadzania wnioskowania i uzyskiwania rekomendacji. W szczególności nasze rekomendacje będą sugerować, które filmy użytkownik najprawdopodobniej obejrzy, biorąc pod uwagę listę filmów, które wcześniej polubił.

Czego się nauczysz

  • Zintegruj Firebase Analytics z aplikacją na Androida, aby zbierać dane o zachowaniach użytkowników.
  • Eksportowanie tych danych do Google BigQuery
  • Wstępne przetwarzanie danych i trenowanie modelu rekomendacji TF Lite
  • Wdrażanie modelu TF Lite w Firebase ML i uzyskiwanie do niego dostępu z aplikacji
  • Przeprowadzanie wnioskowania na urządzeniu za pomocą modelu w celu sugerowania użytkownikom rekomendacji

Czego potrzebujesz

  • Najnowsza wersja Android Studio.
  • Przykładowy kod.
  • urządzenie testowe z Androidem 7 lub nowszym i Usługami Google Play w wersji 9.8 lub nowszej albo emulator z Usługami Google Play w wersji 9.8 lub nowszej;
  • Jeśli używasz urządzenia, kabel połączeniowy.

Jak zamierzasz wykorzystać ten samouczek?

Tylko przeczytaj Przeczytaj i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenie w tworzeniu aplikacji na Androida?

Początkujący Średnio zaawansowany Zaawansowany

2. Pobieranie przykładowego kodu

Sklonuj repozytorium GitHub z wiersza poleceń.

$ git clone https://github.com/FirebaseExtended/codelab-contentrecommendation-android.git

3. Importowanie aplikacji startowej

W Android Studio wybierz katalog codelab-recommendations-android ( android_studio_folder.png) z pobranego kodu przykładowego (Plik > Otwórz > .../codelab-recommendations-android/start).

Projekt początkowy powinien być teraz otwarty w Android Studio.

4. Tworzenie projektu w konsoli Firebase

Tworzenie nowego projektu

  1. Otwórz konsolę Firebase.
  2. Kliknij Dodaj projekt (lub Utwórz projekt, jeśli to pierwszy projekt).
  3. Wybierz lub wpisz nazwę projektu i kliknij Dalej.
  4. Sprawdź, czy opcja „Włącz Google Analytics w tym projekcie” jest włączona.
  5. Wykonaj pozostałe kroki konfiguracji w konsoli Firebase, a potem kliknij Utwórz projekt (lub Dodaj Firebase, jeśli używasz istniejącego projektu Google).

5. Dodaj Firebase

  1. Na ekranie przeglądu nowego projektu kliknij ikonę Androida, aby uruchomić proces konfiguracji.
  2. Wpisz nazwę pakietu codelabu: com.google.firebase.codelabs.recommendations
  3. Kliknij Zarejestruj aplikację.

Dodawanie pliku google-services.json do aplikacji

Po dodaniu nazwy pakietu i kliknięciu Zarejestruj kliknij Pobierz google-services.json, aby uzyskać plik konfiguracyjny Firebase na Androida. Następnie skopiuj plik google-services.json do katalogu app w projekcie. Po pobraniu pliku możesz pominąć kolejne kroki wyświetlane w konsoli (zostały już wykonane w projekcie build-android-start).

Dodawanie wtyczki google-services do aplikacji

Wtyczka google-services używa pliku google-services.json do konfigurowania aplikacji pod kątem korzystania z Firebase. Te wiersze powinny być już dodane do plików build.gradle.kts w projekcie (sprawdź, czy tak jest):

app/build.gradle.kts

plugins {
    id("com.google.gms.google-services")
}

build.grade.kts

plugins {
    id("com.google.gms.google-services") version "4.3.15" apply false
}

Synchronizowanie projektu z plikami Gradle

Aby mieć pewność, że wszystkie zależności są dostępne dla aplikacji, w tym momencie zsynchronizuj projekt z plikami Gradle. Na pasku narzędzi Android Studio wybierz File > Sync Project with Gradle Files (Plik > Synchronizuj projekt z plikami Gradle).

6. Uruchamianie aplikacji wyjściowej

Po zaimportowaniu projektu do Android Studio i skonfigurowaniu wtyczki google-services za pomocą pliku JSON możesz po raz pierwszy uruchomić aplikację. Podłącz urządzenie z Androidem i na pasku narzędzi Android Studio kliknij Uruchom ( execute.png).

Aplikacja powinna się uruchomić na urządzeniu. W tym momencie możesz zobaczyć działającą aplikację, która zawiera kartę z listą filmów, kartę Ulubione filmy i kartę Rekomendacje. Aby dodać film do listy polubionych, kliknij go na liście. Po wykonaniu pozostałych kroków w tym samouczku będziemy mogli generować rekomendacje filmów na karcie Rekomendacje.

7. Dodawanie do aplikacji Firebase Analytics

W tym kroku dodasz do aplikacji Firebase Analytics, aby rejestrować dane o zachowaniu użytkowników (w tym przypadku informacje o tym, które filmy im się podobają). Dane te będą w przyszłości używane zbiorczo do trenowania modelu rekomendacji.

Dodawanie listy materiałów Firebase i zależności Analytics

Aby dodać Firebase Analytics do aplikacji, musisz uwzględnić te zależności. Powinny one być już zawarte w pliku app/build.gradle.kts (sprawdź to).

app/build.gradle.kts

implementation(platform("com.google.firebase:firebase-bom:32.0.0"))
implementation("com.google.firebase:firebase-analytics-ktx")

Konfigurowanie Firebase Analytics w aplikacji

LikedMoviesViewModel zawiera funkcje do przechowywania filmów, które podobają się użytkownikowi. Za każdym razem, gdy użytkownik polubi nowy film, chcemy też wysyłać zdarzenie dziennika Analytics, aby zarejestrować to polubienie.

Dodaj funkcję onMovieLiked z poniższym kodem, aby rejestrować zdarzenie analityczne, gdy użytkownik kliknie przycisk „Lubię” przy filmie.

LikedMoviesViewModel.kt

import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase


class LikedMoviesViewModel internal constructor (application: Application) : AndroidViewModel(application) {

    ...

    fun onMovieLiked(movie: Movie) {
        movies.setLike(movie, true)
        logAnalyticsEvent(movie.id.toString())
    }
       
}

Dodaj to pole i tę funkcję, aby rejestrować zdarzenie Analytics, gdy film zostanie dodany do listy „Lubię” użytkownika.

LikedMoviesViewModel.kt

import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.analytics.ktx.logEvent
import com.google.firebase.ktx.Firebase


class LikedMoviesViewModel internal constructor (application: Application) : AndroidViewModel(application) {
    ...
    private val firebaseAnalytics = Firebase.analytics

    ...

    /**
     * Logs an event in Firebase Analytics that is used in aggregate to train the recommendations
     * model.
     */
    private fun logAnalyticsEvent(id: String) {
        firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SELECT_ITEM) {
            param(FirebaseAnalytics.Param.ITEM_ID, id)
        }
    }

8. Testowanie integracji z Analytics

W tym kroku wygenerujemy w aplikacji zdarzenia Analytics i sprawdzimy, czy są one wysyłane do konsoli Firebase.

Włączanie logowania debugowania w Analytics

Firebase Analytics został zaprojektowany tak, aby maksymalnie wydłużać czas pracy baterii użytkownika. Zdarzenia są grupowane na urządzeniu i wysyłane do Firebase tylko od czasu do czasu. Na potrzeby debugowania możemy wyłączyć to działanie, aby zobaczyć zdarzenia rejestrowane w czasie rzeczywistym. W tym celu uruchom w powłoce to polecenie:

Terminal

adb shell setprop debug.firebase.analytics.app com.google.firebase.codelabs.recommendations

Sprawdzanie, czy generowane są zdarzenia Analytics

  1. W Android Studio otwórz okno Logcat, aby sprawdzić logi z aplikacji.
  2. Ustaw filtr Logcat na ciąg znaków „Logging event”.
  3. Sprawdź, czy zdarzenia Analytics „select_item” są wysyłane za każdym razem, gdy polubisz film w aplikacji.

W tym momencie integracja Firebase Analytics z aplikacją została zakończona. Gdy użytkownicy będą korzystać z aplikacji i polubią filmy, ich polubienia będą rejestrowane w formie zbiorczej. W dalszej części tego laboratorium użyjemy tych zagregowanych danych do wytrenowania modelu rekomendacji. Poniższy krok jest opcjonalny i pozwala wyświetlać w konsoli Firebase te same zdarzenia Analytics, które były widoczne w Logcat. Możesz przejść do następnej strony.

Opcjonalnie: potwierdź zdarzenia Analytics w konsoli Firebase

  1. Otwórz konsolę Firebase.
  2. W sekcji Analytics kliknij DebugView.
  3. W Android Studio kliknij Uruchom, aby uruchomić aplikację i dodać kilka filmów do listy polubionych.
  4. W widoku DebugView w konsoli Firebase sprawdź, czy te zdarzenia są rejestrowane podczas dodawania filmów w aplikacji.

9. Eksportowanie danych z Analytics do BigQuery

BigQuery to usługa Google Cloud, która umożliwia analizowanie i przetwarzanie dużych ilości danych. W tym kroku połączysz projekt w konsoli Firebase z BigQuery, aby dane Analytics generowane przez Twoją aplikację były automatycznie eksportowane do BigQuery.

Włączanie eksportowania do BigQuery

  1. Otwórz konsolę Firebase.
  2. Obok opcji Przegląd projektu kliknij ikonę koła zębatego Ustawienia, a następnie wybierz Ustawienia projektu.
  3. Kliknij kartę Integracje.
  4. W bloku BigQuery kliknij Połącz (lub Zarządzaj).
  5. W kroku Łączenie Firebase z BigQuery kliknij Dalej.
  6. W sekcji Skonfiguruj integrację kliknij przełącznik, aby włączyć wysyłanie danych Google Analytics, a następnie wybierz Połącz z BigQuery.

W projekcie w konsoli Firebase włączono automatyczne wysyłanie danych o zdarzeniach Firebase Analytics do BigQuery. Dzieje się to automatycznie bez konieczności podejmowania dalszych działań, jednak pierwszy eksport, który tworzy zbiór danych analitycznych w BigQuery, może nastąpić dopiero po 24 godzinach. Po utworzeniu zbioru danych Firebase stale eksportuje nowe zdarzenia Analytics do BigQuery do tabeli danych częściowych i grupuje zdarzenia z poprzednich dni w tabeli zdarzeń.

Trenowanie modelu rekomendacji wymaga dużej ilości danych. Nie mamy jeszcze aplikacji generującej duże ilości danych, więc w następnym kroku zaimportujemy do BigQuery przykładowy zbiór danych, którego będziemy używać w dalszej części tego samouczka.

10. Używanie BigQuery do uzyskiwania danych treningowych modelu

Po połączeniu konsoli Firebase z eksportem do BigQuery dane zdarzeń analitycznych aplikacji będą po pewnym czasie automatycznie wyświetlane w konsoli BigQuery. Aby uzyskać wstępne dane na potrzeby tego samouczka, w tym kroku zaimportujemy do konsoli BigQuery istniejący przykładowy zbiór danych, który posłuży do trenowania naszego modelu rekomendacji.

Importowanie przykładowego zbioru danych do BigQuery

  1. Otwórz panel BigQuery w konsoli Google Cloud.
  2. W menu wybierz nazwę projektu.
  3. Aby wyświetlić szczegóły, w dolnej części menu po lewej stronie BigQuery wybierz nazwę projektu.
  4. Kliknij Utwórz zbiór danych, aby otworzyć panel tworzenia zbioru danych.
  5. Wpisz „firebase_recommendations_dataset” w polu Identyfikator zbioru danych i kliknij Utwórz zbiór danych.
  6. Nowy zbiór danych pojawi się w menu po lewej stronie pod nazwą projektu. Kliknij ją.
  7. Kliknij Utwórz tabelę, aby otworzyć panel tworzenia tabeli.
  8. W menu Utwórz tabelę z wybierz „Google Cloud Storage”.
  9. W polu Wybierz plik z zasobnika w GCS wpisz „gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt”.
  10. W menu Format pliku wybierz „JSONL”.
  11. W polu Nazwa tabeli wpisz „recommendations_table”.
  12. Zaznacz pole w sekcji Schemat > Automatyczne wykrywanie > Schemat i parametry wejściowe.
  13. Kliknij Utwórz tabelę.

Przeglądanie przykładowego zbioru danych

Na tym etapie możesz opcjonalnie zapoznać się ze schematem i wyświetlić podgląd tego zbioru danych.

  1. W menu po lewej stronie kliknij firebase-recommendations-dataset, aby rozwinąć tabele, które zawiera.
  2. Wybierz tabelę recommendations-table, aby wyświetlić schemat tabeli.
  3. Kliknij Podgląd, aby wyświetlić rzeczywiste dane zdarzenia Analytics, które zawiera ta tabela.

Tworzenie danych logowania do konta usługi

Teraz utworzymy w projekcie w konsoli Google Cloud dane logowania konta usługi, których użyjemy w następnym kroku w środowisku Colab, aby uzyskać dostęp do danych BigQuery i je wczytać.

  1. Sprawdź, czy w projekcie Google Cloud włączone są płatności.
  2. Włącz interfejsy BigQuery API i BigQuery Storage API. < kliknij tutaj>
  3. Otwórz stronę tworzenia klucza do konta usługi.
  4. Na liście Konto usługi wybierz Nowe konto usługi.
  5. W polu Nazwa konta usługi wpisz nazwę.
  6. Na liście Rola wybierz Projekt > Właściciel.
  7. Kliknij Utwórz. Na komputer zostanie pobrany plik JSON zawierający klucz.

W następnym kroku użyjemy Google Colab do wstępnego przetworzenia tych danych i wytrenowania naszego modelu rekomendacji.

11. Przetwarzanie wstępne danych i trenowanie modelu rekomendacji

W tym kroku użyjemy notatnika Colab, aby wykonać te czynności:

  1. zaimportować dane BigQuery do notatnika Colab;
  2. przetworzyć wstępnie dane, aby przygotować je do trenowania modelu;
  3. wytrenować model rekomendacji na podstawie danych analitycznych,
  4. wyeksportować model jako model TF Lite,
  5. wdrożyć model w konsoli Firebase, aby można było go używać w aplikacji;

Zanim uruchomimy notatnik szkoleniowy Colab, najpierw włączymy interfejs Firebase Model Management API, aby Colab mógł wdrożyć wytrenowany model w naszej konsoli Firebase.

Włączanie interfejsu Firebase Model Management API

Utwórz zasobnik do przechowywania modeli ML

W konsoli Firebase otwórz sekcję Pamięć i kliknij Rozpocznij. fbbea78f0eb3dc9f.png

Postępuj zgodnie z instrukcjami, aby skonfigurować zasobnik.

19517c0d6d2aa14d.png

Włączanie interfejsu Firebase ML API

Otwórz stronę interfejsu Firebase ML API w Google Cloud Console i kliknij Włącz.

Trenowanie i wdrażanie modelu za pomocą notatnika Colab

Otwórz notatnik Colab, korzystając z tego linku, i wykonaj podane w nim czynności. Po wykonaniu czynności w notatniku Colab w konsoli Firebase pojawi się wdrożony plik modelu TF Lite, który możemy zsynchronizować z naszą aplikacją.

Otwórz w Colab

12. Pobieranie modelu w aplikacji

W tym kroku zmodyfikujemy aplikację, aby pobrać z systemów uczących się Firebase wytrenowany przez nas model.

Dodawanie zależności Firebase ML

Aby używać w aplikacji modeli uczenia maszynowego Firebase, musisz dodać to zależności. Powinna być już dodana (sprawdź to).

app/build.gradle.kts

implementation("com.google.firebase:firebase-ml-modeldownloader:24.1.2")

Pobieranie modelu za pomocą interfejsu Firebase Model Manager API

Skopiuj poniższy kod do pliku RecommendationClient.kt, aby skonfigurować warunki pobierania modelu i utworzyć zadanie pobierania, które zsynchronizuje model zdalny z naszą aplikacją.

RecommendationClient.kt

    private fun downloadModel(modelName: String) {
        val conditions = CustomModelDownloadConditions.Builder()
            .requireWifi()
            .build()
        FirebaseModelDownloader.getInstance()
            .getModel(modelName, DownloadType.LOCAL_MODEL, conditions)
            .addOnCompleteListener {
                if (!it.isSuccessful) {
                    showToast(context, "Failed to get model file.")
                } else {
                    showToast(context, "Downloaded remote model: $modelName")
                    GlobalScope.launch { initializeInterpreter(it.result) }
                }
            }
            .addOnFailureListener {
                showToast(context, "Model download failed for recommendations, please check your connection.")
            }
    }

13. Integrowanie modelu rekomendacji TensorFlow Lite z aplikacją

Środowisko wykonawcze TensorFlow Lite umożliwi Ci używanie modelu w aplikacji do generowania rekomendacji. W poprzednim kroku zainicjowaliśmy interpreter TFLite za pomocą pobranego pliku modelu. W tym kroku najpierw wczytamy słownik i etykiety, które będą towarzyszyć naszemu modelowi w kroku wnioskowania. Następnie dodamy przetwarzanie wstępne, aby wygenerować dane wejściowe dla naszego modelu, oraz przetwarzanie końcowe, w którym wyodrębnimy wyniki wnioskowania.

Wczytaj słownik i etykiety

Etykiety używane przez model rekomendacji do generowania kandydatów do rekomendacji są wymienione w pliku sorted_movie_vocab.json w folderze res/assets. Skopiuj poniższy kod, aby wczytać te kandydatury.

RecommendationClient.kt

    /** Load recommendation candidate list.  */
    private suspend fun loadCandidateList() {
        return withContext(Dispatchers.IO) {
            val collection = MovieRepository.getInstance(context).getContent()
            for (item in collection) {
                candidates[item.id] = item
            }
            Log.v(TAG, "Candidate list loaded.")
        }
    }

Wdrażanie wstępnego przetwarzania

W kroku wstępnego przetwarzania zmieniamy formę danych wejściowych, aby pasowały do oczekiwań naszego modelu. Jeśli nie mamy jeszcze wielu polubień użytkowników, uzupełniamy długość danych wejściowych wartością zastępczą. Skopiuj poniższy kod:

RecommendationClient.kt

    /** Given a list of selected items, preprocess to get tflite input.  */
    @Synchronized
    private suspend fun preprocess(selectedMovies: List<Movie>): IntArray {
        return withContext(Dispatchers.Default) {
            val inputContext = IntArray(config.inputLength)
            for (i in 0 until config.inputLength) {
                if (i < selectedMovies.size) {
                    val (id) = selectedMovies[i]
                    inputContext[i] = id
                } else {
                    // Padding input.
                    inputContext[i] = config.pad
                }
            }
            inputContext
        }
    }


Uruchamianie interpretera w celu generowania rekomendacji

Używamy tu modelu pobranego w poprzednim kroku, aby przeprowadzić wnioskowanie na wstępnie przetworzonych danych wejściowych. Określamy typ danych wejściowych i wyjściowych dla naszego modelu i przeprowadzamy wnioskowanie, aby generować rekomendacje filmów. Skopiuj do aplikacji ten kod:

RecommendationClient.kt

    /** Given a list of selected items, and returns the recommendation results.  */
    @Synchronized
    suspend fun recommend(selectedMovies: List<Movie>): List<Result> {
        return withContext(Dispatchers.Default) {
            val inputs = arrayOf<Any>(preprocess(selectedMovies))

            // Run inference.
            val outputIds = IntArray(config.outputLength)
            val confidences = FloatArray(config.outputLength)
            val outputs: MutableMap<Int, Any> = HashMap()
            outputs[config.outputIdsIndex] = outputIds
            outputs[config.outputScoresIndex] = confidences
            tflite?.let {
                it.runForMultipleInputsOutputs(inputs, outputs)
                postprocess(outputIds, confidences, selectedMovies)
            } ?: run {
                Log.e(TAG, "No tflite interpreter loaded")
                emptyList()
            }
        }
    }



Wdrożenie przetwarzania końcowego

Na koniec przetwarzamy dane wyjściowe z naszego modelu, wybierając wyniki o najwyższym poziomie ufności i usuwając zawarte w nich wartości (filmy, które użytkownik już polubił). Skopiuj do aplikacji ten kod:

RecommendationClient.kt

    /** Postprocess to gets results from tflite inference.  */
    @Synchronized
    private suspend fun postprocess(
        outputIds: IntArray, confidences: FloatArray, selectedMovies: List<Movie>
    ): List<Result> {
        return withContext(Dispatchers.Default) {
            val results = ArrayList<Result>()

            // Add recommendation results. Filter null or contained items.
            for (i in outputIds.indices) {
                if (results.size >= config.topK) {
                    Log.v(TAG, String.format("Selected top K: %d. Ignore the rest.", config.topK))
                    break
                }
                val id = outputIds[i]
                val item = candidates[id]
                if (item == null) {
                    Log.v(TAG, String.format("Inference output[%d]. Id: %s is null", i, id))
                    continue
                }
                if (selectedMovies.contains(item)) {
                    Log.v(TAG, String.format("Inference output[%d]. Id: %s is contained", i, id))
                    continue
                }
                val result = Result(
                    id, item,
                    confidences[i]
                )
                results.add(result)
                Log.v(TAG, String.format("Inference output[%d]. Result: %s", i, result))
            }
            results
        }
    }


Przetestuj aplikację!

Uruchom ponownie aplikację. Gdy wybierzesz kilka filmów, automatycznie pobierze ona nowy model i zacznie generować rekomendacje.

14. Gratulacje!

W aplikacji masz już funkcję rekomendacji opartą na TensorFlow Lite i Firebase. Pamiętaj, że techniki i potok przedstawione w tym ćwiczeniu z programowania można uogólnić i wykorzystać do wyświetlania także innych rodzajów rekomendacji.

Omówione zagadnienia

  • Firebase ML
  • Firebase Analytics
  • Eksportowanie zdarzeń analitycznych do BigQuery
  • Wstępne przetwarzanie zdarzeń Analytics
  • Trenowanie modelu rekomendacji TensorFlow
  • Eksportowanie modelu i wdrażanie go w konsoli Firebase
  • Wyświetlanie rekomendacji filmów w aplikacji

Następne kroki

  • Wdróż w aplikacji rekomendacje ML Firebase.

Więcej informacji

Masz pytanie?

Zgłaszanie problemów