7.16. Podsumowanie¶
Ten rozdział omówił te części ml, po które sięga aplikacja OpenMV, gdy etap wnioskowania jest częścią potoku przetwarzania:
Pojęcia – czym jest sieć neuronowa w kategoriach arytmetycznych (stos trenowalnych operatorów odwzorowujących tensor na tensor), co zmieniło uczenie maszynowe w porównaniu z klasycznym przetwarzaniem obrazu (zniknął napisany przez człowieka algorytm podsumowujący, zastąpiony wagami nauczonymi z oznaczonych etykietami danych) oraz demo hello, które uruchomiło detektor twarzy w kilku linijkach kodu Python.
Moduł ml – obiekt
ml.Modeli jego właściwości służące do inspekcji tensorów wejściowych i wyjściowych, ścieżki plików modeli, które przyjmuje, oraz miejsce, w którym te pliki się znajdują: partycja ROMFS tylko do odczytu, umożliwiająca wykonywanie bezpośrednio z pamięci flash, albo dowolny inny system plików MicroPython, gdy model można skopiować do pamięci RAM podczas ładowania.Potok wnioskowania – trzy etapy, które
predict()uruchamia kolejno (wstępne przetwarzanie, wysłanie do silnika, przetwarzanie końcowe), uchwytNormalizationna pierwszym etapie, uchwyt przetwarzania końcowego na trzecim etapie oraz arytmetyka kwantyzacji, która wiąże całkowitoliczbowe tensory uruchamiane przez kamerę z liczbami rzeczywistymi, na których sieć była trenowana.Silniki wnioskowania – TFLM (interpreter operatorów uruchamiany przez większość kamer), CMSIS-NN (biblioteka jąder SIMD leżąca pod nim na Cortex-M) oraz NPU (Arm Ethos-U55 na AE3 sparowany z offline’owym kompilatorem Vela, ST Neural-ART na N6 sparowany ze STAI i STEdgeAI). Silnik jest ustalony przez kamerę; skrypt go nie wybiera.
Dekodowanie wyjścia – procesory końcowe, które zamieniają surowe tensory wyjściowe w ramki, punkty kluczowe lub listy klas, klasa
NMS, która scala nakładające się kandydatury, przewodnik po YOLOv8 pokazujący, jak utrzymać szybkie dekodowanie dzięki progowaniu przed dekwantyzacją, oraz protokół pisania własnego dekodera, gdy katalog nie obejmuje danego modelu.
7.16.1. Co jest teraz w zasięgu¶
Trzy rzeczy, do których przygotowuje ten rozdział:
Wczytanie wytrenowanego modelu i jego uruchomienie. Wszystko w
/rom/działa bez dalszych przygotowań; wszystko dostarczone zewnętrznie jako zgodny plik.tflitedziała po tym, jak offline’owe narzędzie dla docelowej kamery (Vela dla AE3, STEdgeAI dla N6) wytworzy właściwy układ.Dekodowanie dowolnego tensora wyjściowego. Gdy architektura znajduje się w katalogu, dobór właściwego procesora końcowego jest mechaniczny:
YoloV8dla modelu YOLOv8,BlazeFacedla BlazeFace i tak dalej. Gdy jej tam nie ma, protokół writing-your-own opisuje kontrakt, a przewodnik po YOLOv8 jest najczystszym wzorcem do skopiowania.Wnioskowanie o wydajności. Model, który działa z prędkością 30 FPS na NPU, może działać z prędkością 3 FPS na Cortex-M7; stosunek zależy od tego, jak dużą część sieci kamera potrafi zdjąć z CPU. Kwantyzacja, umieszczenie w ROMFS, kompilacja pod NPU oraz pokrycie operatorów przez docelowy silnik to cztery dźwignie, a rozdział omówił każdą z nich.
7.16.2. ML łączy się z resztą kamery¶
Wnioskowanie rzadko działa w izolacji. Moduł image przechwytuje i wstępnie przetwarza ramkę, moduł ml uruchamia sieć, a ulab.numpy wykonuje wszelkie obliczenia numeryczne, dla których żadna ze stron nie ma wbudowanej funkcji. Typowy skrypt wykrywania łączy wszystkie trzy: przechwytywanie za pomocą csi, opcjonalne dostosowanie ramki za pomocą image, uruchomienie predict(), końcowe przetworzenie wyniku właściwym modułem z ml.postprocessing oraz sięgnięcie po ulab.numpy dla dowolnych niestandardowych obliczeń, które aplikacja chce wykonać na ramkach zwróconych przez procesor końcowy. Te trzy moduły dzielą ten sam model pamięci; granice między nimi są wszędzie, gdzie to możliwe, bezkopiowe (zero-copy).