7.4. Cargar un modelo

ml.Model lee un archivo de modelo desde la memoria flash, lo analiza, asigna la RAM que la red necesita durante la inferencia y devuelve un objeto que contiene todo lo que el resto del script necesita saber sobre la red cargada.

7.4.1. El constructor

El constructor recibe una ruta y un postprocesador opcional:

model = ml.Model("/rom/blazeface_front_128.tflite",
                 postprocess=BlazeFace())

Los modelos en /rom/ (el sistema de archivos residente en flash) se leen in situ: los pesos de la red permanecen en la memoria flash y el modelo cargado consume únicamente la RAM correspondiente a la arena de tensores. Los modelos en /sdcard/ se copian a la RAM en el momento de la carga, por lo que el coste total es el tamaño del archivo del modelo más la arena de tensores. Cualquiera de las dos rutas funciona; el compromiso está en la RAM.

Si existe un archivo .txt hermano con el mismo nombre base, su contenido se carga automáticamente en labels. La palabra clave postprocess= registra un invocable que predict() ejecuta después de cada inferencia.

7.4.2. Propiedades de solo lectura

Un modelo cargado expone un pequeño conjunto de propiedades de solo lectura que describen la red sin que nadie la ejecute.

Archivo y memoria.

  • len – tamaño del archivo del modelo en disco, en bytes.

  • ram – tamaño de la arena de tensores que la red necesita para sus activaciones intermedias durante la inferencia, en bytes.

Tensores de entrada.

  • input_shape – una lista de tuplas, una por cada tensor de entrada, que indica la forma que la red espera. Las redes de visión tienen una sola entrada con forma (1, H, W, C).

  • input_dtype – lista de códigos de dtype de un solo carácter ('b' int8, 'B' uint8, 'h' int16, 'H' uint16, 'f' float32), uno por cada entrada.

  • input_scale y input_zero_point – los parámetros de cuantización que convierten entre la entrada de valores reales con la que se entrenó la red y la representación entera con la que la cámara opera.

Tensores de salida. Reflejo del conjunto de entrada: output_shape, output_dtype, output_scale, output_zero_point. Las redes de detección producen dos o tres tensores de salida (cuadros, puntuaciones de confianza y, a veces, probabilidades de clase); las redes de clasificación producen uno.

Extras. labels es la lista de nombres de clase cargada desde el archivo .txt hermano, o None. postprocess es el postprocesador registrado, o None.

7.4.3. Inspeccionar BlazeFace

Cargar el modelo BlazeFace incluido e imprimir cada propiedad ofrece los números reales:

import ml
from ml.postprocessing.mediapipe import BlazeFace

model = ml.Model("/rom/blazeface_front_128.tflite",
                 postprocess=BlazeFace())

print("file size:    ", model.len, "bytes")
print("tensor arena: ", model.ram, "bytes")
print("input shape:  ", model.input_shape)
print("input dtype:  ", model.input_dtype)
print("input scale:  ", model.input_scale)
print("input zp:     ", model.input_zero_point)
print("output shape: ", model.output_shape)
print("output dtype: ", model.output_dtype)
print("output scale: ", model.output_scale)
print("output zp:    ", model.output_zero_point)

Los números identifican de forma concreta la interfaz de la red: un único tensor de entrada int8 de (1, 128, 128, 3) y dos salidas int8 – una para los coeficientes de regresión de cuadros y otra para las puntuaciones de confianza por ancla. Los parámetros de cuantización describen cómo esos valores int8 se asignan a los floats reales con los que se entrenó la red; el postprocesador los utiliza para deshacer la cuantización antes de decodificar los cuadros.

Cada propiedad es la única fuente fiable de lo que describe. Los scripts leen input_shape para saber a qué resolución capturar, leen output_scale y output_zero_point para decodificar los tensores manualmente, y leen labels para obtener nombres de clase legibles por humanos – nunca codificados a mano, nunca asumidos.