• Saltar a la navegación principal
  • Saltar al contenido principal
Logo Codificando Bits

Codificando Bits

  • Academia
    • Rutas
    • Cursos
    • Proyectos
    • Tutoriales
  • Acceder
  • Suscribirse

Algoritmo YOLO para la detección de objetos: cómo funciona paso a paso

La detección de objetos en imágenes es una de las aplicaciones más comunes de la Visión por Computador en la actualidad.

Y YOLO (del Inglés You Only Look Once) es, tal vez, el algoritmo y modelo de Deep Learning más usado en la actualidad para realizar este tipo de tarea. Así que en este artículo explico todos los detalles de cómo funciona la versión original de este algoritmo, comenzando con lo esencial (entender qué es la detección de objetos) hasta llegar a los detalles de cómo se entrena la Red Convolucional usada por este algoritmo para generar las predicciones y detectar objetos en una imagen.

Conceptos básicos: clasificación, localización y detección

Para entender qué es y cómo funciona YOLO, tenemos que comenzar entendiendo cada uno de sus elementos básicos.

Así que comenzaremos analizando qué es la detección de objetos y cómo se codifica numéricamente la información de los objetos que queremos detectar. Y para ello es clave entender tres sencillos conceptos de Visión por Computador que están muy relacionados pero que a la vez tienen ligeras diferencias: clasificación, localización y detección.

Clasificación

Supongamos que tenemos un modelo al cual le introducimos una imagen, por ejemplo una imagen que contiene una silla. Lo que nos interesa en la clasificación es que el modelo le asigne una categoría a esa imagen (la categoría «silla»):

Idea básica de la clasificación de imágenes en la Visión por Computador
Idea básica de la clasificación de imágenes en la Visión por Computador

Así que lo que busca la clasificación es asignar una categoría a la totalidad de la imagen de entrada.

Localización

Si vamos un poco más allá y hablamos de la localización, la idea es que el modelo acepte la imagen pero a la salida nos entregue dos elementos. El primero de ellos nos tiene que indicar que lo que hay en la imagen es una silla. Pero lo más importante de la localización es que nos tiene que indicar en qué región de la imagen se encuentra ubicada dicha silla:

Idea básica de la localización de objetos en imágenes en la Visión por Computador
Idea básica de la localización de objetos en imágenes en la Visión por Computador

Visualmente, esto se representa enmarcando el objeto con un recuadro que se conoce como bounding box (una caja delimitadora) que enmarca la ubicación exacta del objeto.

Detección de objetos

La detección de objetos va un paso más allá de la clasificación y de la localización.

En una imagen de entrada podemos tener no solo una categoría o un único tipo de objeto, sino múltiples objetos. Así que la idea de la detección de objetos en imágenes es que, a la salida, el sistema nos tiene que entregar la categoría a la que pertenece cada objeto presente en la imagen y la ubicación exacta de cada uno de ellos:

Idea básica de la detección de objetos en imágenes en la Visión por Computador
Idea básica de la detección de objetos en imágenes en la Visión por Computador

Es decir, nos va a entregar múltiples bounding boxes, indicando para cada caja qué tipo de objeto contiene.

¡Y esto es precisamente lo que hace YOLO: una tarea de detección de múltiples objetos en imágenes!

Codificación numérica de los bounding boxes

En realidad, las Redes Convolucionales que usamos para detectar objetos no nos van a entregar a la salida una imagen con los recuadros dibujados y la categoría explícita. Lo que realmente entregan es la información codificada como un vector; es decir, un listado de valores numéricos.

Este vector contiene un total de siete elementos fundamentales para codificar un bounding box.

Probabilidad del objeto ($P_r$)

Este primer elemento nos indica la probabilidad de que haya o no un objeto de interés en la imagen. Y por tanto es un valor entre 0 y 1: si es muy cercano a 0, probablemente no hay objetos de interés (por más que haya árboles o césped en el fondo, si buscamos una silla, la probabilidad será baja), mientras que si es cercano a 1, tendremos un objeto de interés.

Así, para un ejemplo ideal con un solo objeto (como en la figura de abajo), codificamos este valor con un 1:

Codificación de la probabilidad de existencia de un objeto en YOLO
Codificación de la probabilidad de existencia de un objeto en YOLO

Coordenadas del centro ($B_x, B_y$)

