7.6. Anatomia metodei predict

Model.predict(inputs, *, callback=None) este locul unde obiectul model încărcat lucrează efectiv. Între intrările care intră și rezultatul care iese, trei etape se execută în secvență: pre-procesare, dispecerizare către motor, post-procesare. Două dintre cele trei primesc parametri pe care scriptul îi controlează direct; motorul din mijloc este decis de cameră.

Un flux orizontal de cinci casete conectate, de la stânga la dreapta. Cea din stânga este "Image input"; o săgeată duce la "Pre-process" subtitrat "Normalization"; o săgeată duce la "Engine" subtitrat "TFLM / STAI"; o săgeată duce la "Post-process" subtitrat "postprocess="; iar o săgeată finală duce la "Result". Cele trei etape din mijloc poartă o etichetă dedesubt -- "user-controllable" sub Pre-process, "automatic" sub Engine și "user-controllable" sub Post-process.

Cele trei etape ale metodei predict(). Pre-procesarea și post-procesarea primesc parametri pe care scriptul îi controlează; motorul din mijloc este fixat de cameră.

7.6.1. Pre-procesare

Etapa de pre-procesare transformă fiecare intrare în tensorul dens pe care îl așteaptă rețeaua. Cea mai frecventă intrare este un obiect image.Image, capturat în RGB565. Etapa îl decupează și îl redimensionează la input_shape al rețelei, îl convertește din RGB565 în formatul de canal pe care a fost antrenată rețeaua (RGB888 pentru majoritatea rețelelor de viziune), aplică scalarea și decalajul per canal și – atunci când rețeaua așteaptă intrare întreagă – cuantizează la input_dtype al modelului în aceeași trecere. Rețelele antrenate pentru intrare float omit pasul de cuantizare și primesc direct rezultatul scalării și decalajului.

Clasa implicită ml.preprocessing.Normalization citește dtype-ul de intrare al modelului și execută automat transformarea corectă. O instanță Normalization reglată manual suprascrie valorile de scalare, medie și abatere standard pentru modelele antrenate pe statistici de canal personalizate (mediile și abaterile standard derivate din ImageNet sunt un caz frecvent). Un obiect apelabil simplu suprascrie complet etapa – util atunci când intrarea nu este deloc o imagine sau când aplicația a produs deja ea însăși tensorul dens.

7.6.2. Dispecerizare către motor

Etapa motorului execută rețeaua. Către ce motor dispecerizează este fixat de cameră: H7 și RT1062 rulează TFLM (interpretorul TensorFlow Lite for Microcontrollers, care dispecerizează nuclee CMSIS-NN optimizate pentru ARM acolo unde acestea există); AE3 rulează același interpretor TFLM cu rezerva sa Cortex-M55 și cu NPU-ul Ethos-U care gestionează orice operator pe care compilatorul offline Vela l-a marcat pentru accelerator; N6 rulează STAI, runtime-ul de la ST pentru NPU-ul dedicat al N6.

Scriptul nu alege motorul. Motorul livrat împreună cu camera execută fiecare model pe care îl încarcă camera.

7.6.3. Post-procesare

Etapa de post-procesare transformă tensorii de ieșire bruți ai rețelei înapoi într-un rezultat utilizabil. Comportamentul implicit este de a dequantiza fiecare tensor de ieșire în virgulă mobilă (sau de a-l trece neschimbat pentru rețelele cu ieșiri float) și de a-i returna ca o listă de obiecte ndarray. Majoritatea aplicațiilor înregistrează un post-procesor – un obiect apelabil care cunoaște aranjamentul de ieșire al rețelei – pentru a decoda tensorii în forma de rezultat asupra căreia acționează aplicația: o listă de casete de încadrare, o listă de puncte-cheie, o listă de clase.

Scriptul controlează această etapă în două moduri. Cuvântul-cheie postprocess= din constructor înregistrează un post-procesor care se execută la fiecare apel. Cuvântul-cheie callback= din predict() suprascrie post-procesorul înregistrat pentru un singur apel – util pentru comutarea între mai multe decodoare fără reîncărcarea modelului. Oricare formă primește (model, inputs, outputs) și returnează tot ceea ce așteaptă aplicația.

7.6.4. Ce controlează scriptul

Pre-procesarea și post-procesarea sunt cele două pârghii ale scriptului. Pre-procesorul implicit gestionează majoritatea modelelor de viziune; post-procesorul potrivit pentru o anumită familie de rețele este ales din catalogul de sub ml.postprocessing. Motorul din mijloc este decis de build și se execută în același mod indiferent de ceea ce cere scriptul.