7.16. Resumen¶
Este capítulo recorrió las partes de ml a las que recurre una aplicación de OpenMV cuando un paso de inferencia forma parte del flujo de procesamiento:
Conceptos – qué es una red neuronal en términos aritméticos (una pila de operadores entrenables que mapea un tensor a un tensor), qué cambió el aprendizaje automático en comparación con el procesamiento clásico de imágenes (desaparece el algoritmo resumen escrito por humanos, reemplazado por pesos aprendidos a partir de datos etiquetados) y la demostración hello que ejecutó un detector de rostros en unas pocas líneas de Python.
El módulo ml – el objeto
ml.Modely sus propiedades para inspeccionar los tensores de entrada y salida, las rutas de archivo de modelo que acepta y dónde residen esos archivos: una partición ROMFS de solo lectura para la ejecución directamente desde la memoria flash, o cualquier otro sistema de archivos de MicroPython cuando el modelo puede copiarse a la RAM en el momento de la carga.El flujo de inferencia – las tres etapas que
predict()ejecuta en secuencia (preprocesamiento, despacho al motor, posprocesamiento), el manejadorNormalizationde la primera etapa, el manejador del posprocesador de la tercera etapa y la aritmética de cuantización que vincula los tensores enteros que ejecuta la cámara con los números de valor real con los que se entrenó la red.Motores de inferencia – TFLM (el intérprete de operadores que ejecutan la mayoría de las cámaras), CMSIS-NN (la biblioteca de kernels SIMD que lo sustenta en Cortex-M) y las NPU (la Ethos-U55 de Arm en la AE3 emparejada con el compilador offline Vela, y la Neural-ART de ST en la N6 emparejada con STAI y STEdgeAI). El motor lo fija la cámara; el script no lo elige.
Descodificación de la salida – los posprocesadores que convierten los tensores de salida sin procesar en cuadros, puntos clave o listas por clase, la clase
NMSque colapsa los candidatos solapados, el recorrido por YOLOv8 que muestra cómo mantener rápida la descodificación aplicando el umbral antes de descuantizar, y el protocolo para escribir un descodificador personalizado cuando el catálogo no cubre un modelo.
7.16.1. Qué está ahora a tu alcance¶
Tres cosas para las que prepara este capítulo:
Cargar un modelo entrenado y ejecutarlo. Cualquier cosa en
/rom/funciona sin preparación adicional; cualquier modelo suministrado externamente como un.tflitecompatible funciona una vez que la herramienta offline de la cámara de destino (Vela para la AE3, STEdgeAI para la N6) ha producido la disposición correcta.Descodificar cualquier tensor de salida. Cuando la arquitectura está en el catálogo, el posprocesador adecuado es mecánico:
YoloV8para un modelo YOLOv8,BlazeFacepara BlazeFace, y así sucesivamente. Cuando no lo está, el protocolo writing-your-own cubre el contrato y el recorrido por YOLOv8 es la referencia más limpia de la que copiar.Razonar sobre el rendimiento. Un modelo que se ejecuta a 30 FPS en una NPU puede ejecutarse a 3 FPS en un Cortex-M7; la proporción depende de cuánto de la red puede descargar la cámara de la CPU. La cuantización, la ubicación en ROMFS, la compilación para la NPU y la cobertura de operadores del motor de destino son las cuatro palancas, y el capítulo abordó cada una de ellas.
7.16.2. El ML se combina con el resto de la cámara¶
Una inferencia rara vez se ejecuta de forma aislada. El módulo image captura y preprocesa el fotograma, el módulo ml ejecuta la red y ulab.numpy realiza cualquier trabajo numérico para el que ninguno de los dos tenga una función integrada. Un script de detección típico combina los tres: captura con csi, ajusta opcionalmente el fotograma con image, ejecuta predict(), posprocesa el resultado con el módulo adecuado de ml.postprocessing y recurre a ulab.numpy para cualquier cálculo personalizado que la aplicación desee aplicar sobre los cuadros que devolvió el posprocesador. Los tres módulos comparten el mismo modelo de memoria; las fronteras entre ellos son de copia cero (zero-copy) siempre que es posible.