7.6. Anatomia predict¶
Model.predict(inputs, *, callback=None) to miejsce, w którym wczytany obiekt modelu faktycznie wykonuje pracę. Pomiędzy wejściem danych a wyjściem wyniku wykonują się po kolei trzy etapy: pre-przetwarzanie, dyspozycja silnika, post-przetwarzanie. Dwa z trzech przyjmują parametry kontrolowane bezpośrednio przez skrypt; o silniku w środku decyduje kamera.
Trzy etapy predict(). Pre-przetwarzanie i post-przetwarzanie przyjmują parametry kontrolowane przez skrypt; o silniku w środku decyduje kamera.¶
7.6.1. Pre-przetwarzanie¶
Etap pre-przetwarzania zamienia każde wejście w gęsty tensor, którego oczekuje sieć. Najczęstszym wejściem jest image.Image, przechwycony w RGB565. Etap kadruje go i skaluje do input_shape sieci, konwertuje z RGB565 do formatu kanałów, na którym trenowano sieć (RGB888 dla większości sieci wizyjnych), stosuje skalę i przesunięcie na każdy kanał oraz – gdy sieć oczekuje wejścia całkowitoliczbowego – kwantyzuje do input_dtype modelu w tym samym przebiegu. Sieci trenowane dla wejścia zmiennoprzecinkowego pomijają krok kwantyzacji i otrzymują bezpośrednio wynik skalowania i przesunięcia.
Domyślny ml.preprocessing.Normalization odczytuje dtype wejścia modelu i automatycznie uruchamia właściwą transformację. Ręcznie dostrojona Normalization nadpisuje wartości skali, średniej i odchylenia standardowego dla modeli trenowanych na własnych statystykach kanałów (powszechnym przypadkiem są średnie i odchylenia standardowe wywiedzione z ImageNet). Zwykły obiekt wywoływalny nadpisuje cały etap – przydatne, gdy wejście w ogóle nie jest obrazem lub gdy aplikacja sama wytworzyła już gęsty tensor.
7.6.2. Dyspozycja silnika¶
Etap silnika uruchamia sieć. To, do którego silnika kieruje, jest ustalone przez kamerę: H7 i RT1062 uruchamiają TFLM (interpreter TensorFlow Lite for Microcontrollers, kierujący do zoptymalizowanych pod ARM jąder CMSIS-NN tam, gdzie istnieją); AE3 uruchamia ten sam interpreter TFLM z awaryjnym Cortex-M55 oraz NPU Ethos-U obsługującym każdy operator, który offline’owy kompilator Vela oznaczył dla akceleratora; N6 uruchamia STAI, środowisko uruchomieniowe ST dla dedykowanego NPU układu N6.
Skrypt nie wybiera silnika. Silnik dostarczany z kamerą uruchamia każdy model, który kamera wczytuje.
7.6.3. Post-przetwarzanie¶
Etap post-przetwarzania zamienia surowe tensory wyjściowe sieci z powrotem w użyteczny wynik. Domyślnym zachowaniem jest dekwantyzacja każdego tensora wyjściowego do liczby zmiennoprzecinkowej (lub przepuszczenie go bez zmian dla sieci z wyjściami zmiennoprzecinkowymi) i zwrócenie ich jako listy obiektów ndarray. Większość aplikacji rejestruje post-procesor – obiekt wywoływalny znający układ wyjść sieci – aby zdekodować tensory do postaci wyniku, na której aplikacja działa: listy ramek ograniczających, listy punktów kluczowych, listy klas.
Skrypt kontroluje ten etap na dwa sposoby. Słowo kluczowe postprocess= w konstruktorze rejestruje post-procesor uruchamiany przy każdym wywołaniu. Słowo kluczowe callback= w predict() nadpisuje zarejestrowany post-procesor tylko dla jednego wywołania – przydatne do przełączania się między kilkoma dekoderami bez ponownego wczytywania modelu. Każda z form otrzymuje (model, inputs, outputs) i zwraca to, czego oczekuje aplikacja.
7.6.4. Co kontroluje skrypt¶
Pre-przetwarzanie i post-przetwarzanie to dwa uchwyty skryptu. Domyślny pre-procesor obsługuje większość modeli wizyjnych; właściwy post-procesor dla danej rodziny sieci wybiera się z katalogu pod ml.postprocessing. O silniku w środku decyduje proces budowania i działa on tak samo, niezależnie od tego, o co prosi skrypt.