Instructivo para la implementación de Edge en Android

Qué compilarás

En este instructivo, descargarás un modelo personalizado de TensorFlow Lite exportado que se creó mediante AutoML Vision Edge. Luego, ejecutarás una app para Android prediseñada que usa el modelo a fin de identificar imágenes de flores.

Captura de pantalla de un dispositivo móvil del producto final
Crédito de la imagen: Felipe Venâncio, “from my mother's garden” (CC BY 2.0, imagen que se muestra en la app).

Objetivos

En esta introducción detallada, usarás el código para lo siguiente:

  • Ejecutar un modelo previamente entrenado en una app para Android con el intérprete de TFLite

Antes de comenzar

Entrena un modelo desde AutoML Vision Edge

Antes de implementar un modelo en un dispositivo de Edge, sigue la guía de inicio rápido sobre modelos de dispositivos de Edge para entrenar y exportar un modelo de TF Lite desde AutoML Vision Edge.

Después de completar la guía de inicio rápido, debes tener exportados los siguientes archivos de modelos entrenados: un archivo de TF Lite, un archivo de etiquetas y un archivo de metadatos, como se muestra a continuación.

Archivos de modelos de TF Lite en Cloud Storage

Instala TensorFlow

Antes de comenzar el instructivo, debes instalar varios tipos de software:

Si tienes una instalación de Python que funcione, ejecuta los siguientes comandos para descargar este software:

pip install --upgrade  "tensorflow==1.7.*"
pip install PILLOW

Consulta la documentación de TensorFlow oficial si tienes problemas con este proceso.

Clona el repositorio de Git

Con la línea de comandos, clona el repositorio de Git mediante el siguiente comando:

git clone https://github.com/googlecodelabs/tensorflow-for-poets-2

Navega al directorio del clon local del repositorio (directorio tensorflow-for-poets-2). Ejecutarás todas las siguientes muestras de códigos de este directorio.

cd tensorflow-for-poets-2

Configura la app para Android

Instala Android Studio

Si es necesario, instala Android Studio 3.0+ de forma local.

Abre el proyecto con Android Studio

Para abrir un proyecto con Android Studio, sigue estos pasos:

  1. Abre Android Studio Ícono de inicio de Android Studio. Después de que se cargue, selecciona Ícono de abrir proyecto de Android Studio “Abrir un proyecto existente de Android Studio” (Open an existing Android Studio project) en esta ventana emergente:

    Ventana emergente para abrir el proyecto de Android Studio

  2. En el selector de archivos, selecciona tensorflow-for-poets-2/android/tflite en el directorio de trabajo.

  3. La primera vez que abras el proyecto, aparecerá una ventana emergente de “Gradle Sync” (Sincronización de Gradle) en la que se pregunta si deseas usar el wrapper de Gradle. Selecciona “OK” (Aceptar).

    Ventana emergente para abrir proyecto de Android Studio

Haz una ejecución de prueba de la app

La app puede ejecutarse en un dispositivo Android real o en Android Studio Emulator.

Configura un dispositivo Android

No puedes cargar la app de Android Studio al teléfono, a menos que actives el “modo de desarrollador” y la “depuración por USB”.

Para completar este proceso de configuración único, sigue estas instrucciones.

Configura el emulador con acceso a la cámara (opcional)

Si eliges usar un emulador en lugar de un dispositivo Android real, Android Studio facilita la configuración del emulador.

Debido a que esta app usa la cámara, configura la del emulador para que puedas usar la cámara de la computadora en lugar del patrón de prueba predeterminado.

Para configurar la cámara del emulador, debes crear un dispositivo nuevo en el “Android Virtual Device Manager” (Administrador de dispositivos virtuales de Android), un servicio al que puedes acceder con este botón Ícono del administrador de dispositivos virtuales. En la página principal de AVDM, selecciona “Create Virtual Device” (Crear un dispositivo virtual):

Opción de crear un dispositivo virtual de Android Studio

Luego, en la página “Verify Configuration” (Verificar configuración), la última página de la configuración del dispositivo virtual, selecciona “Show Advanced Settings” (Mostrar configuración avanzada):

Opción para crear un dispositivo virtual de Android Studio

