Compila e implementa un modelo de detección de objetos personalizado con TensorFlow Lite (Android)

1. Antes de comenzar

En este codelab, aprenderás a entrenar un modelo de detección de objetos personalizado con un conjunto de imágenes de entrenamiento conTFLite Model Maker , y, luego, implementa el modelo en una app para Android conBiblioteca de tareas de TFLite , Realizará lo siguiente:

  • Compila una app para Android que detecte ingredientes en las imágenes de las comidas.
  • Integra un modelo de detección de objetos previamente entrenado de TFLite y consulta el límite de lo que puede detectar el modelo.
  • Entrena un modelo de detección de objetos personalizado para que detecte los ingredientes o los componentes de una comida mediante un conjunto de datos personalizado llamado salad y TFLite Model Maker.
  • Implementa el modelo personalizado en la app para Android mediante la Biblioteca de tareas de TFLite.

Al final, crearás algo similar a la siguiente imagen:

b9705235366ae162.png

Requisitos previos

Este codelab fue diseñado para desarrolladores de dispositivos móviles con experiencia que quieran adquirir experiencia en el aprendizaje automático. Debes estar familiarizado con lo siguiente:

  • Desarrollo para Android con Kotlin y Android Studio
  • Sintaxis básica de Python

Qué aprenderá

  • Cómo entrenar un modelo de detección de objetos personalizado con TFLite Model Maker
  • Cómo implementar un modelo de detección de objetos de TFLite con la biblioteca de tareas de TFLite

Requisitos

  • Una versión reciente de Android Studio (v4.2 o posterior)
  • Android Studio Emulator o un dispositivo Android físico
  • El código de muestra
  • Conocimientos básicos sobre el desarrollo para Android en Kotlin

2. Detección de objetos

La detección de objetos es un conjunto de tareas de visión artificial que pueden detectar y ubicar objetos en una imagen digital. A partir de una imagen o una transmisión de video por Internet, un modelo de detección de objetos puede identificar cuál de un conjunto conocido de objetos puede estar presente y proporcionar información sobre sus posiciones dentro de la imagen.

TensorFlow ofrece modelos previamente entrenados para dispositivos móviles previamente entrenados que pueden detectar objetos comunes, como automóviles, naranjas, etc. Puedes integrar estos modelos previamente entrenados en tu app para dispositivos móviles con solo unas pocas líneas de código. Sin embargo, es posible que necesites detectar objetos en categorías más distintivas o originales. Esto requiere recopilar sus propias imágenes de entrenamiento y, luego, entrenar e implementar su propio modelo de detección de objetos.

TensorFlow Lite

TensorFlow Lite es una biblioteca multiplataforma de aprendizaje automático optimizada para ejecutar modelos de aprendizaje automático en dispositivos perimetrales, incluidos dispositivos móviles iOS y Android.

TensorFlow Lite es el motor principal del Kit de AA para ejecutar modelos de aprendizaje automático. El ecosistema de TensorFlow Lite cuenta con dos componentes que facilitan el entrenamiento y la implementación de modelos de aprendizaje automático en dispositivos móviles:

  • Model Maker es una biblioteca de Python que facilita el entrenamiento de modelos de TensorFlow Lite con tus propios datos y con solo unas pocas líneas de código. No necesitas experiencia en aprendizaje automático.
  • La Biblioteca de tareas es una biblioteca multiplataforma que facilita la implementación de modelos de TensorFlow Lite con solo unas pocas líneas de código en tus apps para dispositivos móviles.

Este codelab se enfoca en TFLite. Los conceptos y los bloques de código que no son relevantes para TFLite y la detección de objetos no se explican y se proporcionan para que simplemente los copies y los pegues.

3. Prepárate

Descarga el código

Haz clic en el siguiente vínculo a fin de descargar todo el código de este codelab:

Descargar código fuente

Descomprime el archivo zip descargado. Esto descomprimirá una carpeta raíz (odml-pathways-main) con todos los recursos que necesitarás. Para este codelab, solo necesitarás las fuentes del subdirectorio object-detection/codelab2/android.

El subdirectorio android en el repositorio object-detection/codelab2/android contiene dos directorios:

  • android_studio_folder.pngstarter: Código inicial en el que se basa este codelab.
  • android_studio_folder.pngfinal: Código completo para la app de muestra finalizada.

Cómo importar la app de inicio

Para comenzar, importa la app de inicio a Android Studio.

  1. Abre Android Studio y selecciona Import Project (Gradle, Eclipse ADT, etc.).
  2. Abre la carpeta starter del código fuente que descargaste antes.

