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

1. Opis

Witamy na kursie Rekomendacje dotyczące TensorFlow Lite i Firebase Codelabs. Z tego ćwiczenia w Codelabs dowiesz się, jak użyć TensorFlow Lite i Firebase do wdrożenia modelu rekomendacji w aplikacji. To ćwiczenie w Codelabs opiera się na tym przykładzie TensorFlow Lite.

Rekomendacje umożliwiają aplikacjom korzystanie z systemów uczących się, aby wyświetlać użytkownikom najtrafniejsze treści. Wykorzystują model wytrenowany na zbiorczych zachowaniu dużej liczby innych użytkowników, aby sugerować treści aplikacji, z którymi użytkownik może chcieć wejść w przyszłości.

Z tego samouczka dowiesz się, jak za pomocą Firebase Analytics zbierać dane od użytkowników aplikacji, utworzyć model systemów uczących się na podstawie tych danych, a potem używać go w aplikacji na Androida do wnioskowania i uzyskiwania rekomendacji. Nasze rekomendacje wskazują przede wszystkim, które filmy użytkownik najprawdopodobniej chętnie obejrzy, biorąc pod uwagę listę filmów, które wcześniej mu się spodobały.

Czego się nauczysz

  • Integracja Firebase Analytics z aplikacją na Androida w celu zbierania danych o zachowaniu użytkowników
  • eksportować te dane do Google Big Query,
  • Wstępne przetwarzanie danych i wytrenowanie modelu rekomendacji TF Lite
  • Wdróż model TF Lite w Firebase ML i uzyskaj do niego dostęp z aplikacji
  • Przeprowadź wnioskowanie na urządzeniu z wykorzystaniem modelu, aby proponować użytkownikom rekomendacje

Czego potrzebujesz

  • Najnowsza wersja Android Studio.
  • Przykładowy kod.
  • urządzenia testowego 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 do łączenia.

Jak wykorzystasz ten samouczek?

Tylko do przeczytania Przeczytaj go i wykonaj ćwiczenia

Jak oceniasz swoje doświadczenia z tworzeniem aplikacji na Androida?

Początkujący Poziom średnio zaawansowany Biegły
.

2. Pobieranie przykładowego kodu

Skopiuj repozytorium GitHub z poziomu wiersza poleceń.

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

3. Zaimportuj aplikację startową

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

Projekt startowy powinien być teraz otwarty w Android Studio.

4. Utwórz projekt konsoli Firebase

Tworzenie nowego projektu

  1. Otwórz konsolę Firebase.
  2. Wybierz Dodaj projekt (lub Utwórz projekt, jeśli jest to pierwszy projekt).
  3. Wybierz lub wpisz nazwę projektu i kliknij Dalej.
  4. Upewnij się, że opcja „Włącz Google Analytics dla tego projektu” 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 rozpocząć proces konfiguracji.
  2. Wpisz nazwę pakietu ćwiczeń z programowania: com.google.firebase.codelabs.recommendations
  3. Wybierz Zarejestruj aplikację.

Dodawanie pliku google-services.json do aplikacji

Po dodaniu nazwy pakietu i wybraniu Zarejestruj się kliknij Pobierz google-services.json, aby uzyskać plik konfiguracyjny Firebase na Androida, a następnie skopiuj plik google-services.json do katalogu app w swoim projekcie. Po pobraniu pliku możesz pominąć kolejne kroki wymienione w konsoli (zostały one już wykonane w projekcie build-android-start).

Dodawanie wtyczki google-services do aplikacji

Wtyczka google-services wykorzystuje plik google-services.json do skonfigurowania aplikacji pod kątem użycia Firebase. Te wiersze powinny być już dodane do plików build.gradle.kts w projekcie (zaznacz, by potwierdzić):

app/build.grade.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 w przypadku aplikacji dostępne są wszystkie zależności, zsynchronizuj projekt z plikami Gradle. Wybierz Plik > Synchronizowanie projektu z plikami Gradle na pasku narzędzi Android Studio.

