Detección de objetos con YOLO: implementaciones y como usarlas

enrique a.
6 min readMay 12, 2018

--

La mayoría de los proyectos de Machine Learning que se están considerando en la empresa donde comencé mi nuevo empleo incluyen de alguna u otra manera la detección de objetos en imágenes. La detección de objetos en imágenes implica, no solamente identificar de que tipo de objeto se trata, sino también localizarlo dentro de la imagen (obtener las coordenadas de la “caja” que lo contiene). En otras palabras, detección = clasificación + localización.

Afortunadamente tuve el tiempo para poder pasar primeras semanas investigando el estado del arte en sistemas y algoritmos de detección. Como en casi cualquier problema, todos los caminos llevan a Deep Learning. Después de comparar varias alternativas, me decidí por explorar YOLO como primera opción, principalmente porque está muy bien explicado en el curso sobre redes neuronales convolucionales (CNN) que he estado siguiendo desde hace algunos meses en Coursera (https://www.deeplearning.ai/), y claro, también por su nombre ;).

Ver http://cv-tricks.com/object-detection/faster-r-cnn-yolo-ssd/ para una buena comparación entre varios diferentes algoritmos.

YOLO: You Only Look Once

Sin entrar mucho a los detalles, porque quiero enfocarme en sus diferentes implementaciones y como usarlas: YOLO (You Only Look Once) utiliza deep learning y CNN para detectar objetos, y se distingue de sus “competidores” porque, como lo indica su nombre requiere de “ver” la imagen una sola vez, lo que le permite ser el más rápido de todos (aunque sacrifica un poco de exactitud). Esta rapidez le permite fácilmente detectar objetos en tiempo real en videos (hasta 30 FPS).

Para llevar a cabo la detección primero divide la imagen en una cuadrícula de SxS (imagen de la izquierda). En cada una de las celdas predice N posibles “bounding boxes” y calcula el nivel de certidumbre (o probabilidad) de cada una de ellas (imagen del centro), es decir, se calculan SxSxN diferentes cajas, la gran mayoría de ellas con un nivel de certidumbre muy bajo. Después de obtener estas predicciones se procede a eliminar las cajas que estén por debajo de un límite. A las cajas restantes se les aplica un paso de “non-max suppression” que sirve para eliminar posibles objetos que fueron detectados por duplicado y así dejar únicamente el mas exacto de ellos (imagen de la derecha).

Al momento de escribir esto, YOLO ha pasado por tres iteraciones, cada una es una mejora gradual sobre la versión anterior. Se pueden consultar los artículos:

Implementaciones

Actualmente hay 3 principales implementaciones de YOLO, cada una con sus ventajas y desventajas.

  1. Darknet (https://pjreddie.com/darknet/). Es la implementación “oficial” de YOLO, creada por las mismas personas detrás del algoritmo. Está escrito en C con CUDA, así que soporta cómputo con GPU. En realidad es todo un framework para redes neuronales, así que se puede usar para otros objetivos además de YOLO. La desventaja es que, al no estar basado en un framework de uso extendido, podría ser más difícil encontrar soluciones para los posibles errores.
  2. AlexeyAB/darknet (https://github.com/AlexeyAB/darknet). Aquí en realidad estoy haciendo trampa, porque este es un fork de Darknet original para Windows y Linux. En realidad no lo he utilizado, pero he consultado su README, que es excelente y tiene muy buenas recomendaciones sobre YOLO en general, como entrenar, etc.
  3. Darkflow (https://github.com/thtrieu/darkflow/). Es el port de Darknet a TensorFlow. Este es el sistema que más he estado utilizando, principalmente porque inicié este proyecto sin contar con GPU para entrenar la red, y al parecer usando solamente CPU Darkflow as mucho más rápido que el Darknet original. Hasta donde tengo entendido, la desventaja es que no ha sido actualizado para YOLOv3.

Actualización 09/09/2018: He publicado en español el tutorial paso a paso de como utilizar Darkflow para entrenar YOLO para detectar nuestros propios objectos.

Todas estas implementaciones vienen “listas para usarse”, es decir, después de descargarlas e instalarlas, se pueden descargar los pesos para las redes entrenadas, y se puede realizar la detección de objetos en imágenes o videos de inmediato. Naturalmente las posibilidades están limitadas a las clases que contienen los sets de datos con las que fueron entrenadas.

Como era de esperarse todas estas implementaciones permiten también el entrenamiento para detectar nuevas clases. Como en cualquier problema de Machine Learning una de las primeras dificultades es obtener el set de datos, o crearlo por nuestra cuenta :).

Crear el set de entrenamiento para nuevas clases

Un set de entrenamiento para YOLO consiste en una serie de imágenes, cada una acompañada de un archivo de texto indicando las coordenadas y la clase a la que pertenece cada uno de los objetos.

Desafortunadamente no hay hasta el momento un estándar de como representar esta información. En otras palabras, cada sistema utiliza un formato diferente:

  • Darknet utiliza un archivo de texto muy sencillo, con el siguiente formato
[category number] [object center in X] [object center in Y] [object width in X] [object width in Y]
  • Darkflow espera las anotaciones en el formato del set de datos PASCAL VOC, que es el utilizado para ImageNet
<annotation>
<folder>map_text/images</folder>
<filename>_ATRP_0001_003_001.JPEG</filename>
<size>
<width>608</width>
<height>608</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>map_text</name>
<pose>center</pose>
<truncated>1</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>6</xmin>
<ymin>318</ymin>
<xmax>97</xmax>
<ymax>409</ymax>
</bndbox>
</object>
<!-- more object instances -->
</annotation>

Herramientas para crear el set de entrenamiento

Existen varias herramientas que se pueden utilizar para crear las anotaciones de las imágenes que van a ser parte del set de entrenamiento. Es decir, indicar manualmente las “cajas” que contienen a cada uno de los objetos, e indicar a cual de las clases pertenece.

Un ejemplo de una herramienta para crear anotaciones

Lamentablemente, siguiendo un tutorial (que por lo demás es muy bueno), comencé (y casi terminé) la creación de mi set de datos utilizando BBox-Label-Tool, así que tuve que escribir además un script para convertir a los formatos aceptados por Darknet o Darkflow (estoy consultando con mis jefes si vamos a publicar esos scripts en github).

EXTRA

  • Enriqueav/BBox-Label-Tool (https://github.com/enriqueav/BBox-Label-Tool). He creado un fork de BBox-Label-Tool que guarda las anotaciones en el formato de PASCAL VOC (para Darkflow). Lamentablemente no me basé en el branch multi-class, así que solo funciona para una clase por imagen.

Estoy planeando un tutorial más detallado, paso a paso, de como usar Darkflow desde la creación del set de datos, entrenamiento, validación, errores comunes, etc.

Actualización 09/09/2018: He publicado en español el tutorial paso a paso de como utilizar Darkflow para entrenar YOLO para detectar nuestros propios objectos.

Más información, referencias:

Especialización de deeplearning.ai en Coursera:

Acerca de las redes neuronales convolucionales:

Tutoriales para entrenar darknet:

--

--

enrique a.

Writing about Machine Learning, software development, python. Living in Japan working as a machine learning leader in a Japanese company.