7c0f27882a2698ac.png

Para asegurarte de que todas las dependencias estén disponibles en la app, debes sincronizar tu proyecto con los archivos de Gradle cuando finalice el proceso de importación.

  1. En la barra de herramientas de Android Studio, selecciona Sync Project with Gradle Files ( b451ab2d04d835f9.png). Importa starter/app/build.gradle

Cómo ejecutar la app de inicio

Ahora que importaste el proyecto a Android Studio, puedes ejecutar la app por primera vez.

Conecta tu dispositivo Android mediante USB a tu computadora o inicia el emulador de Android Studio,y haz clic en Run ( execute.png) en la barra de herramientas de Android Studio.

4. Información sobre la app inicial

A fin de que este codelab sea sencillo y se centre en los bits de aprendizaje automático, la app de inicio contiene código estándar que realiza algunas acciones por ti:

  • Puede tomar fotos con la cámara del dispositivo.
  • Contiene algunas imágenes de archivo para que puedas probar la detección de objetos en un emulador de Android.
  • Tiene un método conveniente para dibujar el resultado de la detección de objetos en el mapa de bits de entrada.

En su mayoría, interactuarás con estos métodos en el esqueleto de la app:

  • fun runObjectDetection(bitmap: Bitmap) Se llama a este método cuando eliges una imagen predeterminada o tomas una foto. bitmap es la imagen de entrada para la detección de objetos. Más adelante en este codelab, agregarás código de detección de objetos a este método.
  • data class DetectionResult(val boundingBoxes: Rect, val text: String) Esta es una clase de datos que representa un resultado de la detección de objetos para la visualización. boundingBoxes es el rectángulo en el que se encuentra el objeto, y text es la string de los resultados de detección que se mostrará junto con el cuadro de límite del objeto.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<DetectionResult>): Bitmap Este método dibuja los resultados de la detección de objetos en detectionResults en la entrada bitmap y muestra la copia modificada.

Este es un ejemplo de un resultado del método de utilidad drawDetectionResult.

f6b1e6dad726e129.png

5. Cómo agregar la detección de objetos en el dispositivo

Ahora, compilarás un prototipo integrando un modelo de TFLite previamente entrenado que pueda detectar objetos comunes en la app de inicio.

Descarga un modelo de detección de objetos de TFLite previamente entrenado

Existen varios modelos de detección de objetos en TensorFlow Hub que puedes usar. En este codelab, descargarás el modelo de detección de objetos eficientesDet-Lite, entrenado con el conjunto de datos COCO 2017, optimizado para TFLite y diseñado con el objetivo de lograr el rendimiento en CPU de dispositivos móviles y GPU y EdgeTPU.

A continuación, usa la biblioteca de tareas de TFLite para integrar el modelo TFLite previamente entrenado en la app de inicio. La Biblioteca de tareas de TFLite facilita la integración de modelos de aprendizaje automático optimizados para dispositivos móviles en una app para dispositivos móviles. Es compatible con muchos casos de uso populares de aprendizaje automático, como la detección de objetos, la clasificación de imágenes y la clasificación de texto. Puedes cargar el modelo de TFLite y ejecutarlo con solo unas pocas líneas de código.

Agrega el modelo a la app de inicio

  1. Copia el modelo que acabas de descargar en la carpeta assets de la app de inicio. Puedes encontrar la carpeta en el panel de navegación Project de Android Studio.

c2609599b7d22641.png

  1. Asígnale un nombre al archivo model.tflite.

c83e9397177c4561.png

Actualiza las dependencias de la biblioteca de tareas del archivo Gradle

Ve al archivo app/build.gradle y agrega esta línea a la configuración dependencies:

implementation 'org.tensorflow:tensorflow-lite-task-vision:0.3.1'

Sincroniza tu proyecto con archivos de Gradle

A fin de asegurarte de que todas las dependencias estén disponibles para tu app, en este momento, debes sincronizar tu proyecto con archivos de Gradle. En la barra de herramientas de Android Studio, selecciona Sync Project with Gradle Files ( b451ab2d04d835f9.png).

(Si se inhabilita este botón, asegúrate de importar solo starter/app/build.gradle, no todo el repositorio).

Cómo configurar y ejecutar la detección de objetos en el dispositivo en una imagen

Solo hay 3 pasos sencillos con 3 API para cargar y ejecutar un modelo de detección de objetos:

  • Prepara una imagen o una transmisión: TensorImage
  • crea un objeto detector: ObjectDetector
  • conecta los 2 objetos anteriores: detect(image)

Esto se logra dentro de la función runObjectDetection(bitmap: Bitmap)en el archivo MainActivity.kt.