Estas son las coordenadas del centro geométrico del bounding box y están normalizadas con respecto a la imagen total.

Por ejemplo, si enmarcamos la imagen en un eje X horizontal y un eje Y vertical (como se muestra en la figura de abajo), el origen (parte superior izquierda) es la coordenada (0,0) y el extremo inferior derecho es (1,1). Esto asume que el ancho y el alto de la imagen se normalizan a 1.

Y este escalamiento resulta clave pues al usar un detector de objetos en muchas aplicaciones tendremos imágenes de diferentes tamaños y el escalamiento garantiza que las coordenadas del centro del bounding box siempre estarán en el rango de 0 a 1:

Codificación de las coordenadas del centro del "bounding box" en YOLO
Codificación de las coordenadas del centro del «bounding box» en YOLO

Por ejemplo, en la figura de arriba el centro está aproximadamente en las coordenadas $B_x = 0.4$ y $B_y = 0.5$.

Dimensiones de la caja ($B_w, B_h$)

Estos valores representan el ancho y el alto del bounding box y también están normalizados con respecto al tamaño de la imagen original (por las mismas razones que vimos en el caso de anterior), así que sus valores oscilan entre 0 y 1:

Codificación del ancho y el alto del "bounding box" en YOLO
Codificación del ancho y el alto del «bounding box» en YOLO

Por ejemplo, si la caja ocupa la mitad de la imagen a lo ancho, $B_w$ será 0.5. Si ocupa un 70% del alto, $B_h$ será 0.7.

Categoría del objeto ($C_1, C_2, \dots, C_n$)

Los últimos elementos codifican la categoría del objeto.

Por ejemplo, si buscamos detectar dos tipos de objetos (sillas y mesas), usaremos dos números ($C_1$ y $C_2$). Y si tuviésemos 100 objetos, usaríamos desde $C_1$ hasta $C_{100}$.

Para el caso de dos objetos, si tenemos una silla, se codifica como 1 para $C_1$ y 0 para $C_2$. Y si fuese una mesa, la codificación sería 0 y 1:

Codificación de la categoría de los objetos en YOLO
Codificación de la categoría de los objetos en YOLO

¿Y si la imagen no contiene objetos a detectar?

En este caso el vector tendrá la misma cantidad de elementos, pero el componente de probabilidad ($P_r$) será etiquetado con un valor de 0. Este cero indica que no hay un objeto de interés, por lo cual los valores de todos los demás elementos del vector (coordenadas, dimensiones y clases) son irrelevantes y no se realizará un procesamiento posterior sobre ellos:

Codificación de la información en YOLO cuando no hay objetos a detectar
Codificación de la información en YOLO cuando no hay objetos a detectar

Operaciones fundamentales en YOLO

Para que YOLO realice la detección correctamente, se basa en un par de operaciones matemáticas y algorítmicas que permiten cuantificar el error y limpiar las predicciones redundantes. Veamos en detalle estas dos operaciones.

Intersección sobre Unión (Intersection over Union, IoU)

Al generar predicciones, los modelos de Deep Learning (como es el caso de YOLO) no son totalmente precisos.

El bounding box ideal (es decir demarcado por un humano) rara vez coincidirá a la perfección con el bounding box predicho por el modelo. Esto lo vemos en la figura de abajo del lado izquierdo, donde el bounding box ideal es de color fucsia y el predicho por el modelo es el amarillo:

El concepto de IoU (intersección sobre unión) en YOLO. A la izquierda el bounding box ideal (en fucsia) y el bounding box predicho (en amarillo); a la derecha el resultado de calcular el IoU
El concepto de IoU (intersección sobre unión) en YOLO. A la izquierda el bounding box ideal (en fucsia) y el bounding box predicho (en amarillo); a la derecha el resultado de calcular el IoU

Para cuantificar qué tan parecida es la predicción al valor ideal de referencia, se usa la Intersección sobre Unión (IoU).

  • Primero, se calcula el área de la intersección entre las dos cajas (la región donde ambas se superponen).
  • Luego, se calcula el área de la unión de ambos objetos.
  • Finalmente, se divide el área de la intersección entre el área de la unión.

El ejemplo de este cálculo lo vemos en la parte derecha de la figura de arriba.

Así, si la predicción es pésima y los bounding boxes no se tocan, la intersección es 0 y, por tanto, el IoU será exactamente 0 (el peor caso):

