7.16. Conclusão¶
Este capítulo percorreu as partes do ml que uma aplicação OpenMV utiliza quando uma etapa de inferência faz parte do pipeline:
Conceitos – o que é uma rede neural em termos aritméticos (uma pilha de operadores treináveis que mapeia um tensor para um tensor), o que o aprendizado de máquina mudou em comparação com o processamento clássico de imagens (o algoritmo de resumo escrito por humanos desapareceu, substituído por pesos aprendidos a partir de dados rotulados) e a demonstração hello que executou um detector de rostos em algumas poucas linhas de Python.
O módulo ml – o objeto
ml.Modele suas propriedades para inspecionar os tensores de entrada e saída, os caminhos de arquivo de modelo que ele aceita e onde esses arquivos residem: uma partição ROMFS somente leitura para execução diretamente a partir do flash, ou qualquer outro sistema de arquivos MicroPython quando o modelo pode ser copiado para a RAM no momento do carregamento.O pipeline de inferência – as três etapas que
predict()executa em sequência (pré-processamento, despacho ao motor, pós-processamento), o controle deNormalizationna primeira etapa, o controle do pós-processador na terceira etapa e a aritmética de quantização que liga os tensores inteiros que a câmera executa de volta aos números de valor real contra os quais a rede foi treinada.Motores de inferência – TFLM (o interpretador de operadores que a maioria das câmeras executa), CMSIS-NN (a biblioteca de kernels SIMD por baixo dele no Cortex-M) e as NPUs (a Ethos-U55 da Arm na AE3, em conjunto com o compilador offline Vela, e a Neural-ART da ST na N6, em conjunto com STAI e STEdgeAI). O motor é fixado pela câmera; o script não o escolhe.
Decodificando a saída – os pós-processadores que transformam tensores de saída brutos em caixas, pontos-chave ou listas por classe, a classe
NMSque colapsa candidatos sobrepostos, o passo a passo da YOLOv8 que mostra como manter a decodificação rápida aplicando o limiar antes de dequantizar, e o protocolo para escrever um decodificador personalizado quando o catálogo não cobre um modelo.
7.16.1. O que agora está ao alcance¶
Três coisas para as quais o capítulo prepara:
Carregar um modelo treinado e executá-lo. Qualquer coisa em
/rom/funciona sem preparação adicional; qualquer coisa fornecida externamente como um.tflitecompatível funciona depois que a ferramenta offline para a câmera de destino (Vela para a AE3, STEdgeAI para a N6) tiver produzido o layout correto.Decodificar qualquer tensor de saída. Quando a arquitetura está no catálogo, o pós-processador correto é mecânico:
YoloV8para um modelo YOLOv8,BlazeFacepara BlazeFace e assim por diante. Quando não está, o protocolo writing-your-own cobre o contrato e o passo a passo da YOLOv8 é a referência mais limpa para copiar.Raciocinar sobre o desempenho. Um modelo que roda a 30 FPS em uma NPU pode rodar a 3 FPS em um Cortex-M7; a razão depende de quanto da rede a câmera consegue tirar da CPU. Quantização, posicionamento em ROMFS, compilação para NPU e a cobertura de operadores do motor de destino são as quatro alavancas, e o capítulo cobriu cada uma delas.
7.16.2. ML se combina com o resto da câmera¶
Uma inferência raramente é executada de forma isolada. O módulo image captura e pré-processa o quadro, o módulo ml executa a rede e ulab.numpy faz qualquer trabalho numérico para o qual nenhum dos dois tenha um recurso embutido. Um script de detecção típico combina os três: captura com csi, ajusta opcionalmente o quadro com image, executa predict(), pós-processa o resultado com o módulo correto dentre os de ml.postprocessing e recorre a ulab.numpy para qualquer cálculo personalizado que a aplicação queira sobre as caixas que o pós-processador retornou. Os três módulos compartilham o mesmo modelo de memória; as fronteiras entre eles são zero-copy sempre que possível.