Reconoce flores con TensorFlow Lite en iOS

1. Introducción

657431be3173fa86.png

TensorFlow es un framework multipropósito de aprendizaje automático. TensorFlow se puede usar en cualquier lugar, ya sea para entrenar modelos grandes en clústeres en la nube o para ejecutar modelos de forma local en un sistema incorporado, como tu teléfono.

En este codelab, se usa TensorFlow Lite para ejecutar un modelo de reconocimiento de imágenes en un dispositivo iOS.

Qué aprenderás

  • Cómo optimizar tu modelo con el conversor de TFLite.
  • Cómo ejecutarlo en una app para iOS prediseñada mediante el intérprete de TFLite

Qué compilarás

Una app de cámara sencilla que ejecuta un programa de reconocimiento de imágenes de TensorFlow para identificar flores.

Requisitos previos

Si realizas este codelab en tu propio hardware, asegúrate de tener instalado lo siguiente:

  • Xcode 10 o una versión más reciente
  • CocoaPods 1.8.0 o una versión más reciente

c45ecd122998622e.png

Licencia: De uso gratuito

2. Entrena un reconocedor de flores con Colab

En este codelab, se usará Colaboratory y Xcode.

Abre Colab, que usa Model Maker de TensorFlow Lite para entrenar un clasificador a fin de reconocer flores con el aprendizaje por transferencia y exportar un modelo de TFLite que se usará en la app para dispositivos móviles.

3. Configura el directorio de trabajo

Clona el repositorio de Git

Con el siguiente comando, se clonará el repositorio de Git que contiene los archivos necesarios para este codelab:

git clone https://github.com/tensorflow/examples.git

Ahora cd ve a la raíz del proyecto Xcode del clon que acabas de crear. Allí es donde trabajarás para el resto de este codelab:

cd examples/lite/examples/image_classification/ios

4. Configura la app para iOS

Instala las dependencias

Con CocoaPods, instala las dependencias de la app para iOS (incluido TensorFlow Lite). Cuando finalice el comando de instalación, abre ImageClassification.xcworkspace para abrir el proyecto en Xcode.

pod install --repo-update
open ImageClassification.xcworkspace

5. Haz una ejecución de prueba de la app

Para usar la cámara, la app debe ejecutarse en un dispositivo real, ya que el simulador de iOS no tiene acceso a la cámara de tu Mac. Para realizar compilaciones en un dispositivo iOS, debes estar inscrito en el Programa para desarrolladores de Apple o tener acceso a un dispositivo que otra persona te haya aprovisionado.

Si quieres ejecutar este codelab en el simulador, deberás copiar imágenes al portapapeles de Safari en el simulador. Estos son los pasos para procesar una imagen en el simulador:

  1. Compila la app en el simulador que elijas.
  2. En el simulador de iOS, presiona Cmd + Mayúsculas + H para minimizar la app.
  3. Presiona Safari en la parte inferior de la pantalla principal y busca una imagen.
  4. En los resultados de la búsqueda de imágenes de Google, presiona un resultado y mantén presionada la imagen. En el diálogo que aparece, selecciona "Copiar".
  5. Regresa a la app de TFL Classify. La imagen copiada debería mostrarse automáticamente junto con los resultados de la inferencia. Si no es así, asegúrate de haber copiado los datos de la imagen en sí y no la URL de la imagen.

Prueba la compilación y, luego, instala la app

Antes de realizar cambios en la app, ejecutemos la versión que se incluye en el repositorio. Selecciona tu dispositivo iOS en el menú desplegable de la parte superior izquierda:

275753d3a77a0df3.png

Luego, presiona Cmd + R o el botón Reproducir f96cf117245c0fa6.png en Xcode para compilar la app en tu dispositivo. La app debería iniciarse automáticamente una vez que esté instalada en tu dispositivo.

Esta versión de la app usa MobileNet estándar, previamente entrenada en las 1,000 categorías de ImageNet. Debería verse algo similar a esto:

d11436f0bb5a75db.jpeg

6. 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.

Ahora modifiquemos la app para que esta use nuestro modelo que se volvió a entrenar para las categorías de imágenes personalizadas entrenadas en Colab.

7. Convierte la app para ejecutar tu modelo

Agrega los archivos del modelo al proyecto

Los recursos del modelo del proyecto se encuentran en ImageClassification > Model en el navegador del proyecto de Xcode. Para reemplazarlos, primero borra los dos archivos existentes en el grupo Model. Cuando se te solicite, selecciona “Mover a la papelera”:

cf2f7fefb2e5075f.png

Luego, arrastra los archivos model.tflite y labels.txt que descargaste de Colab al grupo Modelos. Cuando se te solicite, asegúrate de que Copy items if needed y Add to targets estén seleccionados.

281d7eb72635bb5f.png

Cómo modificar el código de la app

Para que nuestra app funcione, debemos actualizar la ruta de la lógica de carga del modelo para que apunte al modelo nuevo que agregamos.

Abre ModelDataHandler.swift (ruta del navegador de Xcode: ImageClassification -> ModelDataHandler -> ModelDataHandler.swift) y cambia la línea 36 a

// before
static let modelInfo: FileInfo = (name: "mobilenet_quant_v1_224", extension: "tflite")

// after
static let modelInfo: FileInfo = (name: "model", extension: "tflite")

Asegúrate de guardar todos los cambios.

8. Ejecuta la app personalizada

Presiona Cmd + B o el botón Reproducir f96cf117245c0fa6.png en Xcode para compilar la app en tu dispositivo. Una vez que se inicie la app, debería verse así:

c45ecd122998622e.png

Para tomar una captura de pantalla, puedes mantener presionados los botones de encendido y subir volumen al mismo tiempo.

Ahora intenta buscar flores en la Web, apunta la cámara a la pantalla de la computadora y comprueba si esas imágenes se clasifican correctamente.

También puedes pedirle a un amigo que te tome una foto y descubra qué tipo de TensorFlower eres \\uf339 \\uf33b \\uf337.

9. ¿Cómo funciona?

Ahora que la app está en ejecución, veamos el código específico de TensorFlow Lite.

TensorFlowLiteSwift

Esta app usa la biblioteca de TensorFlowLite Swift a través de CocoaPods. La biblioteca de Swift es un wrapper delgado sobre la API de TFLite C, que es a su vez un wrapper de la biblioteca C++ de TFLite.

Las siguientes líneas del archivo Podfile del módulo extraen la versión más reciente del repositorio de especificaciones globales de CocoaPods del módulo al proyecto.

Podfile

target 'ImageClassification' do
  use_frameworks!

  # Pods for ImageClassification
   pod 'TensorFlowLiteSwift'
end

Usa la API de Swift de TensorFlow Lite

El código que interactúa con TensorFlow Lite se encuentra en ModelDataHandler.swift.

Configuración

El primer bloque de interés es el inicializador de ModelDataHandler:

ModelDataHandler.swift

/// A failable initializer for `ModelDataHandler`. A new instance is created if the model and
/// labels files are successfully loaded from the app's main bundle. Default `threadCount` is 1.
init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int = 1) {
  let modelFilename = modelFileInfo.name

  // Construct the path to the model file.
  guard let modelPath = Bundle.main.path(
    forResource: modelFilename,
    ofType: modelFileInfo.extension
  ) else {
    print("Failed to load the model file with name: \(modelFilename).")
    return nil
  }

  // Specify the options for the `Interpreter`.
  self.threadCount = threadCount
  var options = InterpreterOptions()
  options.threadCount = threadCount
  do {
    // Create the `Interpreter`.
    interpreter = try Interpreter(modelPath: modelPath, options: options)
    // Allocate memory for the model's input `Tensor`s.
    try interpreter.allocateTensors()
  } catch let error {
    print("Failed to create the interpreter with error: \(error.localizedDescription)")
    return nil
  }
  // Load the classes listed in the labels file.
  loadLabels(fileInfo: labelsFileInfo)
}

Hay algunas líneas que deben analizarse con más detalle.

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

ModelDataHandler.swift

interpreter = try Interpreter(modelPath: modelPath, options: options)

El intérprete se encarga de pasar entradas de datos sin procesar a través del grafo de TensorFlow. Pasamos al intérprete la ruta de acceso a nuestro modelo en el disco y, luego, lo carga como un FlatBufferModel.

La última línea carga la lista de etiquetas:

loadLabels(fileInfo: labelsFileInfo)

Todo lo que hace es cargar cadenas de un archivo de texto a la memoria.

Ejecuta el modelo

El segundo bloque de interés es el método runModel. Toma un objeto CVPixelBuffer como entrada, ejecuta el intérprete y muestra el texto que se imprimirá en la app.

ModelDataHandler.swift

try interpreter.copy(rgbData, toInputAt: 0)
// ...
try interpreter.invoke()
// ...
outputTensor = try interpreter.output(at: 0)

10. ¿Qué sigue?

Aquí tienes algunos vínculos para obtener más información: