Andiamo nei bit e nei byte

Immagine di Adrien Converse su Unsplash

Per 50 anni, dai tempi di Kernighan, Ritchie e della loro prima edizione del libro sul linguaggio C, era noto che un tipo “float” a precisione singola ha una dimensione di 32 bit e un tipo a precisione doppia ha 64 bit. Esisteva anche un tipo “long double” a 80 bit con precisione estesa e tutti questi tipi coprivano quasi tutte le esigenze di elaborazione dei dati in virgola mobile. Tuttavia, negli ultimi anni, l’avvento di modelli di reti neurali di grandi dimensioni ha richiesto agli sviluppatori di spostarsi in un’altra parte dello spettro e di ridurre il più possibile i tipi in virgola mobile.

Onestamente sono rimasto sorpreso quando ho scoperto che esiste il formato a virgola mobile a 4 bit. Come diavolo può essere possibile? Il modo migliore per saperlo è testarlo da soli. In questo articolo scopriremo i formati in virgola mobile più popolari, creeremo una semplice rete neurale e vedremo come funziona.

Iniziamo.

Un punto mobile “standard” a 32 bit

Prima di addentrarci nei formati “estremi”, ricordiamone uno standard. UN IEEE754 Lo standard per l’aritmetica in virgola mobile è stato stabilito nel 1985 dall’Institute of Electrical and Electronics Engineers (IEEE). Un numero tipico in un tipo a 32 float è simile al seguente:

Qui il primo bit è un segno, i successivi 8 bit rappresentano un esponente e gli ultimi bit rappresentano la mantissa. Il valore finale viene calcolato utilizzando la formula:

Questa semplice funzione di supporto ci consente di stampare un valore in virgola mobile in forma binaria:

import struct

def print_float32(val: float):
""" Print Float32 in a binary form """
m = struct.unpack('I', struct.pack('f', val))(0)
return format(m, 'b').zfill(32)

print_float32(0.15625)

# > 00111110001000000000000000000000

Creiamo anche un altro helper per la conversione all’indietro, che sarà utile in seguito:

def ieee_754_conversion(sign, exponent_raw, mantissa, exp_len=8, mant_len=23):
""" Convert binary data into the floating point value """
sign_mult = -1 if sign == 1 else 1
exponent = exponent_raw - (2 ** (exp_len - 1) - 1)
mant_mult = 1
for b in range(mant_len - 1, -1, -1):
if mantissa & (2 **…

Fonte: towardsdatascience.com

Lascia un commento

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