Cuando los "bounding boxes" no se tocan, el IoU resultante será exactamente igual a cero. Esto quiere decir que la predicción hecha por el modelo es pésima
Cuando los «bounding boxes» no se tocan, el IoU resultante será exactamente igual a cero. Esto quiere decir que la predicción hecha por el modelo es pésima

Si la predicción es perfecta las dos cajas estarán superpuestas y serán exactamente iguales. En este caso, el área de intersección es igual a la de unión, dando como resultado un IoU de 1:

Cuando los "bounding boxes" coinciden a la perfección el IoU será exactamente igual a 1. Esto quiere decir que la predicción hecha por el modelo es perfecta
Cuando los «bounding boxes» coinciden a la perfección el IoU será exactamente igual a 1. Esto quiere decir que la predicción hecha por el modelo es perfecta

En la práctica, entre más cercano a 1 sea el IoU mejor será el bounding box predicho por el modelo.

Algoritmo de Supresión de No-Máximos (Non-Max Suppression)

En la práctica, un modelo suele detectar múltiples bounding boxes para un único objeto.

Por ejemplo, en la figura de abajo (a la derecha) tenemos dos sillas a detectar pero el modelo detecta dos bounding boxes para la primera y tres para la segunda:

En la práctica YOLO puede detectar un número de "bounding boxes" mayor al número de objetos realmente presentes en la imagen
En la práctica YOLO puede detectar un número de «bounding boxes» mayor al número de objetos realmente presentes en la imagen

Para limpiar este exceso de cajas redundantes y dejar solo un bounding box definitivo por cada objeto, se utiliza el algoritmo de Supresión de No Máximos (NMS).

El algoritmo funciona evaluando el vector de predicciones de cada caja, específicamente el valor de probabilidad $P_r$ mencionado anteriormente, y comparando el IoU entre las cajas. Veamos el paso a paso suponiendo que tenemos varias cajas para el mismo tipo de objeto.

Filtrado inicial por umbral de probabilidad

Recordemos que cada bounding box tiene asociada una probabilidad $P_r$. Por ejemplo, una caja en la parte inferior derecha podría tener $0.27$ y otra en la parte superior derecha $0.92$:

Ejemplo de múltiples "bounding boxes" detectados por YOLO y sus correspondientes probabilidades
Ejemplo de múltiples «bounding boxes» detectados por YOLO y sus correspondientes probabilidades

Así que en este primer paso se establece un umbral (generalmente de $0.6$) y todos los objetos cuyo bounding box tenga un $P_r < 0.6$ se eliminan. Esto quiere decir que, si analizamos la figura anterior, el bounding box con probabilidad de 0.27 sería eliminado:

Resultado de eliminar el "bounding box" con probabilidad de 0.27 (menor que el umbral establecido de 0.6)
Resultado de eliminar el «bounding box» con probabilidad de 0.27 (menor que el umbral establecido de 0.6)

Selección del máximo

En este segundo paso, se analizan los bounding boxes restantes y se toma el que tenga la probabilidad más alta (en nuestro ejemplo, el de $0.92$, marcado en color verde en la figura de abajo). Este se establece como una predicción definitiva y no se descartará en pasos posteriores:

El "bounding box" con la probabilidad más alta (en verde) es etiquetado como una predicción definitiva
El «bounding box» con la probabilidad más alta (en verde) es etiquetado como una predicción definitiva

Cálculo de similitud

A continuación se calcula la IoU entre el bounding box recién seleccionado y el resto de cajas.

Supongamos que evaluamos tres cajas restantes: una arroja un IoU de $0.8$ (ya que coincide casi perfectamente con la verde), otra de $0.2$ (corresponde a un objeto distinto) y otra de $0$:

El resultado de calcular el IoU entre el "bounding box" detectado como verdadero (en verde) y las cajas restantes
El resultado de calcular el IoU entre el «bounding box» detectado como verdadero (en verde) y las cajas restantes

Descarte por solapamiento

En este cuarto paso se descartan los bounding boxes cuyo IoU supere un umbral (por ejemplo, $0.5$), pues serán aquellas cajas más similares a la caja de referencia.

En el paso anterior, la caja que arrojó un IoU de $0.8$ supera el umbral, indicando que es altamente probable que corresponda al mismo objeto que la caja verde. Así que en este paso se elimina precisamente esta caja:

