FOMO: Machine Learning con OpenVM Cam H7 Plus y Edge Impulse

Introducción

En el anterior tutorial vimos cómo  generar un modelo de Machine Learning (o aprendizaje automático) para construir un sistema que pueda reconocer objetos y clasificarlos a través de una cámara conectada a un microcontrolador (en nuestro caso con la placa OpenVM Cam H7 Plus).

https://mecatronicalab.es/machine-learning-con-openvm-cam-h7-plus-y-edge-impulse/

En esta ocasión vamos a crear un modelo de Machine Learning pero no para clasificar objetos si no para detectar dentro de una imagen cuántos objetos existen y en qué posición.

La clasificación de imágenes permite saber qué tipo de objeto es el que estamos tomando como imagen pero ¿y si lo que queremos saber no es si está el objeto “A” o el objeto “B” en una imagen si no saber qué cantidad de objetos  “A” y “B”  hay en esa imagen, su posición y su tamaño?, si a eso le sumamos que en muchos de los proyectos de detección de objetos en realidad no se necesita saber el tamaño de los objetos, sino sólo su posición y cuántos objetos hay, es ahí donde podemos utilizar la nueva solución (modelo) que ha creado Edge Impulse: Faster Objects, More Objects (FOMO) capaz de ejecutarse en microcontroladores.

https://www.edgeimpulse.com/blog/announcing-fomo-faster-objects-more-objects

https://docs.edgeimpulse.com/docs/edge-impulse-studio/learning-blocks/object-detection/fomo-object-detection-for-constrained-devices

Software necesario

Para realizar este proyecto es necesario instalar el siguiente software:

  1. Instalar el OpenVM IDE: https://openmv.io/pages/download
  2. Crearnos una cuenta en la plataforma Cloud Edge Impulse (es gratis para desarrolladores): https://studio.edgeimpulse.com/signup

Generando el modelo

Para crear el modelo nos vamos a basar en el tutorialDetect objects with centroids’ que explica Edge Impulse en su página Web:

En este tutorial vamos a realizar un modelo que detecte gaviotas volando. El modelo nos tendrá que decir cuántas gaviotas hay y en qué posición están. Para ello colocaremos delante de la OpenVM Cam H7 Plus una tablet con un video de gaviotas volando y ejecutaremos el modelo de Machine Learning para ver qué tan preciso es.

Generando el Dataset

Para construir el dataset con el OpenVM IDE nos basaremos en el tutorial paso a paso explicado en el siguiente enlace.

La diferencia es que como el modelo que vamos a utilizar no es de clasificación de imágenes sólo usaremos esta utilidad para tomar fotografías de una única clase: gaviota. Realmente el “etiquetado”, para este tipo de proyectos, lo haremos más adelante en la plataforma Edge Impulse (mediante una utilidad que dispone) donde tendremos que ir fotografía a fotografía seleccionando mediante un recuadro cada objeto, en nuestro caso gaviotas, que está presente en la imagen y etiquetarlo como tal.

Cuantas más variedad de imágenes se capturen mejor, pero con unas 30 – 40 imágenes para este proyecto serán suficientes. También es importante tomar imágenes con diferentes ángulos y distancias aunque para este proyecto como nuestra cámara estará en una posición y ángulo fijos enfocando a una tablet que estará mostrando un video de gaviotas volando este punto no será necesario.

Para crear el dataset utilizaremos la opción Herramientas → Editor de conjunto de datos → Nuevo conjunto de datos que se encuentra dentro del editor OpenVM IDE.

Esto abre el panel Editor de conjunto de datos‘ en el lado izquierdo y el script de captura de conjunto de datos ‘dataset_capture_script.py’ en el panel principal del OpenVM IDE.

Ahora crearemos la única clase que llamaremos gaviota.class

Empezaremos a tomar fotos. Para ello:

  1. Clicamos en el icono Play para ejecutar el script  ‘dataset_capture_script.py’.
  2. Seleccionamos la clase haciendo clic en el nombre de la carpeta en el Editor de conjuntos de datos.
  3. Vamos tomando instantáneas haciendo clic en el botón ‘Captura de datos’ (icono de cámara del panel en el lado izquierdo).

Subiendo el dataset a la plataforma Edge Impulse

Entraremos en la plataforma Edge Impulse, crearemos un proyecto y dentro de la sección ‘Dashboard’  iremos a la sección ‘Project info’ (situada a la derecha) y seleccionaremos en Labeling method la opción: Bounding boxes (object detection). Con esto lo que estamos diciendo es que en este proyecto al ser de detección de objetos y no de clasificación de imágenes el etiquetado del objeto/s que tendremos que hacer será diferente (lo veremos más adelante).

Ahora iremos a la sección ‘Data acquisition’ de nuestro proyecto y seleccionaremos la opciónUpload data’ para subir las imágenes de nuestro dataset a la plataforma. Dejaremos seleccionada la opción que viene por defecto ‘Automatically split between training and testing’ dentro de la sección ‘Upload into category’. Seleccionaremos los archivos y le daremos al botón ‘Begin upload’.

Una vez se han subido las imágenes iremos a la sección ‘Labeling queue’ y empezaremos a marcar mediante un recuadro todas las gaviotas que se encuentran en la imagen y etiquetando cada recuadro como “gaviota”. Este proceso lo tendremos que repetir por cada imagen.

 

Una vez realizado este proceso se podrá apreciar que los datos se han dividido automáticamente entre datos de entrenamiento y datos de prueba en una proporción aproximada de 80/20.