Con la configuración avanzada que se muestra, puedes configurar ambas fuentes de cámaras para usar la cámara web de la computadora host:

Opción para elegir una fuente de cámara de Android Studio

Ejecuta la app original

Antes de realizar cambios en la app, ejecuta la versión que viene con el repositorio.

Para iniciar el proceso de compilación y de instalación, ejecuta una sincronización de Gradle.

Ícono de sincronización de Gradle

Después de ejecutar una sincronización de Gradle, selecciona reproducir Ícono de reproducción de Android Studio.

Después de seleccionar el botón de reproducción, deberás seleccionar el dispositivo en esta ventana emergente:

Ventana emergente de selección de dispositivos

Después de seleccionar el dispositivo, debes permitir que la demostración de Tensorflow acceda a tu cámara y a tus archivos:

Ventanas para permitir acceso a la cámara

Ahora que la app está instalada, haz clic en el ícono de la app Ícono de la app de Android Studio para iniciarla. Esta versión de la app usa MobileNet estándar, previamente entrenado en las 1,000 categorías de ImageNet.

Debería ser similar a esto:

App de ejecución de prueba

Ejecuta la app personalizada

La configuración predeterminada de la app clasifica las imágenes en una de las 1,000 clases de ImageNet mediante MobileNet estándar sin necesidad de realizar otro entrenamiento.

Ahora, realiza modificaciones a fin de que la app use un modelo que creó AutoML Vision Edge para las categorías de imágenes personalizadas.

Agrega los archivos del modelo al proyecto

El proyecto de demostración está configurado para buscar un graph.lite y un archivo labels.txt en el directorio android/tflite/app/src/main/assets/.

Reemplaza los dos archivos originales por tus versiones con los siguientes comandos:

cp [Downloads]/model.tflite android/tflite/app/src/main/assets/graph.lite
cp [Downloads]/dict.txt  android/tflite/app/src/main/assets/labels.txt

Modifica tu app

Esta app usa un modelo de número de punto flotante, mientras que el modelo que creó AutoML Vision Edge es cuantizado. Debes hacer algunos cambios de código para permitir que la app use el modelo.

Cambia el tipo de datos de labelProbArray y filterLabelProbArray de número de punto flotante a byte en la definición de miembros de la clase y en el inicializador ImageClassifier.

private byte[][] labelProbArray = null;
private byte[][] filterLabelProbArray = null;

labelProbArray = new byte[1][labelList.size()];
filterLabelProbArray = new byte[FILTER_STAGES][labelList.size()];

Asigna el imgData basado en el tipo int8, en el inicializador ImageClassifier.

    imgData =
        ByteBuffer.allocateDirect(
            DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);

Convierte el tipo de datos de labelProbArray de int8 a número de punto flotante en printTopKLabels():

  private String printTopKLabels() {
    for (int i = 0; i < labelList.size(); ++i) {
      sortedLabels.add(
          new AbstractMap.SimpleEntry<>(labelList.get(i), (float)labelProbArray[0][i]));
      if (sortedLabels.size() > RESULTS_TO_SHOW) {
        sortedLabels.poll();
      }
    }
    String textToShow = "";
    final int size = sortedLabels.size();
    for (int i = 0; i < size; ++i) {
      Map.Entry<String, Float> label = sortedLabels.poll();
      textToShow = String.format("\n%s: %4.2f",label.getKey(),label.getValue()) + textToShow;
    }
    return textToShow;
  }

Ejecuta tu app

En Android Studio, ejecuta una sincronización de Gradle para que el sistema de compilación pueda encontrar tus archivos:

Ícono de sincronización de Gradle

Después de ejecutar una sincronización de Gradle, selecciona reproducir Ícono de reproducción de Android Studio para iniciar el proceso de compilación e instalación como antes.

Debería ser similar a esto:

Captura de pantalla de un dispositivo móvil del producto final
Crédito de la imagen: Felipe Venâncio, “from my mother's garden” (CC BY 2.0, imagen que se muestra en la app).

Puedes mantener presionados los botones de encendido y de bajar volumen a la vez para tomar una captura de pantalla.

Si deseas probar la app actualizada, apunta la cámara a diferentes imágenes de flores para ver si se clasifican de forma correcta.

¿Cómo funciona?