Resultado de descargar el "bounding box" que tenía un alto grado de similitud (IoU = 0.8) con el "bounding box" detectado como verdadero (en verde)
Resultado de descargar el «bounding box» que tenía un alto grado de similitud (IoU = 0.8) con el «bounding box» detectado como verdadero (en verde)

Así que en este punto tenemos tres «bounding boxes»: uno que será definitivo (en verde en la figura de arriba) y dos que aún nos resta por analizar (en gris).

Iteración

Y ahora sólo nos resta repetir los pasos anteriores con los bounding boxes que aún no han sido analizados.

Hasta este punto tenemos dos de estas cajas: una con $P_r$ de $0.85$ y $0.78$ (las de color gris en la figura de arriba).

Así que seleccionamos la de mayor probabilidad (es de cir la de $0.85$) y la marcamos como definitiva (en verde a la izquierda en la figura de abajo):

Resultado de marcar como definitivo el "bounding box" asociado a la silla del lado izquierdo
Resultado de marcar como definitivo el «bounding box» asociado a la silla del lado izquierdo

Y ahora calculamos el IoU con el «bounding box» de $0.78$, lo cual nos arroja un valor de 0.9. Este valor alto quiere decir que esta última caja es muy similar a la que acabamos de marcar como definitiva, así que procedemos a eliminarla:

Resultado final de aplicar el algoritmo de supresión de no máximos en YOLO
Resultado final de aplicar el algoritmo de supresión de no máximos en YOLO

¡Así que en este punto tenemos los «bounding boxes» totalmente depurados!: las dos cajas que aparecen en la figura de arriba serían las obtenidas tras el proceso de detección con YOLO.

Entonces, como acabamos de ver en este ejemplo, el algoritmo de supresión de no-máximos se detiene cuando no hay más cajas por eliminar o preservar.

Además, cuando tenemos múltiples objetos de múltiples categorías (por ejemplo, sillas y sofás), la limpieza mediante Non-Max Suppression se ejecuta de manera independiente por cada tipo de objeto.

Así por ejemplo, en la imagen de abajo se han detectado tres posibles cajas para el objeto «silla» y del lado derecho vemos el resultado de su depuración con non-max suppression:

Resultado de depurar las detecciones iniciales usando "non-max suppression" para el objeto tipo "silla"
Resultado de depurar las detecciones iniciales usando «non-max suppression» para el objeto tipo «silla»

Y este sería el resultado si aplicamos la depuración a los «bounding boxes» asociados al objeto tipo «sofá»:

Resultado de depurar las detecciones iniciales usando "non-max suppression" para el objeto tipo "sofa"
Resultado de depurar las detecciones iniciales usando «non-max suppression» para el objeto tipo «sofa»

Así que, en este caso, el resultado final de la detección sería un «bounding box» para «silla» y uno para «sofá»:

Resultado de la detección final hecha por YOLO para dos objetos y usando el algoritmo de supresión de no-máximos
Resultado de la detección final hecha por YOLO para dos objetos y usando el algoritmo de supresión de no-máximos

Superposición de objetos

Ocasionalmente, los objetos a detectar pueden ocupar la misma región espacial de la imagen.

Por ejemplo, una mesa y una silla que se superponen (como se observa en la figura de abajo). Dado que un vector simple de 7 elementos solo puede codificar un único objeto (si es silla $C_1=1, C_2=0$, pero si es mesa $C_1=0, C_2=1$ y no pueden coexistir ambas clases simultáneamente en los mismos bits de un solo vector básico), se debe buscar una alternativa:

Cuando tenemos objetos superpuestos ("mesa" y "silla" en la imagen) se debe cambiar la codificación del vector de detección en YOLO
Cuando tenemos objetos superpuestos («mesa» y «silla» en la imagen) se debe cambiar la codificación del vector de predicciones en YOLO

Para solucionar esto, concatenamos los vectores. Es decir que ahora el vector de predicciones pasa a ser una combinación. La primera mitad del vector codifica el primer objeto y la segunda mitad el segundo.

