7.1. Qué es una red neuronal

Una red neuronal es un algoritmo cuyo comportamiento se aprende a partir de ejemplos en lugar de programarse a mano. La misma arquitectura de red, alimentada con un millón de imágenes de rostros, aprende a detectar rostros. La misma arquitectura, alimentada con un millón de imágenes de manos, aprende a detectar manos. La misma arquitectura, alimentada con un conjunto etiquetado que abarca muchas categorías de objetos, aprende a detectarlos todos a la vez. Solo los pesos cambian entre objetivos, y los pesos los produce un proceso de entrenamiento externo que observa las predicciones de la red frente a ejemplos etiquetados y ajusta los pesos hasta que coincidan.

7.1.1. El mecanismo

Una red neuronal es una pila de capas. Cada capa multiplica la salida de la capa anterior por una matriz de pesos, suma un vector de sesgo y aplica una función no lineal al resultado. La salida de una capa es la entrada de la siguiente. Una imagen capturada entra por la parte superior de la pila, desciende a través de decenas o cientos de capas y emerge por la parte inferior como un tensor cuyas entradas describen lo que había en la imagen.

Lo que hacen los pesos de cada capa depende de aquello con lo que se entrenó la red. Una matriz de pesos de una capa temprana en una red de visión podría activarse ante un borde horizontal corto; una un poco más profunda podría activarse ante una esquina; otra más profunda podría activarse ante la forma circular de un ojo; las capas más profundas podrían activarse ante la disposición de un rostro completo. Nada de esto se escribió a mano. El proceso de entrenamiento iteró sobre millones de ejemplos etiquetados, empujó los pesos cuesta abajo sobre una función de pérdida, y la jerarquía borde-luego-esquina-luego-ojo-luego-rostro surgió de los datos.

Una pila vertical de nueve cajas etiquetadas que representan las capas de una pequeña red de clasificación. La caja superior está etiquetada como "Input image" con una forma de tensor de (192, 192, 3). Una flecha desciende hacia una caja "Conv + ReLU" con forma (96, 96, 32). Otra flecha conduce a una segunda caja "Conv + ReLU" con forma (48, 48, 64). Le sigue una caja "MaxPool" con forma (24, 24, 64). Siguen dos cajas más "Conv + ReLU" con formas (12, 12, 128) y (6, 6, 256). Una caja "Global average pool" tiene forma (256,). Una caja "Fully connected" tiene forma (1000,). La caja inferior está etiquetada como "Class scores" con forma (1000,). El flujo del tensor va de arriba abajo.

Una pequeña red de clasificación como una pila de capas. El tensor de entrada entra por la parte superior con la forma de la imagen capturada y desciende a través de las capas, cada una de las cuales transforma las dimensiones del tensor. El tensor de salida en la parte inferior tiene una entrada por cada clase. Las redes de detección y de puntos clave comparten la misma forma de pila de capas; solo cambia la interpretación del tensor de salida.

La arquitectura de la red – cómo están dispuestas las capas, qué operaciones las conectan – es lo que la red puede hacer. Los pesos son lo que la red ha aprendido. La parte que corresponde a la cámara es cargar el archivo de pesos producido por el entrenamiento y ejecutar la misma aritmética que ejecutó el entrenador, pero sobre el fotograma capturado en lugar del conjunto de entrenamiento.

7.1.2. Qué se introduce, qué sale

Ambos extremos de la red son tensores – matrices multidimensionales de números, el mismo tipo de objeto que acaba de presentar el capítulo sobre numpy. El tensor de entrada para una red de visión es la imagen capturada reorganizada en la disposición que la red espera: normalmente una forma de 4 elementos (B, H, W, C) donde B es la dimensión de lote (siempre 1 en la cámara, ya que se procesa un fotograma a la vez), H y W son la altura y la anchura en píxeles que la red espera, y C es el número de canales (3 para una red RGB, 1 para escala de grises).

El tensor de salida depende de para qué sirve la red:

  • Una red de clasificación produce un tensor unidimensional de puntuaciones de confianza, una por clase. El índice de la puntuación más alta es la clase predicha. El detector de personas derivado de MobileNet que viene en la mayoría de las cámaras tiene esta forma: dos puntuaciones, una para «persona» y otra para «no persona».

  • Una red de detección produce un tensor bidimensional cuyas entradas describen una lista de cuadros delimitadores más probabilidades de clase. YOLOv8 tiene esta forma: un tensor (84, N) donde 4 de las 84 filas son valores de regresión del cuadro y las otras 80 son probabilidades por clase, repetidas a lo largo de N posiciones de ancla.

  • Una red de puntos clave produce un tensor cuyas entradas son posiciones en píxeles de puntos de referencia con nombre. El modelo de puntos de referencia faciales de MediaPipe tiene esta forma: 468 puntos clave por cada rostro detectado.

  • Una red de segmentación produce un tensor bidimensional cuyas entradas son etiquetas de clase por píxel – las mismas dimensiones que la entrada, con un índice de categoría en cada posición.

  • Una red de regresión produce un único número o un vector corto de números – una estimación de profundidad, un ángulo, una temperatura.

Cada forma tiene su propio posprocesador en la cámara que convierte el tensor de salida en bruto de nuevo en la forma de resultado que utiliza el resto de la aplicación – cuadros delimitadores, listas de puntos clave, etiquetas de clase, estimaciones numéricas. El posprocesador es código del lado de la aplicación que conoce la disposición de la salida de la red; la red en sí no es más que la aritmética que produce el tensor.

7.1.3. Por qué esto funciona en una cámara

Dos elementos de aritmética hacen que esto sea práctico para un componente de clase microcontrolador. El primero es la cuantización. El entrenamiento ocurre en aritmética de coma flotante de 32 bits; la inferencia puede ejecutarse en aritmética de enteros de 8 bits casi sin pérdida de precisión para la mayoría de las redes. Los pesos de 8 bits ocupan la cuarta parte del almacenamiento y se ejecutan varias veces más rápido que los flotantes de 32 bits. Todos los modelos que vienen con la cámara ya han sido cuantizados de forma externa.

El segundo es la aceleración por hardware. La misma aritmética que la CPU de un microcontrolador procesa pesadamente una instrucción a la vez, un acelerador de redes neuronales la ejecuta con cientos de operaciones a la vez. Las cámaras más nuevas (la AE3 y la N6) incorporan una unidad de procesamiento neuronal (NPU) dedicada – un acelerador de tensores en el SoC – que convierte un modelo que habría tardado un segundo en ejecutarse en la CPU en uno que se ejecuta en decenas de milisegundos. El capítulo sobre motores de inferencia cubre cómo es la parte que corresponde a la cámara en esto.

7.1.4. Qué cubre el capítulo

El entrenamiento no es tarea de la cámara. Un modelo entrenado llega a la cámara como un archivo .tflite; la cámara lo carga, pasa cada fotograma capturado a través de él y decodifica el tensor resultante en un resultado sobre el que la aplicación puede actuar. Todo lo que sigue trata sobre cada uno de esos pasos:

  • cargar e inspeccionar un modelo;

  • la partición de memoria flash donde residen los archivos de modelo;

  • las cuatro etapas de una llamada de inferencia;

  • los motores que realmente realizan la aritmética;

  • y los posprocesadores que convierten un tensor de salida de nuevo en una lista de cuadros, puntos clave o clases.

Cada uno de los detectores del capítulo sobre imágenes estaba acotado a un objetivo concreto. Los que cubre el resto de este capítulo se entrenan a partir de datos en su lugar, con el mismo motor ejecutando cualquier modelo que cargue el script. El cambio en el flujo de trabajo que vino con ellos – un algoritmo específico para un objetivo sustituido por un archivo de pesos específico para un objetivo – es lo siguiente que conviene resaltar.