6. Uruchom aplikację startową

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

Aplikacja powinna uruchomić się na urządzeniu. W tym momencie możesz zobaczyć działającą aplikację, która wyświetla kartę z listą filmów oraz karty Polubione filmy i Rekomendacje. Możesz kliknąć film na liście, aby dodać go do swojej listy polubionych. Gdy wykonasz pozostałe kroki ćwiczeń z programowania, na karcie Rekomendacje będziemy mogli generować rekomendacje filmów.

7. Dodaj Firebase Analytics do aplikacji

W tym kroku dodasz do aplikacji Firebase Analytics, aby rejestrować dane o zachowaniu użytkowników (w tym przypadku oznacza to, które filmy mu się podobają). Te dane będą używane w formie zbiorczej w kolejnych krokach do trenowania modelu rekomendacji.

Dodaj zależność Analytics i Zestawu materiałów Firebase

Podane niżej zależności są niezbędne, aby dodać Firebase Analytics do aplikacji. Powinny już być uwzględnione w pliku app/build.gradle.kts (verify).

app/build.grade.kts

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

Konfigurowanie Firebase Analytics w aplikacji

Obiekt LikeMoviesViewModel zawiera funkcje do przechowywania filmów, które spodobały się użytkownikowi. Za każdym razem, gdy użytkownikowi spodoba się nowy film, chcemy też wysłać zdarzenie z dziennika narzędzia analitycznego, aby to zarejestrować.

Dodaj funkcję onMovieShared z poniższym kodem, aby rejestrować zdarzenie analityczne, gdy użytkownik kliknie przycisk „Podoba mi się” film.

LubianeFilmyViewModel.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 funkcję, aby rejestrować zdarzenie Analytics po dodaniu filmu do listy polubień użytkownika.

LubianeFilmyViewModel.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 zdarzenia Analytics w aplikacji i sprawdzimy, czy są wysyłane do konsoli Firebase.

Włącz logowanie debugowania Analytics.

Usługa Firebase Analytics została zaprojektowana z myślą o maksymalizacji czasu pracy na baterii, dlatego grupuje zdarzenia na urządzeniu i wysyła je do Firebase tylko od czasu do czasu. Na potrzeby debugowania możemy wyłączyć to zachowanie, aby obserwować zdarzenia w czasie rzeczywistym, gdy są one rejestrowane. W tym celu uruchom następujące polecenie w powłoce.

Terminal.

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

Sprawdzanie, czy zdarzenia Analytics są generowane

  1. W Android Studio otwórz okno Logcat, aby sprawdzić logowanie z aplikacji.
  2. Ustaw filtr Logcat na ciąg „Rejestrowanie zdarzenia”.
  3. Sprawdź, czy „select_item” Zdarzenia Analytics są generowane za każdym razem, gdy polubisz film w aplikacji.

Udało Ci się zintegrować Firebase Analytics ze swoją aplikacją. W miarę jak użytkownicy korzystają z Twojej aplikacji lub oglądają filmy, będą one rejestrowane zbiorczo. Wykorzystamy te dane zbiorcze w pozostałej części tego ćwiczenia z programowania do wytrenowania naszego modelu rekomendacji. Wykonaj jeszcze opcjonalny krok, aby wyświetlić w konsoli Firebase te same zdarzenia Analytics, które pojawiły się w narzędziu Logcat. Możesz przejść do następnej strony.

Opcjonalnie: potwierdzaj zdarzenia Analytics w konsoli Firebase

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

9. Eksportowanie danych Analytics do BigQuery

Big Query to usługa Google Cloud, która umożliwia badanie i przetwarzanie dużych ilości danych. W tym kroku połączysz swój projekt w konsoli Firebase z Big Query, dzięki czemu dane Analytics generowane przez Twoją aplikację będą automatycznie eksportowane do BigQuery.

