Abbiamo già parlato delle reti neurali. Una rete neurale è, in sintesi, una fitta interconnessione di elementi semplici chiamati percettroni. Tali unità, disposte in due o più strati, sono in grado di adattarsi tramite algoritmi particolari in modo tale che dato un ingresso X la rete “apprenda” l’uscita Y. Non entrerò oltre nel dettaglio, la materia è infatti piuttosto complicata acnhe trattata in modo superficiale.
A questo punto è bene precisare che questa procedura è quasi esclusivamente una mia particolare speculazione. Non ho letto nessuna pubblicazione al riguardo ma dai miei piccolissimi test sembra funzionare correttamente. Ma veniamo al punto.
Supponiamo di avere una rete neurale come quella in figura:
Abbiamo una rete con 4 ingressi binari e altrettante uscite. Poi, subito prima dell’uscita e subito dopo l’ingresso, ci sono due blocchi nascosti. Tali blocchi sono composti da uno o più strati della rete, l’importante è che le due sotto-reti siano simmetriche. Infine abbiamo due strati centrali, l’importante è che tali strati contengano un numero di unità minori di quelle in ingresso e uscita.
A questo punto addestriamo la rete in modo tale che ad un ingresso X corrisponde un uscita Y del tutto uguale all’uscita. Vi chiederete, a che diavolo serve una rete neurale che non faccia altro che dare in uscita lo stesso valore in ingresso? A nulla, ovviamente, ma proviamo a separare la rete in due reti all’altezza dello strato centrale. In questo modo abbiamo due reti: una con 4 ingressi e 2 uscite e una con 2 ingressi e 4 uscite.
Per il modo in cui la rete è stata addestrata possiamo trattare la prima rete come un coder e la seconda rete è un decoder. L’utilizzo di questa rete può essere, ad esempio, di codificare un’immagine spezzandola a blocchi di 4 bit e passandola nel coder. Il risultato sarà un file ridotto del 50%. La decodifica, analogamente, avviene spezzando il file codificato in blocchi da 2 bit per riottenere i 4 bit originali.
È bene precisare che questa compressione è solitamente lossy (quindi ha utilità solo per codifiche video/audio/immagini) in quanto le reti neurali solitamente sono “approssimazioni” oltre che statisticamente fonte di errore. Inoltre, il caso di 4 bit ridotti a 2 è poco efficente, solitamente andrebbero usato un ingresso molto più numeroso e un fattore di compressione variabile. Più il valore di compressione è alto più, ovviamente, la possibilità di errori e l’approssimazione aumenta.
Il vantaggio di questa tecnica è che, poiché la rete può essere facilmente addestrata partendo da pezzi del file da codificare, la rete apprende la migliore codifica da N a M per quello specifico file.
Questo è un piccolo esempio di come sia possibile utilizzare una tecnologia nata dall’intelligenza artificiale per compiti che apparentemente non hanno nulla a cui spartire con essa come la codifica multimediale.
Mmm non mi trovi d’accordo su questo ragionamento.
Come hai giustamente evidenziato tu nell’ultima parte, per ogni singolo file andrebbe addestrata una rete specifica che a sua volta rappresenterebbe sia l’encoder che il decoder del file stesso.
Ma insieme al file codificato/compresso, andrebbe distribuita anche la metà della rete che si occupa del decoding essendo specializzata e non generica.
Considerando che una rete viene rappresentata da tipi double, i quali notoriamente occupano ben più dei 4 byte di un intero o del byte del singolo carattere, molto probabilmente (diciamo anche sicuramente) la grandezza dell’archivio complessivo potrebbe equagliare, se non superare il file originale.
Mettici anche che questo tipo di ragionamento va bene su stream molto piccoli, ma l’entropia di un file “normale” è talmente elevata (così come la deviazione standard quindi), che non risciresti mai ad addestrare una rete per rappresentare in toto il file.
Quindi ti troveresti a codificare N coder per N chunks a 4 bit, sicuro che conviene? 🙂
I parametri della seconda rete sono facilmente “allegabili” dopotutto, esagerando, una rete da 1000 unità si codifica con circa 2000 float. Occupano in media meno dello 0.5% di un file immagine o di un qualunque stream audio.
Inoltre l’entropia di un qualunque stream di dati è molto meno elevata di quello che pensi. Una foto di un paesaggio, ad esempio, è comprimibile fino al 90% tramite compressione frattale (che è la compressione che più sfrutta l’entropia). Un audio parlato ha un livello di “pattern” elevatissimo. Il bello della compressione che sfrutta le reti neurali è che tali pattern non hanno bisogno di essere conosciuti a priori perché è la rete stessa che li apprende (oltre al fatto che può facilmente essere implementata via hardware).
Ovviamente il mio è un articolo molto seplicistico. Mentre scrivevo poi mi sono informato e ho scoperto molte pubblicazioni e articoli al riguardo tipo
http://www.comp.glam.ac.uk/digimaging/neural.htm
http://neuron.eng.wayne.edu/bpImageCompression9PLUS/bp9PLUS.html
http://cs.fit.edu/~mmahoney/compression/
Il principio alla base è quello che ho descritto io, solo che loro trattano, ovviamente, anche tutti i dettagli.
allora faccio qualche ricerca, xkè se fosse possibile quello che dici (e a quanto pare lo è! :D) potrebbe diventare una cosa divertente da implementare 🙂
PS: Non ricevo le notifiche email delle risposte su i commenti in questo blog :S
Eh no, ho letto bene quella documentazione e l’approccio è completamente diverso dal tuo, quindi ribadisco che il tuo modello non può funzionare.
Il loro approccio è un encoder predittivo, ovvero una rete che, data una maschera di simboli chiamata contesto, predice la possibilità che un dato simbolo (il prossimo carattere da encodare) possa comparire.
Questa probabilità, che ha un intervallo [0,1] è palesemente rappresentabile con meno bit dell’intervallo ascii [0,255], di conseguenza si ottiene una compressione.
Mm… io ho implementato il mio in Python e ho visto che comprime decentemente fino al 60% di un immagine con risultati in uscita abbastanza decenti. Poi appena commento te lo invii così provi anche tu. Magari dipende solo dal tipo di file. 🙁