Por ejemplo, si queremos codificar una mesa que se superpone a una silla, entonces:

  • La mitad superior del vector corresponderá al primer objeto (por ejemplo «mesa»). Así que tendrá asociados estos valores: probabilidad 1, coordenadas del centro 0.4 y 0.4, ancho y alto 0.6 y 0.8 y categoría 1 y 0 (indicando mesa).
  • Mientras que la mitad inferior del vector corresponderá al segundo objeto («silla») y tendrá los siguientes valores: probabilidad 1, coordenadas del centro de la silla 0.3, ancho y alto de 0.6 y 0.5 y categoría 0 y 1 (indicando silla).
Para detectar múltiples objetos con YOLO, debemos concatenar sus correspondientes vectores de predicción
Para detectar múltiples objetos con YOLO, debemos concatenar sus correspondientes vectores de predicción

Y si, por ejemplo, en la imagen tenemos sólo un objeto codificamos solo la mitad correspondiente del vector de predicción. Por ejemplo, si es una «silla» codificamos sólo la mitad inferior empezando con un 1 de probabilidad y un (0,1) en las clases, mientras que la mitad superior (correspondiente a «mesa») tendría un $0$ en la probabilidad e ignoramos el resto de sus valores:

Si queremos detectar múltiples objetos pero sólo uno está presente en la imagen, entonces únicamente se codifica la porción del vector de predicciones correspondiente
Si queremos detectar múltiples objetos pero sólo uno está presente en la imagen, entonces únicamente se codifica la porción del vector de predicciones correspondiente

Ahora sí: !el algoritmo YOLO (You Only Look Once)!

Antes de YOLO, la detección de objetos se basaba en la técnica de ventanas deslizantes. En esta técnica se tomaban bloques de diferentes tamaños y proporciones y se hacía un barrido completo por toda la imagen, múltiples veces, para intentar detectar objetos de diferentes tamaños. Esto requería enormes tiempos de cómputo:

Principio de detección de objetos con ventanas deslizantes (antes de YOLO)

YOLO cambió este paradigma: su nombre proviene de You Only Look Once («solo lo miras una vez»). Esto quiere decir que analiza la imagen por bloques pero en una única pasada (de allí el término «only look once», o sólo se mira una vez) logrando un proceso mucho más rápido y con menos cálculos. Y este sencillo cambio introdujo una revolución en la Visión por Computador y en particular en la detección de objetos.

Así que entendamos cómo se realiza el entrenamiento de un modelo YOLO.

La grilla y el set de entrenamiento

Para entrenar y ejecutar YOLO, se divide la imagen en una grilla (una cuadrícula de sub-imágenes):

El primer paso para entrenar YOLO es subdividir la imagen usando una grilla
El primer paso para entrenar YOLO es subdividir la imagen usando una grilla

Por ejemplo, supongamos que queremos detectar tres tipos de objeto: «silla», «mesa» y «sofá» y supongamos además que como máximo tendremos dos objetos superpuestos por cada cuadrante (o elemento de la grilla).

El entrenamiento de YOLO requiere recolectar y etiquetar manualmente cientos de miles de imágenes marcando el bounding box ideal. Y ese etiquetado implica que el vector de predicciones por cada celda en la grilla tendrá una longitud de $2 \cdot (5 + n)$, donde:

  • $2$ se refiere a que asumiremos que como máximo hay dos objetos superpuestos a detectar
  • $5$ corresponde al vector ($P_r, B_x, B_y, B_w, B_h$) (probabilidad, coordenadas x e y del centro y ancho y alto del bounding box)
  • Y $n$ es el número de diferentes objetos a detectar ($N=3$ en el ejemplo que estamos analizando)
Estructura del vector de predicción por cada celda en YOLO, asumiendo tres tipos de objeto a detectar y máximo dos objetos superpuestos
Estructura del vector de predicción por cada celda en YOLO, asumiendo tres tipos de objeto a detectar y máximo dos objetos superpuestos

A continuación entran en juego precisamente las celdas de la grilla definida anteriormente. Y acá hay una regla de oro: una celda de la grilla solo es responsable de codificar y detectar un bounding box sí y solo sí dicha celda contiene el punto central exacto de dicho bounding box.

Entendamos esta regla con un ejemplo. Supongamos que tenemos la siguiente imagen etiquetada, la cual contiene dos objetos a detectar («silla» y «mesa») los cuales a su vez están superpuestos:

Imagen etiquetada con dos objetos a detectar ("mesa" y "silla") los cuales a su vez están superpuestos
Imagen etiquetada con dos objetos a detectar («mesa» y «silla») los cuales a su vez están superpuestos

En la figura anterior, los círculos representan la ubicación del centro de cada bounding box.

Y supongamos que para este ejemplo usaremos una grilla de 4×4 (4 filas y 4 columnas):

Bounding boxes de los objetos a detectar (en azul y en rojo) y la correspondiente grilla de 4x4
Bounding boxes de los objetos a detectar (en azul y en rojo) y la correspondiente grilla de 4×4

Veamos por ejemplo cómo se codificaría el vector de predicciones para la celda de la esquina superior izquierda (resaltada en color gris en la figura de abajo, a la izquierda):

Una celda de la grilla en YOLO (en gris a la izquierda) y su correspondiente vector de predicción (a la derecha)
Una celda de la grilla en YOLO (en gris a la izquierda) y su correspondiente vector de predicción (a la derecha)

En este caso, a pesar de que la celda contiene fragmentos visuales de la mesa, no contiene el centro geométrico de su bounding box. Por este motivo, esta celda se codifica con ceros en sus campos de probabilidad (lo cual se aprecia en detalle del lado derecho en la figura de arriba).

Veamos ahora un segundo ejemplo: en la figura de abajo la celda de interés (en gris) contiene únicamente el centro geométrico del bounding box de la mesa:

Una celda de la grilla en YOLO (en gris) que contiene únicamente el centro del "bounding box" de la mesa
Una celda de la grilla en YOLO (en gris) que contiene únicamente el centro del «bounding box» de la mesa

En este caso sólo se codifica la porción superior del vector de predicción, pues solo tenemos el centro del bounding box correspondiente a un objeto (el objeto «mesa»). Así que:

  • Asignamos un valor de 1 al primer elemento (correspondiente a la probabilidad $P_r$)
  • Luego codificamos las coordenadas $B_x$ y $B_y$ (elementos 2 y 3) correspondientes al centro del bounding box pero normalizadas, es decir calculadas con respecto al tamaño de la celda. En este caso estos valores son de aproximadamente 0.9 y 0.9
  • Y al codificar el alto y el ancho del bounding box ($B_w$ y $B_h$, elementos 4 y 5) los calculamos con respecto a la imagen completa, pues dicho bounding box se extiende más allá de la celda que estamos analizando. Y como la caja es más grande que la celda, sus valores pueden ser mayores a 1 (por ejemplo, un ancho de 2.5 veces el ancho de la celda y un alto de 2.4)
  • Finalmente, la clase (elementos 6, 7 y 8) se codifica como 0, 1, 0 (que corresponde a la categoría «mesa»)

Y la segunda mitad, que corresponde a un segundo objeto, se codifica con un 0 en el elemento $P_r$, pues recordemos que la celda sólo contiene el centro del objeto «mesa».

Así que el vector resultante se muestra a continuación:

Una celda de la grilla en YOLO (en gris, a la izquierda) que contiene únicamente el centro del "bounding box" de la mesa, así como su correspondiente vector de predicción (a la derecha)
Una celda de la grilla en YOLO (en gris, a la izquierda) que contiene únicamente el centro del «bounding box» de la mesa, así como su correspondiente vector de predicción (a la derecha)

Siguiendo la misma lógica anterior, si ahora analizamos la celda que contiene el centro del bounding box correspondiente a la silla (figura de abajo, a la izquierda), veremos que la mitad de arriba del vector se codifica con los elementos correspondientes al bounding box del objeto «silla», mientras que la mitad de abajo se codifica con un valor 0 en la posición $P_r$ (pues no tenemos más objetos en dicha celda):

Una celda de la grilla en YOLO (en gris, a la izquierda) que contiene únicamente el centro del "bounding box" de la silla, así como su correspondiente vector de predicción (a la derecha)
Una celda de la grilla en YOLO (en gris, a la izquierda) que contiene únicamente el centro del «bounding box» de la silla, así como su correspondiente vector de predicción (a la derecha)

Pero tengamos en cuenta que esta codificación es válida sólo si la grilla es de 4×4.

Si por ejemplo ahora la grilla es de 3×3, en la figura de abajo (a la izquierda) podemos ver que los centros de ambos bounding boxes se encuentran en la misma celda (resaltada en color gris):