Włączanie eksportu do BigQuery

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

W ramach projektu konsoli Firebase masz teraz włączone automatyczne wysyłanie danych o zdarzeniach z Firebase Analytics do BigQuery. Dzieje się to automatycznie i bez dalszej interakcji, jednak pierwszy eksport, który utworzy zbiór danych analitycznych w BigQuery, może nastąpić dopiero po upływie 24 godzin. 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ń.

Wytrenowanie modelu rekomendacji wymaga dużych 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żyj BigQuery, aby uzyskać dane do trenowania modelu

Po połączeniu konsoli Firebase z funkcją eksportowania do BigQuery dane o zdarzeniach analityki aplikacji po pewnym czasie automatycznie pojawią się w konsoli BigQuery. Aby uzyskać dane początkowe na potrzeby tego samouczka, w tym kroku zaimportujemy istniejący przykładowy zbiór danych do Twojej konsoli BigQuery, aby wykorzystać go do wytrenowania modelu rekomendacji.

Importowanie przykładowego zbioru danych do BigQuery

  1. Otwórz panel BigQuery w konsoli Google Cloud.
  2. Wybierz nazwę projektu z menu.
  3. Aby zobaczyć szczegóły, wybierz nazwę projektu u dołu menu nawigacyjnego BigQuery po lewej stronie.
  4. Wybierz Utwórz zbiór danych, aby otworzyć panel tworzenia zbioru danych.
  5. Wpisz „firebase_recommendations_dataset” jako Identyfikator zbioru danych i wybierz 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 polu Utwórz tabelę z wybierz „Google Cloud Storage”.
  9. W polu Wybierz plik z zasobnika GCS wpisz „gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt”.
  10. Wybierz „JSONL”. z menu Format pliku.
  11. Wpisz „recommendations_table” (tabela rekomendacji) w polu Nazwa tabeli.
  12. Zaznacz pole w sekcji Schemat > Wykryj automatycznie > Schemat i parametry wejściowe
  13. Wybierz Utwórz tabelę.

Zobacz przykładowy zbiór danych

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

  1. W menu po lewej stronie wybierz firebase-recommendations-dataset, aby rozwinąć znajdujące się w nim tabele.
  2. Wybierz tabelę recommendations-table, aby wyświetlić schemat tabeli.
  3. Kliknij Podgląd, aby zobaczyć rzeczywiste dane zdarzeń Analytics zawarte w tej tabeli.

Utwórz dane logowania do konta usługi

Teraz w projekcie w konsoli Google Cloud utworzymy dane logowania do konta usługi, których w kolejnym kroku będzie można używać w środowisku Colab do uzyskiwania dostępu do danych BigQuery i ich wczytywania.

  1. Sprawdź, czy w projekcie Google Cloud włączone są płatności.
  2. włączyć interfejsy BigQuery Storage API i BigQuery Storage API, < kliknij tutaj>
  3. Otwórz stronę tworzenia klucza konta usługi.
  4. Z listy Konto usługi wybierz Nowe konto usługi.
  5. W polu Nazwa konta usługi wpisz nazwę.
  6. Z listy 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, aby wstępnie przetworzyć te dane i wytrenować nasz model rekomendacji.

11. Wstępne przetwarzanie danych i trenowanie modelu rekomendacji

W tym kroku wykorzystamy notatnik Colab, aby wykonać te czynności:

  1. zaimportować dane BigQuery do notatnika Colab
  2. wstępne przetwarzanie danych w celu przygotowania ich do trenowania modelu
  3. wytrenowanie modelu rekomendacji na danych analitycznych
  4. wyeksportuj model jako model TF Lite
  5. wdrożymy model w konsoli Firebase, abyśmy mogli używać go w naszej aplikacji

Zanim wprowadzimy notatnik treningowy Colab, najpierw włączymy interfejs Firebase Model Management API, aby usługa Colab mogła wdrożyć wytrenowany model w konsoli Firebase.

