7.8. Tensorin I/O¶
Moottori hyväksyy syötepuolelta yhden tensorin ja tuottaa yhden tai useamman tulostepuolelle. Tensorit ovat ndarray -olioita, joilla on muoto, dtype ja kuvaajien sanasto, jotka numpy-luvussa esiteltiin. Niiden muodot ja dtype-tyypit tulevat mallitiedostosta ja ilmoitetaan ominaisuuksien input_shape / output_shape ja input_dtype / output_dtype kautta.
7.8.1. Kvantisointi¶
Useimmat kameran ajamat verkot toimivat kvantisoiduilla kokonaislukutensoreilla – int8 tai uint8 – mahtuakseen kameran keskusmuistiin ja laskentabudjettiin. Kvantisoitu tensori kuljettaa kokonaislukuarvoja, jotka edustavat reaaliarvoisia lukuja tensorikohtaisen skaalauksen ja nollapisteen kautta:
Skaalaus ja nollapiste tulevat mallin koulutusajan kalibroinnista ja tallennetaan mallitiedostoon. Ne esitetään ominaisuuksina input_scale, input_zero_point, output_scale ja output_zero_point – kukin lista, jossa on yksi merkintä kutakin syöte- tai tulostensoria kohden.
ml.utils.quantize() ja ml.utils.dequantize() soveltavat kaavoja määriteltyä tulosteindeksiä vastaan:
import ml.utils
real_tensor = ml.utils.dequantize(model, q_tensor, index=0)
q_tensor = ml.utils.quantize(model, real_tensor, index=0)
Molemmat funktiot palauttavat arvon muuttumattomana, kun annetun indeksin tulosteen dtype on jo liukuluku, joten kutsu on turvallinen riippumatta mallin kvantisointitilasta.
7.8.2. Mitä skripti näkee tulostepuolella¶
Se, mitä predict() palauttaa, riippuu siitä, onko jälkikäsittelijä rekisteröity.
Ilman jälkikäsittelijää moottorin raa’at kokonaislukutulosteet puretaan automaattisesti kvantisoinnista liukuluvuksi ja palautetaan listana liukuluku-ndarray -olioita. Skripti saa reaaliarvoisia lukuja, jotka ovat valmiita luettaviksi. Tämä on oikea polku luokitteluverkoille, joiden yksittäinen tulostensori on jo lista luokkakohtaisia luottamuspisteitä, joita sovellus käy läpi – purkamisvaihetta ei tarvita. Se on myös helppo polku saada tuntematon malli nopeasti käyntiin tai REPL:stä tapahtuvaan satunnaiseen tarkasteluun.
Kun jälkikäsittelijä on rekisteröity (avainsanalla postprocess= konstruktorissa tai callback= predict-kutsussa), raa’at kvantisoidut tensorit luovutetaan jälkikäsittelijän kutsuttavalle oliolle suoraan. Jälkikäsittelijä saa raa’at kvantisoidut tensorit ja vastaa tarvitsemastaan kvantisoinnin purkamisesta.
Jako on suorituskykyvalinta. Automaattinen kvantisoinnin purku varaa uuden liukulukutensorin jokaiselle tulosteelle ja käy läpi jokaisen elementin. Jälkikäsittelijä, joka tarvitsee vain muutaman arvon kustakin tensorista – kynnystää luottamuspisteet ja purkaa sitten laatikot selviytyjille – ohittaa lopun purkamisen kustannuksen. Moduulin ml.postprocessing alla toimitettavat laatikkopurkajat valitsevat kaikki tämän reitin, ja ml.utils.threshold() on rakennettu juuri tätä tapausta varten: se ottaa kvantisoidun pisteytystensorin ja palauttaa indeksit, joiden puretut arvot ylittävät reaaliarvoisen kynnysarvon, purkamatta koko tensoria.