Cominciamo con un esempio molto semplice e costruiamolo.

Esempio-1: quantizzazione simmetrica uint8

Diciamo che desideriamo mappare l’intervallo in virgola mobile (0.0 .. 1000.0) sull’intervallo quantizzato (0 .. 255). L’intervallo (0…255) è l’insieme di valori che possono essere contenuti in un numero intero a 8 bit senza segno.

Per eseguire questa trasformazione, vogliamo ridimensionare l’intervallo in virgola mobile in modo che sia vero quanto segue:

Virgola mobile 0.0 = Quantizzato 0

Virgola mobile 1000.0 = Quantizzato 255

Questa è chiamata quantizzazione simmetrica perché la virgola mobile 0.0 è quantizzata 0.

Quindi, definiamo una scala, che è uguale a

Dove,

In questo caso, scala = 3.9215

Per convertire da un valore in virgola mobile a un valore quantizzato, possiamo semplicemente dividere il valore in virgola mobile per la scala. Ad esempio, il valore in virgola mobile 500.0 corrisponde al valore quantizzato

In questo semplice esempio, lo 0,0 dell’intervallo in virgola mobile corrisponde esattamente allo 0 nell’intervallo quantizzato. Questa è chiamata quantizzazione simmetrica. Vediamo cosa succede quando questo non è il caso.

Esempio 2: quantizzazione affine uint8

Diciamo che desideriamo mappare l’intervallo in virgola mobile (-20.0 .. 1000.0) sull’intervallo quantizzato (0 .. 255).

In questo caso, abbiamo un fattore di scala diverso rispetto al nostro xmin è diverso.

Vediamo cosa rappresenta il numero in virgola mobile 0.0 nell’intervallo quantizzato se applichiamo il fattore di scala a 0.0

Bene, questo non sembra del tutto corretto poiché, secondo il diagramma sopra, ci saremmo aspettati che il valore in virgola mobile -20.0 corrispondesse al valore quantizzato 0.

È qui che entra in gioco il concetto di punto zero. Il punto zero funge da bias per lo spostamento del valore in virgola mobile scalato e corrisponde al valore nell’intervallo quantizzato che rappresenta il valore in virgola mobile 0,0. Nel nostro caso, il punto zero è il negativo della rappresentazione in virgola mobile scalata di -20.0, che è -(-5) = 5. Il punto zero è sempre il negativo della rappresentazione del valore minimo in virgola mobile poiché il minimo sarà essere sempre negativo o zero. Scopriremo di più sul perché questo è il caso nella sezione che spiega l’esempio 4.

Ogni volta che quantizziamo un valore, aggiungeremo sempre il punto zero a questo valore scalato per ottenere il valore quantizzato effettivo nell’intervallo di quantizzazione valido. Nel caso in cui desideriamo quantizzare il valore -20.0, lo calcoliamo come il valore scalato di -20.0 più il punto zero, che è -5 + 5 = 0. Quindi, quantized(-20.0, scale=4, zp=5 ) = 0.

Esempio-3: quantizzazione affine int8

Cosa succede se il nostro intervallo quantizzato è un intero a 8 bit con segno anziché un intero a 8 bit senza segno? Bene, l’intervallo è ora (-128 .. 127).

In questo caso, -20.0 nell’intervallo float viene mappato a -128 nell’intervallo quantizzato e 1000.0 nell’intervallo float viene mappato a 127 nell’intervallo quantizzato.

Il modo in cui calcoliamo il punto zero è calcolarlo come se l’intervallo quantizzato fosse (0 .. 255) e quindi compensarlo con -128, quindi il punto zero nel nuovo intervallo è

Pertanto, il punto zero per il nuovo intervallo è -123.

Finora abbiamo esaminato esempi in cui l’intervallo in virgola mobile include il valore 0,0. Nella prossima serie di esempi, daremo un’occhiata a cosa succede quando l’intervallo in virgola mobile non include il valore 0.0

L’importanza di 0.0

Perché è importante che il valore in virgola mobile 0.0 sia rappresentato nell’intervallo in virgola mobile?

Quando si utilizza una convoluzione riempita, ci si aspetta che i pixel del bordo vengano riempiti utilizzando il valore 0.0 nel caso più comune. Pertanto, è importante che 0.0 sia rappresentato nell’intervallo in virgola mobile. Allo stesso modo, se il valore X verrà utilizzato per il riempimento nella rete, è necessario assicurarsi che il valore X sia rappresentato nell’intervallo in virgola mobile e che la quantizzazione ne sia consapevole.

Esempio 4: La storia non raccontata: intervallo in virgola mobile distorto

Ora diamo un’occhiata a cosa succede se 0.0 non fa parte dell’intervallo in virgola mobile.

In questo esempio, stiamo cercando di quantizzare l’intervallo in virgola mobile (40,0 .. 1000,0) nell’intervallo quantizzato (0 .. 255).

Poiché non possiamo rappresentare il valore 0.0 nell’intervallo in virgola mobile, dobbiamo estendere il limite inferiore dell’intervallo a 0.0.

Possiamo vedere che una parte dell’intervallo quantizzato viene sprecata. Per determinare quanto, calcoliamo il valore quantizzato a cui è associato il valore in virgola mobile 40.0.

Quindi, stiamo sprecando l’intervallo (0 .. 9) nell’intervallo quantizzato, che rappresenta circa il 3,92% dell’intervallo. Ciò potrebbe influire in modo significativo sulla precisione post-quantizzazione del modello.

Questa distorsione è necessaria se vogliamo essere sicuri che il valore 0.0 nell’intervallo in virgola mobile possa essere rappresentato nell’intervallo quantizzato.

Un altro motivo per includere il valore 0,0 nell’intervallo in virgola mobile è che confrontare in modo efficiente un valore quantizzato per verificare se è 0,0 nell’intervallo in virgola mobile è molto utile. Pensa a operatori come ReLU, che ritagliano tutti i valori inferiori a 0,0 nell’intervallo in virgola mobile a 0,0.

Per noi è importante poterlo fare rappresentare il punto zero utilizzando lo stesso tipo di dati (con segno o senza segno int8) come valori quantizzati. Ciò ci consente di eseguire questi confronti in modo rapido ed efficiente.

Successivamente, diamo un’occhiata a come la normalizzazione dell’attivazione aiuta con la quantizzazione del modello. Ci concentreremo in particolare su come la standardizzazione dei valori di attivazione ci consenta di utilizzare in modo efficace l’intero intervallo quantizzato.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *