Este artículo explica la arquitectura de detección de objetos de YOLO, desde el punto de vista de alguien que quiere implementarla desde cero. No describirá las ventajas/desventajas de la red o las razones de cada elección de diseño. En cambio, se enfoca en cómo funciona. Debe tener una comprensión básica de las redes neuronales, especialmente CNNS, antes de leer esto.
Todas las descripciones en esta publicación están relacionadas con el artículo original de YOLO: Solo miras una vez: Detección unificada de objetos en tiempo real de Joseph Redmon, Santosh Divvala, Ross Girshick y Ali Farhadi (2015) . Se han propuesto muchas mejoras desde entonces, que se combinaron en la nueva versión de YOLOv2 sobre la que podría escribir en otro momento. Es más fácil comprender primero esta versión original y luego verificar qué cambios se realizaron y por qué.
YOLO (You Only Look Once), es una red para la detección de objetos. La tarea de detección de objetos consiste en determinar la ubicación en la imagen donde están presentes ciertos objetos, así como clasificar esos objetos. Los métodos anteriores para esto, como R-CNN y sus variaciones, usaban una canalización para realizar esta tarea en varios pasos. Esto puede ser lento de ejecutar y también difícil de optimizar, porque cada componente individual debe entrenarse por separado. YOLO, lo hace todo con una sola red neuronal. Del papel:
Replanteamos la detección de objetos como un problema de regresión simple, directamente desde los píxeles de la imagen hasta las coordenadas del cuadro delimitador y las probabilidades de clase.
Entonces, para simplificar, toma una imagen como entrada, la pasa a través de una red neuronal que se parece a una CNN normal y obtiene un vector de cuadros delimitadores y predicciones de clase en la salida.
Entonces, ¿cómo son estas predicciones?
El primer paso para comprender YOLO es cómo codifica su salida. La imagen de entrada se divide en una cuadrícula de celdas S x S. Para cada objeto que está presente en la imagen, se dice que una celda de la cuadrícula es "responsable" de predecirlo. Esa es la celda donde cae el centro del objeto.
Cada celda de la cuadrícula predice cuadros delimitadores B , así como probabilidades de clase C. La predicción del cuadro delimitador tiene 5 componentes: (x, y, w, h, confianza) . Las coordenadas (x, y) representan el centro del cuadro, en relación con la ubicación de la celda de la cuadrícula (recuerde que, si el centro del cuadro no cae dentro de la celda de la cuadrícula, esta celda no es responsable de ello). Estas coordenadas se normalizan para caer entre 0 y 1. Las dimensiones del cuadro (w, h) también se normalizan a [0, 1], en relación con el tamaño de la imagen. Veamos un ejemplo:
Ejemplo de cómo calcular coordenadas de caja en una imagen de 448x448 con S=3. Observe cómo las coordenadas (x,y) se calculan en relación con la celda de la cuadrícula central
Todavía hay un componente más en la predicción del cuadro delimitador, que es la puntuación de confianza. Del papel:
Formalmente definimos la confianza como Pr(Objeto) * IOU(pred, verdad) . Si no existe ningún objeto en esa celda, la puntuación de confianza debe ser cero. De lo contrario, queremos que la puntuación de confianza sea igual a la intersección sobre la unión (IOU) entre el cuadro predicho y la realidad fundamental.
Tenga en cuenta que la confianza refleja la presencia o ausencia de un objeto de cualquier clase . En caso de que no sepas qué es el pagaré, échale un vistazo aquí .
Ahora que comprendemos los 5 componentes de la predicción del cuadro, recuerde que cada celda de la cuadrícula hace B de esas predicciones, por lo que hay un total de S x S x B * 5 salidas relacionadas con las predicciones del cuadro delimitador.
También es necesario predecir las probabilidades de clase, Pr(Clase(i) | Objeto). Esta probabilidad está condicionada a que la celda de la cuadrícula contenga un objeto (vea esto si no sabe lo que significa la probabilidad condicional). En la práctica, significa que si no hay ningún objeto presente en la celda de la cuadrícula, la función de pérdida no lo penalizará por una predicción de clase incorrecta, como veremos más adelante. La red solo predice un conjunto de probabilidades de clase por celda, independientemente del número de casillas B . Eso hace que las probabilidades de clase S x S x C en total
Al agregar las predicciones de clase al vector de salida, obtenemos un tensor S x S x (B * 5 +C) como salida.
Cada celda de la cuadrícula hace predicciones de cuadro delimitador B y predicciones de clase C (S=3, B=2 y C=3 en este ejemplo)
Una vez que comprenda cómo se codifican las predicciones, el resto es fácil. La estructura de la red se parece a una CNN normal, con capas convolucionales y de agrupación máxima, seguidas de 2 capas completamente conectadas al final:
" ────────┐│ Nombre │ Filtros │ Dimensión de salida │├────────────┼───────────────────────── ─────┼───────────────────┤│ Conv 1 │ 7 x 7 x 64, zancada=2 │ 224 x 224 x 64 │ Máx. │ 1 │ 2 x 2, zancada=2 │ 112 x 112 x 64 ││ Conv 2 │ 3 x 3 x 192 │ 112 x 112 x 192 ││ Max Pool 2 │ 2 x 2, zancada=2 │ 56 x 56 x 192 │ │ Conv 3 │ 1 x 1 x 128 │ 56 x 56 x 128 ││ Conv 4 │ 3 x 3 x 256 │ 56 x 56 x 256 ││ Conv 5 │ 1 x 1 x 256 │ 56 x 56 x 256 ││ Conv 6 │ 1 x 1 x 512 │ 56 x 56 x 512 ││ Max Pool 3 │ 2 x 2, stride=2 │ 28 x 28 x 512 ││ Conv 7 │ 1 x 1 x 256 │ 28 x 28 x 256 ││ Conv. 8 │ 3 x 3 x 512 │ 28 x 28 x 512 ││ Conv. 9 │ 1 x 1 x 256 │ 28 x 28 x 256 ││ Conv. 10 │ 3 x 3 x 512 │ 28 x 28 x 512 │1│ Conv. │ 1 x 1 x 256 │ 28 x 28 x 256 ││ Conv 12 │ 3 x 3 x 512 │ 28 x 28 x 512 ││ Conv 13 │ 1 x 1 x 256 │ 28 x 28 x 256 ││ │ Conv 14 x 3 x 512 │ 28 x 28 x 512 ││ Conv 15 │ 1 x 1 x 512 │ 28 x 28 x 512 ││ Conv 16 │ 3 x 3 x 1024 │ 28 x 28 x 1024 ││ Max Pool 4 x │ 2, zancada=2 │ 14 x 1 4 x 1024 ││ Conv 17 │ 1 x 1 x 512 │ 14 x 14 x 512 ││ Conv 18 │ 3 x 3 x 1024 │ 14 x 14 x 1024 ││ Conv 19 │ 1 x 1 x 514 x │ 14 512 ││ Conv 20 │ 3 x 3 x 1024 │ 14 x 14 x 1024 ││ Conv 21 │ 3 x 3 x 1024 │ 14 x 14 x 1024 ││ Conv 22 │ 3 x 3 x 1024, paso 7 x │ 7 x 1024 ││ Conv 23 │ 3 x 3 x 1024 │ 7 x 7 x 1024 ││ Conv 24 │ 3 x 3 x 1024 │ 7 x 7 x 1024 ││ FC 1 │ - │ 4096 ││ - 2 7 x 7 x 30 (1470) │└────────────┴────────────────────┴───────── ─────────────────┘
Algunos comentarios sobre la arquitectura:
Hay mucho que decir sobre la función de pérdida, así que hagámoslo por partes. Comienza así:
Función de pérdida de YOLO — Parte 1
Esta ecuación calcula la pérdida relacionada con la posición prevista del cuadro delimitador (x,y) . No te preocupes por λ por ahora, solo considéralo una constante dada. La función calcula una suma sobre cada predictor de cuadro delimitador ( j = 0.. B ) de cada celda de cuadrícula ( i = 0 .. S^2 ) . 𝟙 obj se define de la siguiente manera:
Pero, ¿cómo sabemos qué predictor es responsable del objeto? Citando el artículo original:
YOLO predice múltiples cuadros delimitadores por celda de cuadrícula. En el momento del entrenamiento, solo queremos que un predictor de cuadro delimitador sea responsable de cada objeto. Asignamos un predictor para que sea "responsable" de predecir un objeto en función de qué predicción tiene el IOU actual más alto con la verdad básica.
Los otros términos en la ecuación deberían ser fáciles de entender: (x, y) son la posición predicha del cuadro delimitador y (x̂, ŷ) son la posición real de los datos de entrenamiento.
Pasemos a la segunda parte:
Función de pérdida de YOLO — Parte 2
Esta es la pérdida relacionada con el ancho/alto del cuadro previsto. La ecuación es similar a la primera, excepto por la raíz cuadrada. ¿Que pasa con eso? Citando el documento de nuevo:
Nuestra métrica de error debe reflejar que las pequeñas desviaciones en las cajas grandes importan menos que en las cajas pequeñas. Para abordar esto parcialmente, predecimos la raíz cuadrada del ancho y la altura del cuadro delimitador en lugar del ancho y la altura directamente.
Pasando a la tercera parte:
Función de pérdida de YOLO — Parte 3
Aquí calculamos la pérdida asociada con la puntuación de confianza para cada predictor de cuadro delimitador. C es la puntuación de confianza y Ĉ es la intersección sobre la unión del cuadro delimitador predicho con la realidad fundamental. 𝟙 obj es igual a uno cuando hay un objeto en la celda y 0 en caso contrario. 𝟙 noobj es todo lo contrario.
Los parámetros λ que aparecen aquí y también en la primera parte se utilizan para ponderar de manera diferente partes de las funciones de pérdida. Esto es necesario para aumentar la estabilidad del modelo. La penalización más alta es para predicciones de coordenadas ( λ coord = 5) y la más baja para predicciones de confianza cuando no hay ningún objeto presente ( λ noobj = 0,5) .
La última parte de la función de pérdida es la pérdida de clasificación:
Función de pérdida de YOLO — Parte 4
Se parece a un error de suma cuadrática normal para la clasificación, excepto por el término 𝟙 obj . Este término se usa porque así no penalizamos el error de clasificación cuando no hay ningún objeto presente en la celda (de ahí la probabilidad de clase condicional discutida anteriormente).
Los autores describen el entrenamiento de la siguiente manera
Este procedimiento se describe con mayor detalle en el artículo original. Planeo reproducirlo yo mismo, pero aún no he llegado :).
Me tomó algún tiempo obtener todos los detalles sobre este documento. Si está leyendo esto, espero haber facilitado su trabajo al compartir mis comentarios al respecto.
Creo que la mejor prueba para comprobar si realmente has entendido un algoritmo es intentar implementarlo tú mismo desde cero. Hay muchos detalles que no están explícitos en el texto y que no te das cuenta hasta que te ensucias las manos y tratas de construir algo con él.
Gracias por leer y por favor deja tus comentarios a continuación, si tienes alguno.