/**
* TFLite Object Detection Function
*/
private fun runObjectDetection(bitmap: Bitmap) {
    //TODO: Add object detection code here
}

En este momento, la función está vacía. Sigue los pasos que se indican a continuación para implementar el detector de objetos TFLite. Durante el proceso, Android Studio te pedirá que agregues las importaciones necesarias:

  • org.tensorflow.lite.support.image.TensorImage
  • org.tensorflow.lite.task.vision.detector.ObjectDetector

Crea un objeto de imagen

Las imágenes que usarás para este codelab provendrán de la cámara del dispositivo o de imágenes preseleccionadas que selecciones en la IU de la app. La imagen de entrada se decodifica en el formato Bitmap y se pasa al método runObjectDetection.

TFLite brinda una API simple para crear un objeto TensorImage a partir de Bitmap. Agrega el siguiente código en la parte superior de runObjectDetection(bitmap:Bitmap):

// Step 1: create TFLite's TensorImage object
val image = TensorImage.fromBitmap(bitmap)

Crea una instancia de detector

La biblioteca de tareas de TFLite sigue el patrón de diseño de compilador. Debes pasar la configuración a un compilador y, luego, adquirir un detector. Existen varias opciones para configurar, incluida la configuración de la sensibilidad del detector de objetos:

  • max result (la cantidad máxima de objetos que el modelo debería detectar)
  • umbral de puntuación (qué tan confiable debe ser el detector de objetos para mostrar un objeto detectado)
  • etiquetar lista de entidades permitidas o rechazar (permitir o rechazar los objetos de una lista predefinida)

Inicializa la instancia del detector de objetos especificando el nombre de archivo del modelo de TFLite y las opciones de configuración:

// Step 2: Initialize the detector object
val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setMaxResults(5)
    .setScoreThreshold(0.5f)
    .build()
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "model.tflite", // must be same as the filename in assets folder
    options
)

Imágenes del feed en el detector

Agrega el siguiente código a fun runObjectDetection(bitmap:Bitmap). De este modo, se enviarán tus imágenes al detector.

// Step 3: feed given image to the model and print the detection result
val results = detector.detect(image)

Cuando se completa, el detector muestra una lista de Detection, cada una con información sobre un objeto que el modelo encontró en la imagen. Cada objeto se describe con lo siguiente:

  • boundingBox: el rectángulo que declara la presencia de un objeto y su ubicación dentro de la imagen
  • categories: qué tipo de objeto es y qué tan seguro está el modelo con el resultado de la detección. El modelo muestra varias categorías, y la más segura es la primera.
  • label: Es el nombre de la categoría del objeto.
  • classificationConfidence:un número de punto flotante entre 0.0 y 1.0, en el que 1.0 representa el 100%

Agrega el siguiente código a fun runObjectDetection(bitmap:Bitmap). De esta manera, se llama a un método para imprimir los resultados de la detección de objetos en Logcat.

// Step 4: Parse the detection result and show it
debugPrint(results)

Luego, agrega este método debugPrint() a la clase MainActivity:

private fun debugPrint(results : List<Detection>) {
    for ((i, obj) in results.withIndex()) {
        val box = obj.boundingBox

        Log.d(TAG, "Detected object: ${i} ")
        Log.d(TAG, "  boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")

        for ((j, category) in obj.categories.withIndex()) {
            Log.d(TAG, "    Label $j: ${category.label}")
            val confidence: Int = category.score.times(100).toInt()
            Log.d(TAG, "    Confidence: ${confidence}%")
        }
    }
}

El detector de objetos ya está listo. Compila y ejecuta la app haciendo clic en Run ( execute.png) en la barra de herramientas de Android Studio. Una vez que la app aparezca en el dispositivo, presiona cualquiera de las imágenes preestablecidas para iniciar el detector de objetos. Luego, observa la ventana Logcat*(* 16bd6ea224cf8cf1.png*)* dentro del IDE, y deberías ver algo similar a lo siguiente:

D/TFLite-ODT: Detected object: 0
D/TFLite-ODT:   boundingBox: (0.0, 15.0) - (2223.0,1645.0)
D/TFLite-ODT:     Label 0: dining table
D/TFLite-ODT:     Confidence: 77%
D/TFLite-ODT: Detected object: 1
D/TFLite-ODT:   boundingBox: (702.0, 3.0) - (1234.0,797.0)
D/TFLite-ODT:     Label 0: cup
D/TFLite-ODT:     Confidence: 69%