Codificación de una celda en YOLO cuando la grilla es de 3x3 y en una misma celda coinciden los centros de dos "bounding boxes"
Codificación de una celda en YOLO cuando la grilla es de 3×3 y en una misma celda coinciden los centros de dos «bounding boxes»

Así que en este caso codificamos ambas mitades del vector de esta forma: la mitad superior contendrá la información asociada al bounding box del objeto «mesa», mientras que la mitad inferior tendrá los datos del bounding box asociado a «silla» (parte derecha de la figura anterior).

El entrenamiento de YOLO

Al final, este etiquetado manual que acabamos de ver genera un arreglo numérico de múltiples dimensiones de tamaño $S \times S \times (2 \times (5+n))$ donde:

  • El tamaño de la grilla es $S \times S$
  • El $2$ se refiere al número de objetos que se pueden superponer
  • El $5$ corresponde al vector de codificación del bounding box de cada objeto (que contiene exactamente 5 elementos: $P_r$, $B_x$, $B_y$, $B_w$ y $B_h$)
  • Y $n$ es el número de categorías o tipos de objeto que queremos detectar (por ejemplo, si queremos detectar «silla» y «mesa», entonces $n=2$)

Entonces, cada dato de entrenamiento contendrá un par imagen – arreglo numérico. Y el objetivo del entrenamiento es que la Red Convolucional de YOLO tome como entradas las imágenes y aprenda a predecir el arreglo numérico correspondiente, con lo cual en últimas habrá aprendido a predecir precisamente los bounding boxes de los objetos a detectar.

Generación de predicciones

Con el modelo entrenado, ya podemos generar predicciones. Es decir, podemos presentar al modelo una imagen de entrada y este debería entregarnos a la salida el arreglo con la información de los objetos detectados en la imagen.

Este es el flujo de inferencia (o predicción) en detalle:

  1. Tomamos la imagen que queremos procesar y establecemos el tamaño de grilla a usar
  2. Presentamos la imagen a la Red Convolucional (es decir al modelo YOLO entrenado).
  3. La red genera el volumen de predicciones en una sola pasada. Y recordemos que estas predicciones contienen toda la información asociada a los objetos detectados (categorías y ubicación dentro de la imagen)
  4. Generalmente, este proceso crudo arroja múltiples bounding boxes redundantes para un mismo objeto, así que se aplica el algoritmo de Non-Max Suppression visto previamente para limpiar las redundancias.
  5. Y con esto, a la salida, obtenemos el resultado esperado: la imagen de entrada con un único y preciso bounding box por cada objeto de interés detectado.
El flujo de predicción (o inferencia) en YOLO que permite detectar objetos en una imagen de entrada
El flujo de predicción (o inferencia) en YOLO que permite detectar objetos en una imagen de entrada

Conclusión

Y este es el algoritmo YOLO, concebido en 2016 y que ha evolucionado en múltiples versiones modernas.

Se trata de un enfoque que representa un antes y un después en la Visión por Computador, pues, como acabamos de ver, permite analizar una imagen y realizar la detección de objetos en una sola pasada.

Con el tiempo, este modelo ha venido evolucionando hasta versiones como las implementadas por la empresa Ultralytics, que ha logrado progresivamente mejorar tanto la precisión del modelo al momento de detectar objetos así como los tiempos de inferencia.

Es así como, en la actualidad, los modelos YOLO son uno de los estándares de la industria al momento de implementar aplicaciones de detección de objetos en diferentes entornos y no sólo en imágenes estáticas sino también en secuencias de video.

De hecho, si te interesa te invito a darle una mirada al curso Detección de Objetos con Deep Learning, donde vemos cómo funcionan los modelos YOLO modernos y cómo realizar la afinación de estos modelos YOLO para diferentes retos de detección de objetos en imágenes.

© Codificando Bits, LLC | Blog | Contacto | Servicios | Acerca de | Políticas

¿Has olvidado la contraseña?
¿Has perdido tu contraseña? Por favor, introduce tu nombre de usuario o dirección de correo electrónico. Recibirás por correo electrónico un enlace para crear una nueva contraseña.
body::-webkit-scrollbar { width: 7px; } body::-webkit-scrollbar-track { border-radius: 10px; background: #f0f0f0; } body::-webkit-scrollbar-thumb { border-radius: 50px; background: #dfdbdb }