7.6. Anatomía de predict

Model.predict(inputs, *, callback=None) es donde el objeto del modelo cargado realmente hace su trabajo. Entre las entradas que entran y el resultado que sale, se ejecutan tres etapas en secuencia: preprocesamiento, despacho del motor, postprocesamiento. Dos de las tres toman parámetros que el script controla directamente; el motor del medio lo decide la cámara.

Un flujo horizontal de cinco cuadros conectados de izquierda a derecha. El de más a la izquierda es "Entrada de imagen"; una flecha lleva a "Preprocesamiento" subtitulado "Normalización"; una flecha lleva a "Motor" subtitulado "TFLM / STAI"; una flecha lleva a "Postprocesamiento" subtitulado "postprocess="; y una última flecha lleva a "Resultado". Las tres etapas centrales llevan una etiqueta debajo -- "controlable por el usuario" bajo Preprocesamiento, "automático" bajo Motor, y "controlable por el usuario" bajo Postprocesamiento.

Las tres etapas de predict(). El preprocesamiento y el postprocesamiento toman parámetros que el script controla; el motor del medio lo fija la cámara.

7.6.1. Preprocesamiento

La etapa de preprocesamiento convierte cada entrada en el tensor denso que la red espera. La entrada más común es una image.Image, capturada en RGB565. La etapa la recorta y redimensiona a la input_shape de la red, la convierte de RGB565 al formato de canal con el que se entrenó la red (RGB888 para la mayoría de las redes de visión), aplica escala y desplazamiento por canal y – cuando la red espera entrada entera – cuantiza al input_dtype del modelo en la misma pasada. Las redes entrenadas para entrada float omiten el paso de cuantización y reciben directamente el resultado de escala y desplazamiento.

La ml.preprocessing.Normalization por defecto lee el dtype de entrada del modelo y ejecuta automáticamente la transformación correcta. Una Normalization ajustada a mano reemplaza los valores de escala, media y desviación estándar para modelos entrenados con estadísticas de canal personalizadas (las medias y desviaciones estándar derivadas de ImageNet son un caso común). Un invocable simple reemplaza la etapa por completo – útil cuando la entrada no es una imagen en absoluto o cuando la aplicación ya ha producido el tensor denso por sí misma.

7.6.2. Despacho del motor

La etapa del motor ejecuta la red. El motor al que despacha lo fija la cámara: el H7 y el RT1062 ejecutan TFLM (el intérprete TensorFlow Lite for Microcontrollers, que despacha núcleos CMSIS-NN optimizados para ARM allí donde existen); el AE3 ejecuta el mismo intérprete TFLM con su respaldo Cortex-M55 y la NPU Ethos-U gestionando cualquier operador que el compilador Vela sin conexión haya etiquetado para el acelerador; el N6 ejecuta STAI, el entorno de ejecución de ST para la NPU específica del N6.

El script no elige el motor. El motor que viene con la cámara ejecuta todos los modelos que la cámara carga.

7.6.3. Postprocesamiento

La etapa de postprocesamiento convierte los tensores de salida en bruto de la red de nuevo en un resultado utilizable. El comportamiento por defecto es decuantizar cada tensor de salida a punto flotante (o pasarlo sin cambios para redes con salidas float) y devolverlos como una lista de objetos ndarray. La mayoría de las aplicaciones registran un postprocesador – un invocable que conoce la disposición de salida de la red – para decodificar los tensores en la forma de resultado sobre la que actúa la aplicación: una lista de cuadros delimitadores, una lista de puntos clave, una lista de clases.

El script controla esta etapa de dos maneras. La palabra clave postprocess= en el constructor registra un postprocesador que se ejecuta en cada llamada. La palabra clave callback= en predict() reemplaza el postprocesador registrado para una sola llamada – útil para alternar entre varios decodificadores sin recargar el modelo. Cualquiera de las dos formas recibe (model, inputs, outputs) y devuelve lo que la aplicación espere.

7.6.4. Lo que el script controla

El preprocesamiento y el postprocesamiento son las dos palancas del script. El preprocesador por defecto gestiona la mayoría de los modelos de visión; el postprocesador adecuado para una familia de red determinada se elige del catálogo en ml.postprocessing. El motor del medio lo decide la compilación y se ejecuta de la misma manera independientemente de lo que el script pida.