Esto indica que el detector detectó 2 objetos. La primera es:

  • Un objeto está dentro del rectángulo de (0, 15) a (2223, 1645)
  • La etiqueta es mesa de comedor
  • El modelo confía en que la primera es una mesa de comedor (77%).

Técnicamente, eso es todo lo que necesitas para que la Biblioteca de tareas de TFLite funcione en este momento. Felicitaciones.

Sin embargo, en el lado de la IU, todavía estás en el punto de partida. Ahora, debes usar los resultados detectados en la IU mediante el procesamiento posterior de los resultados detectados.

6. Dibuja el resultado de la detección en la imagen de entrada

En pasos anteriores, imprimiste el resultado de la detección en logcat: simple y rápido. En este paso, utilizarás el método de utilidad que ya está implementado en la app de inicio para hacer lo siguiente:

  • dibujar un cuadro de límite en una imagen
  • dibujar un nombre de categoría y un porcentaje de confianza dentro del cuadro de límite
  1. Reemplaza la llamada debugPrint(results) por el siguiente fragmento de código:
val resultToDisplay = results.map {
    // Get the top-1 category and craft the display text
    val category = it.categories.first()
    val text = "${category.label}, ${category.score.times(100).toInt()}%"

    // Create a data object to display the detection result
    DetectionResult(it.boundingBox, text)
}
// Draw the detection result on the bitmap and show it.
val imgWithResult = drawDetectionResult(bitmap, resultToDisplay)
runOnUiThread {
    inputImageView.setImageBitmap(imgWithResult)
}
  1. Ahora, haz clic en Run ( execute.png) en la barra de herramientas de Android Studio.
  2. Cuando se cargue la app, presiona una de las imágenes predeterminadas para ver el resultado de la detección.

¿Quieres probar con tu propia foto? Presiona el botón Tomar foto y captura algunas fotos de los objetos a tu alrededor.

8b024362b15096a6.png

7. Entrena un modelo de detección de objetos personalizado

En el paso anterior, integraste un modelo de detección de objetos TFLite previamente entrenado en la app para Android y viste que puede detectar objetos comunes, como cuencos o mesas de comedor, en imágenes de muestra. Sin embargo, tu objetivo es detectar los ingredientes de los platos de la imagen, por lo que la detección general de objetos no se adapta a tu caso de uso. Desea entrenar un modelo de detección de objetos personalizado mediante un conjunto de datos de entrenamiento con los ingredientes que queremos detectar.

A continuación, se muestra un conjunto de datos que contiene imágenes y etiquetas que puede usar para practicar el entrenamiento de su propio modelo personalizado. Se creó con imágenes del conjunto de datos de imágenes abiertas V4.

Colaboratory

A continuación, iremos a Google Colab para entrenar el modelo personalizado.

Entrenar el modelo personalizado demorará unos 30 minutos.

Si tienes prisa, puedes descargar un modelo previamente entrenado para ti en el conjunto de datos proporcionado y continuar con el siguiente paso.

8. Integra el modelo de TFLite personalizado a la app para Android

Ahora que entrenaste un modelo de detección de ensaladas, intégralo y convierte tu app de un detector de objetos común a uno específico.

  1. Copia el modelo de TFLite de ensalada en la carpeta assets. Asigna el nombre salad.tflite al nuevo modelo.

91e8d37c4f78eddb.png

  1. Abre el archivo MainActivity.kt y busca el código de inicialización ObjectDetector.
  2. Reemplaza el modelo eficienteDet-Lite (model.tflite) por el modelo de ensalada (salad.tflite)
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "salad.tflite", // must be same as the filename in assets folder
    options
)
  1. En la barra de herramientas de Android Studio, haz clic en Run ( execute.png) para volver a ejecutar la app con el modelo nuevo. ¡Listo! La app ahora puede reconocer quesos, ensaladas, productos horneados.

b9705235366ae162.png

9. ¡Felicitaciones!

Usaste TFLite para entrenar un modelo personalizado y agregar capacidades de detección de objetos a tu app. ¡Eso es todo lo que necesitas para ponerte en marcha!

Temas abordados

  • Cómo encontrar modelos de detección de objetos TFLite previamente entrenados en TensorFlow Hub
  • Cómo integrar modelos de detección de objeciones a tu app para Android mediante la Biblioteca de tareas de TFLite
  • Cómo entrenar un modelo de detección de objetos personalizado con TFLite Model Maker

Próximos pasos

  • Usa Firebase para mejorar la implementación del modelo de TFLite
  • Recopila datos de entrenamiento para entrenar tu propio modelo
  • Aplica la detección de objetos en tu propia app para Android

Más información