Creando el Impulso

Dentro de la plataforma Edge Impulse, un impulso toma los datos sin procesar, ajusta el tamaño de la imagen, usa un bloque de procesamiento para extraer características de la imagen y luego usa un bloque de aprendizaje para clasificar nuevos datos.

En nuestro caso seleccionaremos los bloques que la propia plataforma nos recomienda para este tipo de proyectos. Son los siguientes:

Configuración del bloque de procesamiento de imagen

Seleccionamos la opción ‘Image’ presente en el menú izquierdo que se encuentra dentro de la opción  ‘Impulse design para configurar el bloque de procesamiento.

Una vez dentro de la opción podemos ver los datos sin procesar en la parte superior de la pantalla (podemos seleccionar otros archivos a través del menú desplegable) y los resultados del procesamiento a la derecha (DSP Result). Podemos usar la opción para cambiar  la profundidad de color entre el modo ‘RGB’ y ‘Escala de grises’ aunque dejaremos la profundidad de color en ‘RGB’ . Haremos clic en ‘Save parameters’

Esta acción nos llevará a la pantalla que generará las características. Una vez dentro de esa pantalla hacemos clic en el botón verde Generate features  que hará que se generen las siguientes acciones:

  • Cambiar el tamaño de todos los datos.
  • Aplicar el bloque de procesamiento sobre todos estos datos.
  • Cree una visualización 3D de su conjunto de datos completo.

Configuración del bloque de detección de objetos

Con todos los datos procesados, es hora de comenzar a entrenar una red neuronal. Las redes neuronales son un conjunto de algoritmos, modelados libremente según el cerebro humano, que están diseñados para reconocer patrones.

Seleccionamos la opción Object detection’ presente en el menú izquierdo que se encuentra dentro de la opción ‘Impulse design y una vez dentro de la pantalla hacemos clic en el botón ‘Start trainingpara empezar a entrenar la red neural. Antes debemos asegurarnos de tener las opciones de configuración de la red neuronal que nos aparecen en la pantalla con los siguientes valores:

  • Number of training cycles: 60.
  • Learning rate: 0.001.
  • Validation set size: 20%.
  • Data augmentation: marcado.
  • Transfer learning model: FOMO (Faster Objects, More Objects) MobileNetV2 0.35.

Una vez que termine de procesar ya tendremos el modelo entrenado y podremos ver el porcentaje del nivel de precisión que hemos obtenido (cuanto más grande sea este porcentaje mejor). En nuestro caso el nivel de precisión obtenido es del 89,5%.

 Validando el modelo

Con el modelo entrenado vamos a comprobar que tal funciona usando los datos de prueba (test). Recordemos que al cargar el dataset el conjunto de datos se dividió en una proporción aproximada de 80/20 entre datos de entrenamiento y datos de prueba. El modelo se entrenó solo con los datos de entrenamiento y lo que vamos a hacer ahora es usar los datos de prueba para validar qué tan bien funciona el modelo.

Para validar el modelo, iremos a la opción ‘Model testing’  (presente en el menú izquierdo) y veremos que en la pantalla aparece el listado de todas las imágenes de prueba. 

Podemos clasificar una imagen individual de las que aparecen en la lista (seleccionando dentro de los 3 puntitos que aparecen junto a la muestra la opción ‘Show classification’) o podríamos clasificar todas las imágenes con la opción ‘Classify all’. En nuestro caso las clasificaremos todas.

El resultado que nos ha dado ha sido excelente ya que hemos obtenido una precisión del 100%.

 Ejecutar el modelo en nuestro dispositivo

Ahora iremos a la opción del menú izquierdo ‘Deployment’  y exportaremos  el modelo como una librería y no como un firmware.

En el siguiente enlace podéis ver un tutorial de cómo exportar el modelo creado desde la plataforma Edge Impulse a nuestra OpenVM Cam H7 tanto como una librería como un firmware.

Para ello seleccionamos la biblioteca OpenMV y hacemos clic en el botón ‘Build’ que se encuentra en la parte inferior de la pantalla. 

Se generará un archivo .zip que contiene 3 archivos:  ‘trained.tflite’ (modelo creado), ‘labels.txt’  y ‘ei_object_detection.py’.

Para agregar el modelo a su nuestra cámara OpenMV Cam H7 Plus copiaremos los archivos ‘trained.tflite’ y ‘labels.txt’ en la unidad flash (unidad USB que se crea al conectar el dispositivo en el ordenador) de la  OpenMV Cam H7 Plus.

Por último lo que haremos es abrir el script ‘ei_object_detection.py’ en el OpenMV IDE y ejecutarlo. Solo cambiaremos ligeramente esta script para que el centroide que aparece al detectar la gaviota sea de color rojo y más pequeño.

Podéis descargar el script ya modificado así como el modelo generado en el siguiente enlace:

https://github.com/avilmaru/openvmcamh7plus_machinelearning_fomo

Al ejecutar el modelo podemos ver que detecta y posiciona correctamente las gaviotas presentes en el video. Es cierto que cuando dos o más gaviotas se solapan no detecta las que se encuentran detrás pero esto es algo normal ya que no es posible detectar objetos con centroides superpuestos. La verdad es que el modelo FOMO de Machine Learning creado por Edge Impulse para detectar objetos funciona muy bien y ofrece un sinfín de posibilidades.

NOTA: Créditos del video de las gaviotas (Metraje de stock Videezy)