Agrega recomendaciones a tu app con TensorFlow Lite y Firebase - Codelab para Android

1. Descripción general

Te damos la bienvenida al codelab Recomendaciones con TensorFlow Lite y Firebase. En este codelab, aprenderás a usar TensorFlow Lite y Firebase para implementar un modelo de recomendación en tu app. Este codelab se basa en este ejemplo de TensorFlow Lite.

Las recomendaciones permiten que las apps usen el aprendizaje automático para entregar de manera inteligente el contenido más relevante para cada usuario. Tienen en cuenta el comportamiento pasado de los usuarios para sugerir contenido de la app con el que podría querer interactuar en el futuro mediante un modelo entrenado en el comportamiento agregado de una gran cantidad de otros usuarios.

En este instructivo, se muestra cómo obtener datos de los usuarios de tu app con Firebase Analytics, compilar un modelo de aprendizaje automático para las recomendaciones a partir de esos datos y, luego, usar ese modelo en una app para Android para ejecutar inferencias y obtener recomendaciones. En particular, nuestras recomendaciones sugerirán cuáles son las películas más probables que el usuario miraría dada la lista de películas que le gustaron anteriormente.

Qué aprenderás

  • Integra Firebase Analytics en una app para Android a fin de recopilar datos de comportamiento de los usuarios.
  • Exporta esos datos a Google BigQuery
  • Procesa previamente los datos y entrena un modelo de recomendaciones de TF Lite
  • Implementa el modelo de TF Lite en el AA de Firebase y accede a él desde tu app
  • Ejecuta la inferencia en el dispositivo con el modelo para sugerir recomendaciones a los usuarios.

Requisitos

  • La versión más reciente de Android Studio
  • Código de muestra.
  • Un dispositivo de prueba con Android 7 o versiones posteriores y Servicios de Google Play 9.8 o versiones posteriores, o un emulador con Servicios de Google Play 9.8 o versiones posteriores
  • Si usas un dispositivo, debes usar un cable de conexión.

¿Cómo usarás este instructivo?

Leer Leer y completar los ejercicios

¿Cómo calificarías tu experiencia con la compilación de apps para Android?

Principiante Intermedio Avanzado

2. Obtén el código de muestra

Clona el repositorio de GitHub a partir de la línea de comandos.

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

3. Importa la app de partida

En Android Studio, selecciona el directorio codelab-recommendations-android ( carpeta_android_studio.png) desde la descarga del código de muestra (File > Open > .../codelab-recommendations-android/start).

Ahora, deberías tener el proyecto de inicio abierto en Android Studio.

4. Crea un proyecto de Firebase console

Crea un proyecto nuevo

  1. Dirígete a Firebase console.
  2. Selecciona Agregar proyecto (o Crear un proyecto si es el primero).
  3. Selecciona o ingresa un nombre para el proyecto y haz clic en Continuar.
  4. Asegúrate de que la opción “Habilitar Google Analytics para este proyecto” esté habilitada.
  5. Sigue los pasos de configuración restantes en Firebase console y, luego, haz clic en Crear proyecto (o Agregar Firebase si usas un proyecto de Google existente).

5. Agregar Firebase

  1. En la pantalla de descripción general del proyecto nuevo, haz clic en el ícono de Android para iniciar el flujo de trabajo de configuración.
  2. Ingresa el nombre del paquete del codelab: com.google.firebase.codelabs.recommendations
  3. Selecciona Registrar app.

Agrega el archivo google-services.json a tu app

Después de agregar el nombre del paquete y seleccionar Registrar, haz clic en Descargar google-services.json para obtener el archivo de configuración de Firebase para Android y, luego, copia el archivo google-services.json en el directorio app de tu proyecto. Una vez que se descargue el archivo, puedes omitir los próximos pasos que se muestran en la consola (ya se realizaron en el proyecto build-android-start).

Agrega el complemento google-services a tu app

El complemento google-services usa el archivo google-services.json para configurar tu aplicación de modo que use Firebase. Se deberían agregar las siguientes líneas a los archivos build.gradle.kts del proyecto (marca para confirmar):

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
}

Sincroniza tu proyecto con archivos de Gradle.

A fin de asegurarte de que todas las dependencias estén disponibles para tu app, debes sincronizar tu proyecto con archivos de Gradle en este momento. Selecciona File > Sync Project with Gradle Files en la barra de herramientas de Android Studio.

6. Ejecuta la app de partida

Ahora que importaste el proyecto a Android Studio y configuraste el complemento google-services con tu archivo JSON, tienes todo listo para ejecutar la app por primera vez. Conecta el dispositivo Android y haz clic en Run ( ejecutar.png) en la barra de herramientas de Android Studio.

La app debería iniciarse en el dispositivo. En este punto, puedes ver una aplicación en funcionamiento que muestra una pestaña con una lista de películas, una pestaña de Películas que te gustan y una pestaña de Recomendaciones. Puedes hacer clic en una película de la lista para agregarla a la lista que te gusta. Después de completar los pasos restantes del codelab, podremos generar recomendaciones de películas en la pestaña Recomendaciones.

7. Agrega Firebase Analytics a la app

En este paso, agregarás Firebase Analytics a la app para registrar datos de comportamiento de los usuarios (en este caso, las películas que le gustan a un usuario). Estos datos se usarán de forma agregada en pasos futuros para entrenar el modelo de recomendaciones.

Cómo agregar la dependencia de lista de materiales y Analytics de Firebase

Las siguientes dependencias son necesarias para agregar Firebase Analytics a tu app. Ya deberían estar incluidas en el archivo app/build.gradle.kts (verificar).

app/build.grade.kts

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

Configura Firebase Analytics en la app

LikedMoviesViewModel contiene funciones para almacenar las películas que le gustan al usuario. Cada vez que al usuario le gusta una película nueva, también queremos enviar un evento de registro de estadísticas para registrarlo.

Agrega la función onMovieLiked con el código que aparece a continuación para registrar un evento de estadísticas cuando el usuario haga clic en una película.

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

Agrega el siguiente campo y la siguiente función para registrar un evento de Analytics cuando se agregue una película a la lista de Me gusta del usuario.

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. Prueba tu integración de Analytics

En este paso, generaremos eventos de Analytics en la app y verificaremos que se envíen a Firebase console.

Habilita el registro de depuración de Analytics

Firebase Analytics está diseñado para maximizar la duración de la batería del usuario, agrupa eventos en lotes en el dispositivo y los envía a Firebase solo ocasionalmente. Con fines de depuración, podemos inhabilitar este comportamiento para ver los eventos a medida que se registran en tiempo real ejecutando el siguiente comando en la shell.

Terminal

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

Verifica que se generen los eventos de Analytics

  1. En Android Studio, abre la ventana Logcat para examinar los registros de tu app.
  2. Establece el filtro Logcat en la cadena "Evento de registro".
  3. Verifica que se emitan los eventos de Analytics "select_item" cada vez que quieras ver una película en la app.

En este punto, integraste correctamente Firebase Analytics en tu app. A medida que los usuarios usan tu app y les gustan las películas, sus "me gusta" se registran en conjunto. Usaremos estos datos agregados en el resto de este codelab para entrenar nuestro modelo de recomendaciones. El siguiente es un paso opcional para ver los mismos eventos de Analytics que viste en Logcat también se transmiten en Firebase console. No dudes en pasar a la siguiente página.

Opcional: Confirma los eventos de Analytics en Firebase console.

  1. Dirígete a Firebase console.
  2. En Analytics, selecciona DebugView.
  3. En Android Studio, selecciona Ejecutar para iniciar la app y agregar algunas películas a la lista que te gustaron.
  4. En DebugView de Firebase console, verifica que estos eventos se registren mientras agregas películas en la app.

9. Exporta datos de Analytics a BigQuery

BigQuery es un producto de Google Cloud que permite examinar y procesar grandes cantidades de datos. En este paso, conectarás tu proyecto de Firebase console a BigQuery para que los datos de Analytics generados por tu app se exporten automáticamente a BigQuery.

Habilita la exportación de BigQuery

  1. Dirígete a Firebase console.
  2. Selecciona el ícono de ajustes de Configuración junto a Descripción general del proyecto y, luego, Configuración del proyecto.
  3. Selecciona la pestaña Integraciones.
  4. Selecciona Vincular (o Administrar) en el bloque BigQuery.
  5. Selecciona Siguiente en el paso Acerca de la vinculación de Firebase a BigQuery.
  6. En la sección Configurar integración, haz clic en el interruptor para habilitar el envío de datos de Google Analytics y selecciona Vincular a BigQuery.

Ya habilitaste tu proyecto de Firebase console para enviar automáticamente datos de eventos de Firebase Analytics a BigQuery. Esto sucede automáticamente sin ninguna interacción adicional. Sin embargo, es posible que la primera exportación que cree el conjunto de datos de estadísticas en BigQuery no se realice por 24 horas. Después de crear el conjunto de datos, Firebase exporta continuamente los nuevos eventos de Analytics a BigQuery en la tabla intradía y agrupa los eventos de días anteriores en la tabla de eventos.

El entrenamiento de un modelo de recomendaciones requiere muchos datos. Como todavía no tenemos una app que genere grandes cantidades de datos, en el siguiente paso importaremos un conjunto de datos de muestra a BigQuery para usarlo en el resto de este instructivo.

10. Usa BigQuery para obtener datos de entrenamiento de modelos

Ahora que conectamos Firebase console para exportar a BigQuery, los datos de eventos de análisis de aplicaciones aparecerán automáticamente en la consola de BigQuery después de un tiempo. Para obtener algunos datos iniciales a los fines de este instructivo, en este paso importaremos un conjunto de datos de muestra existente a tu consola de BigQuery a fin de usarlo para entrenar nuestro modelo de recomendaciones.

Importa un conjunto de datos de muestra a BigQuery

  1. Ve al panel de BigQuery en la consola de Google Cloud.
  2. Selecciona el nombre de tu proyecto en el menú.
  3. Selecciona el nombre de tu proyecto en la parte inferior del panel de navegación izquierdo de BigQuery para ver los detalles.
  4. Selecciona Crear conjunto de datos para abrir el panel de creación del conjunto de datos.
  5. Ingresa “firebase_recommendations_dataset” en el ID del conjunto de datos y selecciona Crear conjunto de datos.
  6. El nuevo conjunto de datos aparecerá en el menú de la izquierda debajo del nombre del proyecto. Haz clic en él.
  7. Selecciona Crear tabla para abrir el panel de creación de tablas.
  8. En Crear tabla desde, selecciona “Google Cloud Storage”.
  9. En el campo Seleccionar archivo del bucket de GCS, ingresa “gs://firebase-recommendations/recommendations-test/formatted_data_filtered.txt”.
  10. Selecciona “JSONL” en el menú desplegable Formato de archivo.
  11. Ingresa “recommendations_table” en el Nombre de la tabla.
  12. Marca la casilla en Esquema > Detección automática > Esquema y parámetros de entrada.
  13. Selecciona Crear tabla.

Explorar el conjunto de datos de muestra

En este punto, tienes la opción de explorar el esquema y obtener una vista previa de este conjunto de datos.

  1. Selecciona firebase-recommendations-dataset en el menú de la izquierda para expandir las tablas que contiene.
  2. Selecciona la tabla recommendations-table para ver el esquema de la tabla.
  3. Selecciona Vista previa para ver los datos reales de eventos de Analytics que contiene esta tabla.

Crea credenciales de cuenta de servicio

Ahora, crearemos credenciales de cuenta de servicio en nuestro proyecto de la consola de Google Cloud que podremos usar en el entorno de Colab en el siguiente paso para acceder a nuestros datos de BigQuery y cargarlos.

  1. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.
  2. Habilita las APIs de BigQuery Storage y BigQuery. < haz clic aquí>
  3. Ve a la página Crear clave de la cuenta de servicio.
  4. En la lista Cuenta de servicio, selecciona Cuenta de servicio nueva.
  5. Escribe un nombre en el campo Nombre de cuenta de servicio.
  6. En la lista Función, selecciona Proyecto > Propietario.
  7. Haz clic en Crear. Se descargará a tu computadora un archivo JSON con la clave.

En el siguiente paso, usaremos Google Colab para procesar previamente estos datos y entrenar nuestro modelo de recomendaciones.

11. Procesa previamente los datos y entrena el modelo de recomendaciones

En este paso, usaremos un notebook de Colab para realizar los siguientes pasos:

  1. Importar los datos de BigQuery al notebook de Colab
  2. Procesar previamente los datos y prepararlos para el entrenamiento de modelos
  3. entrenar el modelo de recomendaciones con los datos de Analytics
  4. Exporta el modelo como un modelo lite de TF
  5. implementar el modelo en Firebase console para poder usarlo en nuestra app

