7.6. Anatomin hos predict

Model.predict(inputs, *, callback=None) är där det laddade modellobjektet faktiskt utför arbete. Mellan att indata går in och att resultatet kommer ut körs tre steg i följd: förbehandling, motoranrop, efterbehandling. Två av de tre tar parametrar som skriptet styr direkt; motorn i mitten bestäms av kameran.

Ett horisontellt flöde av fem sammankopplade rutor från vänster till höger. Längst till vänster är "Bildindata"; en pil leder till "Förbehandling" med underrubriken "Normalisering"; en pil leder till "Motor" med underrubriken "TFLM / STAI"; en pil leder till "Efterbehandling" med underrubriken "postprocess="; och en sista pil leder till "Resultat". De tre mellersta stegen bär en etikett under sig -- "användarstyrbar" under Förbehandling, "automatisk" under Motor, och "användarstyrbar" under Efterbehandling.

De tre stegen i predict(). Förbehandling och efterbehandling tar parametrar som skriptet styr; motorn i mitten är fastlagd av kameran.

7.6.1. Förbehandling

Förbehandlingssteget omvandlar varje indata till den täta tensor som nätverket förväntar sig. Den vanligaste indatan är en image.Image, infångad i RGB565. Steget beskär och ändrar storlek på den till nätverkets input_shape, konverterar från RGB565 till det kanalformat som nätverket tränades på (RGB888 för de flesta visionsnätverk), tillämpar skala och förskjutning per kanal, och – när nätverket förväntar sig heltalsindata – kvantiserar till modellens input_dtype i samma pass. Nätverk som tränats för flyttalsindata hoppar över kvantiseringssteget och tar emot resultatet av skala och förskjutning direkt.

Standardvärdet ml.preprocessing.Normalization läser modellens indata-dtype och kör rätt transformation automatiskt. En handjusterad Normalization åsidosätter värdena för skala, medelvärde och standardavvikelse för modeller som tränats mot anpassad kanalstatistik (de ImageNet-härledda medelvärdena och standardavvikelserna är ett vanligt fall). Ett vanligt anropbart objekt åsidosätter steget helt och hållet – användbart när indatan inte är en bild alls eller när applikationen redan själv har producerat den täta tensorn.

7.6.2. Motoranrop

Motorsteget kör nätverket. Vilken motor det anropar är fastlagt av kameran: H7 och RT1062 kör TFLM (TensorFlow Lite for Microcontrollers-tolken, som anropar ARM-optimerade CMSIS-NN-kärnor där de finns); AE3 kör samma TFLM-tolk med dess Cortex-M55-reserv och Ethos-U-NPU:n som hanterar alla operatorer som den offline-baserade Vela-kompilatorn taggat för acceleratorn; N6 kör STAI, ST:s körningsmiljö för N6:ans ändamålsbyggda NPU.

Skriptet väljer inte motorn. Den motor som levereras med kameran kör varje modell som kameran laddar.

7.6.3. Efterbehandling

Efterbehandlingssteget omvandlar nätverkets råa utdatatensorer tillbaka till ett användbart resultat. Standardbeteendet är att dekvantisera varje utdatatensor till flyttal (eller skicka den vidare oförändrad för nätverk med flyttalsutdata) och returnera dem som en lista med ndarray-objekt. De flesta applikationer registrerar en efterbehandlare – ett anropbart objekt som känner till nätverkets utdatalayout – för att avkoda tensorerna till den resultatform som applikationen agerar på: en lista med begränsningsrutor, en lista med nyckelpunkter, en lista med klasser.

Skriptet styr detta steg på två sätt. Nyckelordet postprocess= på konstruktorn registrerar en efterbehandlare som körs vid varje anrop. Nyckelordet callback=predict() åsidosätter den registrerade efterbehandlaren för endast ett anrop – användbart för att växla mellan flera avkodare utan att ladda om modellen. Båda formerna tar emot (model, inputs, outputs) och returnerar vad än applikationen förväntar sig.

7.6.4. Vad skriptet styr

Förbehandling och efterbehandling är skriptets två handtag. Standardförbehandlaren hanterar de flesta visionsmodeller; rätt efterbehandlare för en given nätverksfamilj väljs ur katalogen under ml.postprocessing. Motorn i mitten bestäms av bygget och körs på samma sätt oavsett vad skriptet ber om.