Ahora que tienes la app en ejecución, examina el código específico de TensorFlow Lite.

AAR de TensorFlow-Android

Esta app usa un Android ARchive (AAR) de TFLite ya compilado. Este AAR está alojado en jcenter.

En las siguientes líneas del archivo build.gradle del módulo, se incluye la versión más reciente del AAR del repositorio de TensorFlow de Bintray y Maven del proyecto.

build.gradle

repositories {
    maven {
        url 'https://google.bintray.com/tensorflow'
    }
}

dependencies {
    // ...
    compile 'org.tensorflow:tensorflow-lite:+'
}

Usa el siguiente bloque para indicar a Android Asset Packaging Tool que los elementos .lite o .tflite no deben comprimirse. Esto es importante, ya que el archivo .lite se asignará en memoria y no funcionará cuando el archivo esté comprimido.

build.gradle

android {
    aaptOptions {
        noCompress "tflite"
        noCompress "lite"
    }
}

Usa la API de TFLite para Java

El código que interactúa con TFLite está incluido en ImageClassifier.java.

Configuración

El primer bloque de interés es el constructor de ImageClassifier:

ImageClassifier.java

ImageClassifier(Activity activity) throws IOException {
    tflite = new Interpreter(loadModelFile(activity));
    labelList = loadLabelList(activity);
    imgData =
        ByteBuffer.allocateDirect(
            4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);
    imgData.order(ByteOrder.nativeOrder());
    labelProbArray = new float[1][labelList.size()];
    Log.d(TAG, "Created a Tensorflow Lite Image Classifier.");
}

Hay algunas líneas de interés especial.

Con la siguiente línea, se crea el intérprete de TFLite:

ImageClassifier.java

tflite = new Interpreter(loadModelFile(activity));

Con esta línea se crea una instancia del intérprete de TFLite. El intérprete funciona de manera similar a una tf.Session (para aquellos familiarizados con TensorFlow, fuera de TFLite). Debes enviarle al intérprete un MappedByteBuffer que contenga el modelo. La función local loadModelFile crea un MappedByteBuffer que contiene el archivo de elementos graph.lite de la actividad.

Con las siguientes líneas, se crea el búfer de datos de entrada:

ImageClassifier.java

imgData = ByteBuffer.allocateDirect(
    4 * DIM_BATCH_SIZE * DIM_IMG_SIZE_X * DIM_IMG_SIZE_Y * DIM_PIXEL_SIZE);

Este búfer de bytes puede contener los datos de imágenes una vez que se convirtieron en float. El intérprete puede aceptar arreglos de número de punto flotante directamente como entrada, pero el ByteBuffer es más eficaz, ya que evita copias adicionales en el intérprete.

Con las siguientes líneas, se carga la lista de etiquetas y se crea el búfer de salida:

labelList = loadLabelList(activity);
//...
labelProbArray = new float[1][labelList.size()];

El búfer de salida es un arreglo de números de punto flotante con un elemento para cada etiqueta en el que el modelo escribirá las probabilidades de salida.

Ejecuta el modelo

El segundo bloque de interés es el método classifyFrame. Este método toma un Bitmap como entrada, ejecuta el modelo y muestra el texto que se imprimirá en la app.

ImageClassifier.java

String classifyFrame(Bitmap bitmap) {
 // ...
 convertBitmapToByteBuffer(bitmap);
 // ...
 tflite.run(imgData, labelProbArray);
 // ...
 String textToShow = printTopKLabels();
 // ...
}

Este método realiza tres acciones. Primero, el método convierte y copia el Bitmap de entrada en imgData ByteBuffer para la entrada del modelo. Luego, llama al método de ejecución del intérprete y pasa el búfer de entrada y el arreglo de salida como argumentos. El intérprete establece los valores del arreglo de salida según la probabilidad calculada para cada clase. Los nodos de entrada y de salida se definen mediante los argumentos del paso de conversión toco que creó el archivo del modelo .lite antes.

Próximos pasos

Completaste un instructivo de una app de clasificación de flores de Android mediante un modelo de Edge. Probaste una app de clasificación de imágenes antes de hacerle modificaciones y obtener anotaciones de muestra. Luego examinaste el código específico de TensorFlow Lite para comprender la funcionalidad subyacente.