Antes de lanzar el notebook de entrenamiento de Colab, habilitaremos la API de Firebase Model Management para que Colab pueda implementar el modelo entrenado en Firebase console.

Habilitar la API de Firebase Model Management

Crea un bucket para almacenar tus modelos de AA

En Firebase console, ve a Storage y haz clic en Comenzar. fbbea78f0eb3dc9f.png

Sigue el diálogo para configurar tu bucket.

19517c0d6d2aa14d.png

Habilitar la API de AA de Firebase

Ve a la página de la API de AA de Firebase en la consola de Google Cloud y haz clic en Habilitar.

Usa el notebook de Colab para entrenar y, luego, implementar el modelo.

Abre el notebook de Colab mediante el siguiente vínculo y completa los pasos que se indican. Después de completar los pasos en el notebook de Colab, se implementará un archivo del modelo de TF Lite en Firebase console que podemos sincronizar con nuestra app.

Abrir en Colab

12. Descarga el modelo en tu app

En este paso, modificaremos nuestra app para descargar el modelo que acabamos de entrenar a partir del aprendizaje automático de Firebase.

Agrega una dependencia del AA de Firebase

La siguiente dependencia es necesaria para usar los modelos de aprendizaje automático de Firebase en tu app. Ya debería estar agregada (verificar).

app/build.grade.kts

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

Descarga el modelo con la API de Firebase Model Manager

Copia el siguiente código en RecommendationClient.kt para configurar las condiciones en las que se produce la descarga del modelo y crea una tarea de descarga para sincronizar el modelo remoto con nuestra app.

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. Integra el modelo de recomendación de TensorFlow Lite en tu app

El entorno de ejecución de Tensorflow Lite te permitirá usar tu modelo en la app para generar recomendaciones. En el paso anterior, inicializamos un intérprete de TFlite con el archivo de modelo que descargamos. En este paso, primero cargaremos un diccionario y etiquetas para acompañar a nuestro modelo en el paso de inferencia, luego agregaremos el procesamiento previo para generar las entradas a nuestro modelo y el procesamiento posterior, desde donde extraeremos los resultados de nuestra inferencia.

Carga el diccionario y las etiquetas

Las etiquetas que se usan para generar las candidatas por el modelo de recomendaciones se enumeran en el archivo sorted_movie_vocab.json de la carpeta res/assets. Copia el siguiente código para cargar estos candidatos.

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.")
        }
    }

Implementa el procesamiento previo

En el paso de procesamiento previo, cambiamos la forma de los datos de entrada para que coincidan con lo que espera nuestro modelo. Aquí, rellenamos la longitud de la entrada con un valor de marcador de posición si todavía no se generaron muchos "Me gusta" de los usuarios. Copia el siguiente código:

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


Ejecuta el intérprete para generar recomendaciones

Aquí usamos el modelo que descargamos en un paso anterior para ejecutar inferencias en la entrada ya procesada. Establecemos el tipo de entrada y salida para nuestro modelo y ejecutamos inferencias para generar nuestras recomendaciones de películas. Copia el siguiente código en tu app.

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



Implementa el procesamiento posterior

Por último, en este paso realizamos un procesamiento posterior de la salida de nuestro modelo. Para ello, seleccionamos los resultados con el mayor nivel de confianza y quitamos los valores contenidos (películas que ya le gustaron al usuario). Copia el siguiente código en tu app.

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


Prueba tu app

Vuelve a ejecutar tu app. A medida que selecciones algunas películas, se debería descargar automáticamente el modelo nuevo y comenzar a generar recomendaciones.

14. ¡Felicitaciones!

Creaste una función de recomendaciones en tu app con TensorFlow Lite y Firebase. Ten en cuenta que las técnicas y la canalización que se muestran en este codelab se pueden generalizar y usarse para entregar otros tipos de recomendaciones.

Temas abordados

  • AA de Firebase
  • Firebase Analytics
  • Exporta eventos de estadísticas a BigQuery
  • Procesa previamente los eventos de estadísticas
  • Recomendaciones de entrenamiento del modelo de TensorFlow
  • Exporta el modelo y, luego, impleméntalo en Firebase console
  • Entrega recomendaciones de películas en una app

Próximos pasos

  • Implementa las recomendaciones del AA de Firebase en tu app.

Más información

¿Tienes alguna pregunta?

Informar problemas