Włącz interfejs Firebase Model Management API

Tworzenie zasobnika do przechowywania modeli ML

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

Postępuj zgodnie z instrukcjami wyświetlanymi w oknie, aby skonfigurować zasobnik.

19517c0d6d2aa14d.png

Włączanie interfejsu Firebase ML API

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

Użyj notatnika Colab do wytrenowania i wdrożenia modelu

Otwórz notatnik Colab, korzystając z tego linku, i wykonaj podane instrukcje. Po wykonaniu czynności w notatniku Colab w konsoli Firebase wdrożysz plik modelu TF Lite, który będziemy mogli zsynchronizować z naszą aplikacją.

Otwórz w Colab

12. Pobierz model w aplikacji

W tym kroku zmodyfikujemy aplikację, aby pobrać model, który właśnie wytrenowaliśmy z użyciem systemów uczących się Firebase.

Dodaj zależność Firebase ML

Aby można było używać w aplikacji modeli systemów uczących się Firebase, wymagana jest zależność poniżej. Powinien już zostać dodany (weryfikacja).

app/build.grade.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, aby zsynchronizować 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. Zintegruj model rekomendacji Tensorflow Lite z aplikacją

Środowisko wykonawcze Tensorflow Lite pozwoli Ci używać modelu w aplikacji do generowania rekomendacji. W poprzednim kroku zainicjowaliśmy interpreter TFlite z pobranym przez nas plikiem modelu. W tym kroku najpierw wczytamy słownik i etykiety, które będą towarzyszyć naszemu modelowi w kroku wnioskowania. Potem dodamy do modelu wstępne przetwarzanie w celu generowania danych wejściowych i przetwarzanie, na którym wyodrębnimy wyniki z naszego wnioskowania.

Wczytaj słownik i etykiety

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

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

Na etapie wstępnego przetwarzania zmieniamy formę danych wejściowych, tak aby była zgodna z oczekiwaniami naszego modelu. Jeśli nie uzyskaliśmy jeszcze dużej liczby polubień, dodajemy tutaj długość wejściową wartością zmiennej. 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 tłumaczenia rozmowy w celu wygenerowania rekomendacji

W tym przykładzie używamy modelu pobranego w poprzednim kroku, aby wnioskować na podstawie wstępnie przetworzonych danych wejściowych. Określamy typ danych wejściowych i wyjściowych dla naszego modelu i uruchamiamy wnioskowanie, aby generować rekomendacje dotyczące filmów. Skopiuj ten kod do aplikacji.

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



Wdrażanie przetwarzania końcowego

Na koniec przetwarzamy dane wyjściowe naszego modelu, wybierając je o największym stopniu pewności i usuwając wartości zawarte (filmy, które użytkownik już polubił). Skopiuj ten kod do aplikacji.

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ę

Ponownie uruchom aplikację. Po wybraniu kilku filmów nowy model powinien automatycznie pobrać nowy model i zacząć generować rekomendacje.

14. Gratulacje!

Masz wbudowaną w swoją aplikację funkcję rekomendacji za pomocą TensorFlow Lite i Firebase. Pamiętaj, że techniki i potok pokazane w tym ćwiczeniu z programowania można uogólnić i wykorzystać także do obsługi innych typów rekomendacji.

Omówione zagadnienia

  • Firebase ML
  • Firebase Analytics
  • Eksportowanie zdarzeń analitycznych do BigQuery
  • Zdarzenia analizy wstępnej przetwarzania
  • Trenowanie rekomendacji w modelu TensorFlow
  • Wyeksportuj model i wdróż go w konsoli Firebase
  • Wyświetlanie rekomendacji filmów w aplikacji

Następne kroki

  • Wdrażaj rekomendacje systemów uczących się w Firebase w swojej aplikacji.

Więcej informacji

Masz pytanie?

Zgłaszanie problemów