7.6. A predict felépítése

A Model.predict(inputs, *, callback=None) az a hely, ahol a betöltött modellobjektum ténylegesen dolgozik. A bemenetek bemenése és az eredmény kijövetele között három szakasz fut egymás után: előfeldolgozás, engine-diszpécselés, utófeldolgozás. A háromból kettő olyan paramétereket vesz át, amelyeket a szkript közvetlenül vezérel; a középső engine-t a kamera dönti el.

Öt összekapcsolt doboz vízszintes folyama balról jobbra. A bal szélső az "Image input"; egy nyíl vezet a "Pre-process" "Normalization" alcímű dobozhoz; egy nyíl vezet az "Engine" "TFLM / STAI" alcímű dobozhoz; egy nyíl vezet a "Post-process" "postprocess=" alcímű dobozhoz; és egy utolsó nyíl vezet a "Result" dobozhoz. A három középső szakasz egy-egy címkét hord alattuk -- "user-controllable" a Pre-process alatt, "automatic" az Engine alatt, és "user-controllable" a Post-process alatt.

A predict() három szakasza. Az előfeldolgozás és az utófeldolgozás olyan paramétereket vesz át, amelyeket a szkript vezérel; a középső engine-t a kamera rögzíti.

7.6.1. Előfeldolgozás

Az előfeldolgozási szakasz minden bemenetet a hálózat által elvárt sűrű tenzorrá alakít. A leggyakoribb bemenet egy image.Image, amelyet RGB565 formátumban rögzítettek. A szakasz a hálózat input_shape méretére vágja és átméretezi, átalakítja RGB565-ből arra a csatornaformátumra, amelyre a hálózatot tanították (a legtöbb látórendszeri hálózatnál RGB888), csatornánkénti skálát és eltolást alkalmaz, és – amikor a hálózat egész számos bemenetet vár – ugyanabban a menetben a modell input_dtype típusára kvantál. A float bemenetre tanított hálózatok kihagyják a kvantálási lépést, és közvetlenül a skála-és-eltolás eredményét kapják.

Az alapértelmezett ml.preprocessing.Normalization beolvassa a modell bemeneti dtype-ját, és automatikusan a megfelelő transzformációt futtatja. Egy kézzel hangolt Normalization felülírja a skála-, átlag- és szórásértékeket azoknál a modelleknél, amelyeket egyéni csatornastatisztikák ellenében tanítottak (az ImageNetből származó átlagok és szórások gyakori eset). Egy egyszerű meghívható objektum teljesen felülírja a szakaszt – akkor hasznos, ha a bemenet egyáltalán nem kép, vagy amikor az alkalmazás már maga előállította a sűrű tenzort.

7.6.2. Engine-diszpécselés

Az engine-szakasz futtatja a hálózatot. Azt, hogy melyik engine-hez diszpécsel, a kamera rögzíti: a H7 és az RT1062 a TFLM-et futtatja (a TensorFlow Lite for Microcontrollers interpretert, amely ARM-ra optimalizált CMSIS-NN kerneleket diszpécsel ott, ahol léteznek); az AE3 ugyanazt a TFLM interpretert futtatja a Cortex-M55 tartalékával, és az Ethos-U NPU kezeli mindazokat az operátorokat, amelyeket az offline Vela fordító a gyorsítóhoz jelölt; az N6 az STAI-t futtatja, az ST futtatókörnyezetét az N6 célorientált NPU-jához.

A szkript nem választja ki az engine-t. A kamerával szállított engine futtat minden modellt, amelyet a kamera betölt.

7.6.3. Utófeldolgozás

Az utófeldolgozási szakasz a hálózat nyers kimeneti tenzorait visszaalakítja használható eredménnyé. Az alapértelmezett viselkedés az, hogy minden kimeneti tenzort lebegőpontossá dekvantál (vagy változatlanul továbbít a float kimenetű hálózatoknál), és ndarray objektumok listájaként adja vissza. A legtöbb alkalmazás regisztrál egy utófeldolgozót – egy meghívható objektumot, amely ismeri a hálózat kimeneti elrendezését –, hogy a tenzorokat azzá az eredményformává dekódolja, amelyre az alkalmazás reagál: határoló dobozok listájává, kulcspontok listájává, osztályok listájává.

A szkript két módon vezérli ezt a szakaszt. A konstruktoron lévő postprocess= kulcsszó egy minden híváskor lefutó utófeldolgozót regisztrál. A predict() metóduson lévő callback= kulcsszó csak egyetlen hívásra írja felül a regisztrált utófeldolgozót – akkor hasznos, ha több dekóder között váltunk a modell újratöltése nélkül. Mindkét forma (model, inputs, outputs) paramétereket kap, és azt adja vissza, amit az alkalmazás elvár.

7.6.4. Mit vezérel a szkript

Az előfeldolgozás és az utófeldolgozás a szkript két fogantyúja. Az alapértelmezett előfeldolgozó a legtöbb látórendszeri modellt kezeli; egy adott hálózatcsaládhoz a megfelelő utófeldolgozót a ml.postprocessing alatti katalógusból választják. A középső engine-t a build dönti el, és mindig ugyanúgy fut, függetlenül attól, mit kér a szkript.