7.8. Tenzor I/O¶
Az engine a bemeneti oldalon egyetlen tenzort fogad el, a kimeneti oldalon pedig egyet vagy többet állít elő. A tenzorok ndarray objektumok azzal az alakkal, dtype-pal és leíró-szókinccsel, amelyet a numpy fejezet bevezetett. Alakjaik és dtype-jaik a modellfájlból származnak, és a input_shape / output_shape és a input_dtype / output_dtype attribútumokon keresztül jelennek meg.
7.8.1. Kvantálás¶
A kamera által futtatott legtöbb hálózat kvantált egész számos tenzorokon – int8 vagy uint8 – működik, hogy beférjen a kamera RAM- és számítási kereteibe. Egy kvantált tenzor egész értékeket hordoz, amelyek egy tenzoronkénti skálán és nullponton keresztül valós értékű számokat reprezentálnak:
A skála és a nullpont a modell tanításkori kalibrálásából származik, és a modellfájlban van tárolva. Ezek a input_scale, input_zero_point, output_scale és output_zero_point attribútumokként vannak elérhetővé téve – mindegyik egy lista, bemeneti vagy kimeneti tenzoronként egy bejegyzéssel.
Az ml.utils.quantize() és az ml.utils.dequantize() egy megadott kimeneti indexre alkalmazza a képleteket:
import ml.utils
real_tensor = ml.utils.dequantize(model, q_tensor, index=0)
q_tensor = ml.utils.quantize(model, real_tensor, index=0)
Mindkét függvény változatlanul adja vissza az értéket, amikor az adott indexen lévő kimeneti dtype már float, így a hívás biztonságos a modell kvantálási állapotától függetlenül.
7.8.2. Mit lát a szkript a kimeneti oldalon¶
Az, hogy a predict() mit ad vissza, attól függ, hogy regisztrálva van-e utófeldolgozó.
Utófeldolgozó nélkül az engine nyers egész kimenetei automatikusan dekvantálódnak floattá, és float ndarray objektumok listájaként térnek vissza. A szkript olvasásra kész valós értékű számokat kap. Ez a helyes út az osztályozási hálózatoknál, amelyek egyetlen kimeneti tenzora már osztályonkénti megbízhatósági pontszámok listája, amelyen az alkalmazás végigiterál – nincs szükség dekódolási lépésre. Ez egyben a könnyű út egy ismeretlen modell gyors elindításához, vagy a REPL-ből történő eseti vizsgálathoz is.
Regisztrált utófeldolgozóval (a konstruktoron lévő postprocess= vagy a predict hívásán lévő callback= révén) a nyers kvantált tenzorok közvetlenül az utófeldolgozó meghívható objektumának adódnak át. Az utófeldolgozó megkapja a nyers kvantált tenzorokat, és felelős minden szükséges dekvantálásért.
A szétválasztás egy teljesítménybeli döntés. Az automatikus dekvantálás minden kimenethez új float tenzort foglal, és minden elemen végighalad. Egy olyan utófeldolgozó, amelynek minden tenzorból csak néhány értékre van szüksége – megküszöböli a megbízhatósági pontszámokat, majd dekódolja a dobozokat a túlélőkhöz –, megspórolja a többi dekvantálásának költségét. A ml.postprocessing alatt szállított dobozdekódolók mind ezt az utat járják, és az ml.utils.threshold() pontosan erre az esetre készült: egy kvantált pontszámtenzort vesz át, és visszaadja azokat az indexeket, amelyek dekvantált értékei átmennek egy valós értékű küszöbön, anélkül hogy az egész tenzort dekvantálná.