Matteo Basei

Una collezione di piccoli programmi realizzati a scopo didattico.

NeuNet la rappresentazione geometrica delle reti neurali Video YouTube

"Per trattare iperpiani in uno spazio a 14 dimensioni, visualizza uno spazio tridimensionale e di «quattordici» a te stesso molto forte. È quello che fanno tutti."

Geoffrey Hinton

Le reti neurali artificiali vengono spesso considerate delle "black box", delle scatole magiche che riescono a fare quello che fanno senza che si possa capire come lo fanno. Certamente le reti neurali usate per risolvere problemi reali sono costituite da un numero tale di elementi (neuroni e sinapsi) da renderne difficile l'analisi e soprattutto capirne i difetti quando qualcosa va storto. Basti pensare che già una semplice rete per riconosce cifre scritte a mano libera in piccole immagini di dimensione 20 x 20 come in questo mio piccolo esperimento, può tranquillamente arrivare ad avere 41000 sinapsi. Immaginate una rete neurale in grado di guidare un'automobile! Ma il problema è quantitativo, non qualitativo. Il funzionamento delle reti neurali ha infatti una semplice interpretazione geometrica.

Scopo di questo programma è mostrare questa cosa partendo da reti di piccole dimensioni, inutili dal punto di vista pratico, ma ottime dal punto di vista didattico!

La più semplice rete neurale con due ingressi e un'uscita, senza hidden layer.
La più semplice rete neurale con due ingressi e un'uscita, senza hidden layer.

L'input space

L'elemento fondamentale per comprendere la rappresentazione geometrica delle reti neurali è l'input space, uno spazio vettoriale avente un asse per ogni singolo ingresso della rete. Se avete qualche nozione di meccanica razionale è un concetto molto simile allo spazio delle configurazioni. Effettivamente possiamo vederlo come lo spazio delle configurazioni degli input della rete. Ogni punto di questo spazio corrisponde a un possibile set di ingressi.

Se ad esempio gli ingressi della rete sono i 16 pixel di un'immagine 4 x 4 in scala di grigi avremo uno spazio vettoriale a 16 dimensioni. Ad ogni asse corrisponderà il valore (ad esempio da 0 a 255) di uno dei pixel dell'immagine. Ad un punto dello spazio, con le sue 16 coordinate, corrisponderanno i valori dei 16 pixel e il punto identificherà quindi univocamente uno dei possibili input, cioè una delle possibili immagini 4 x 4.

Una rete con 2 neuroni nello strato nascosto fallisce nel tentativo di separare input distribuiti in modo \
Una rete con 2 neuroni nello strato nascosto fallisce nel tentativo di separare input distribuiti in modo "circolare".

Il perceptron

La semplice rete neurale per riconoscere cifre scritte a mano libera in immagini 20 x 20 citata all'inizio ha ben 400 ingressi (uno per ogni pixel dell'immagine) e 10 uscite (una per ogni cifra). Qui per semplicità, considereremo reti neurali con due ingressi e una singola uscita. Come vedremo considerando una singola uscita non si perde in generalità e con due ingressi si ha un input space bidimensionale, perfetto per essere rappresentato sullo schermo.

La più semplice rete di questo tipo è una funzione a 2 variabili, i 2 input, che indicheremo con $x_1$ e $x_2$, e 3 parametri: i 2 pesi sinaptici $w_1$ e $w_2$ (da weight, peso) e la soglia di attivazione $\theta$ (da threshold, soglia, a volte indicata anche con la $b$, da bias). Una rete di questo tipo viene chiamata perceptron in riferimento ad una delle prime realizzazioni di questo tipo, ottenuta da Frank Rosenblatt nel 1958, utilizzando il modello di neurone artificiale proposto da McCulloch e Pitts nell'articolo A logical calculus of the ideas immanent in nervous activity del 1943.

Tutto ciò che può fare una rete di questo tipo è suddividere gli input in due categorie separate da una retta. I pesi sinaptici regolano l'inclinazione della retta, la soglia di attivazione regola la posizione di tale retta rispetto all'origine dello spazio degli input. Consideriamo per semplicità una funzione di attivazione a gradino. In questo caso il neurone si attiva se $$ x \cdot w > \theta $$ dove a primo membro compare il prodotto scalare $$ x \cdot w = x_1 w_1 + x_2 w_2 $$ tra i vettori bidimensionali $x = \left[ x_1, x_2 \right]$ e $w = [w_1, w_2]$. Il prodotto scalare tra due vettori corrisponde geometricamente ad un numero proporzionale alla proiezione dell'uno sull'altro.

Generalizzando per un input space $n$-dimensionale e usando una funzione di attivazione $f$ l'uscita del neurone sarà $$ y = f \left( x \cdot w - \theta \right) $$ dove $$ x \cdot w = \sum_{i = 1}^n x_i w_i $$ In questo caso il perceptron potrà classificare gli ingressi dividento l'ipervolume $n$-dimensionale in due parti divise da un iperpiano $\left( n - 1 \right)$-dimensionale.

Il rendersi conto che una singola unità può classificare gli ingressi solo linearmente (fallendo anche nel semplice caso di ingressi XOR), evidenziata in particolare dal testo Perceptrons: An Introduction to Computational Geometry pubblicato da Minsky e Papert nel 1969, ha portato ad un periodo che è stato successivamente chiamato AI winter.

Una rete con 5 neuroni nello strato nascosto riesce ad approssimare input
Una rete con 5 neuroni nello strato nascosto riesce ad approssimare input "circolari".

L'hidden layer

Nel 1986 Hinton, Rumelhart e Williams pubblicano Learning representations by back-propagating errors in cui mostrano come creare e addestrare correttamente una rete con uno strato di neuroni aggiuntivo, chiamato hidden layer, interposto tra quello di input (che non fa altro che dare in output gli input della rete) e quello di output (che corrisponde sostanzialmente ad una serie di perceptron in parallelo).

Aggiungere un singolo neurone nascosto non porta a nessuna conseguenza, essendo essenzialmente la medesima cosa di aggiungere un singolo neurone a valle del neurone di uscita. Questo ulteriore neurone non potrà fare altro che suddividere linearmente la singola uscita a cui è collegato.

Aumentando il numero di neuroni nello strato nascosto è invece possibile delineare forme via via più complesse, quindi ottenere reti in grado di classificare distribuzioni via via più complesse di dati. In particolare il teorema di approssimazione universale dimostra che una rete neurale con un singolo strato nascosto con un numero sufficiente (e finito) di neuroni può approssimare qualsiasi funzione continua. Il teorema fu dimostrato da parte di George Cybenko nell'articolo Approximation by Superpositions of a Sigmoidal Function del 1989.

Il teorema di approssimazione universale è un teorema di esistenza, afferma che una rete con un singolo strato nascosto può approssimare qualsiasi funzione continua, ma non da alcuna indicazione su come ottenerla, come istruirla e se un singolo strato sia la scelta più efficiente.

Una rete con 5 neuroni nello strato nascosto alle prese con input di tipo \
Una rete con 5 neuroni nello strato nascosto alle prese con input di tipo "xor".

Rappresentazione algebrica

Normalmente, soprattutto nelle reti moderne costituite da un gran numero di layer, è in uso una rappresentazione algebrica alternativa e del tutto equivalente del calcolo neuronale con pesi sinaptici e soglie di attivazione.

Avendo un vettore di input $x_i$ con $i$ che prende i valori da $1$ a $n$ si pone $$ x_0 = 1 , \quad w_0 = -\theta $$ in modo da incorporare la soglie di attivazione del neurone nel vettore $w$ e calcolare semplicemente $$ y = f \left( \sum_{i = 0}^n x_i w_i \right) $$ in luogo di $$ y = f \left( \sum_{i = 1}^n x_i w_i - \theta \right) $$

In questo modo i pesi sinaptici e le soglie di attivazione di un intero layer costituito da $k$ neuroni possono essere incorporati in un'unica matrice $W_{ij}$ con tante righe quanti sono gli input (+1) e tante colonne quanti sono i neuroni del layer. In questo modo l'intero calcolo del layer diventa $$ y_i = f \left( \sum_{j = 0}^n x_j W_{ji} \right) $$ Il vettore risultate $y_i$ sarà un vettore $k$-dimensionale. Volendo usare una notazione priva di indici, essendo il vettore $x$ a sinistra, dovremmo usare il vettore riga $x^T$, oppure usare la matrice trasposta di $W$ e scrivere semplicemente $$ y = f \left( W^Tx \right) $$

L'apprendimento

L'apprendimento supervisionato consiste in sostanza nella determinazione dei pesi sinaptici e delle soglie di attivazione della rete partendo da un set di input precedentemente classificati manualmente. Anche l'algoritmo che si occupa di questo aspetto, la discesa del gradiente implementata attraverso la backpropagation perfezionato nel già citato articolo di Hinton, Rumelhart e Williams, ha una semplice ed interessante interpretazione geometrica, che ho cerco di spiegare nel modo più semplice e dettagliato possibile in questa pagina.

Un classico esempio di rete neurale ad apprendimento non supervisionato è invece l'autoencoder. In realtà i pesi sinaptici vengono aggiornati ancora tramite l'algoritmo di retropropagazione dell'errore, ma in questo caso gli input forniti non sono etichettati e l'output viene confrontato con l'input stesso. La rete ha una struttura simmetrica in cui dopo essere passati dall'input layer ad un layer centrale, chiamato bottleneck layer, si ripete a ritroso la struttura di ogni layer (con le stesse caratteristiche, fullyconnected, convoluzionale, eccetera, e con lo stesso tipo di funzione di attivazione) fino ad arrivare ad un output layer identico a quello di input. In pratica si istruisce la rete a replicare nell'output ciò che gli viene dato in input passando per un bottleneck layer di dimensione ridotta. Una volta addestrata la rete si va a vedere se e quali categorie sono naturalmente emerse nel bottleneck layer.

Deep learning

Diversi risultati teorici nel corso dei primi anni del nuovo millennio [...] evidenziano che la rappresentazione di certe funzioni richiederebbe un numero esponenziale di neuroni in un'architettura a singolo hidden layer, mentre un numero polinomiale di neuroni con reti "profonde", cioè architetture con un gran numero di hiddel layer. In generale si evidenza come nelle reti neurali depth is better than width, cioè la profondità (il numero di layer) è più importante della larghezza (il numero di neuroni in un singolo layer). [...] Contro: il problema della scomparsa del gradiente (vanishing gradient). [...]

Una rete con 2 hidden layer ciascuno con 10 neuroni, istruita con input randomici, riesce già ad approssimare funzioni molto complesse.
Una rete con 2 hidden layer ciascuno con 10 neuroni, istruita con input randomici, riesce già ad approssimare funzioni molto complesse.

Reti convoluzionali e long short term memory

In questa pagina abbiamo sempre parlato di un tipo di reti neurali chiamate feedforward fully connected, vale a dire reti neurali in cui:

Attualmente queste reti sono importanti principalmente da un punto di vista didattico o come parti di reti più complesse.

La comprensione di questo tipo di reti è un prerequisito per la comprensione di quelle da esse derivate, in cui queste due ipotesi vengono meno. Attualmente (2019) i tipi di rete neurale che vanno per la maggiore sono le reti convoluzionali (che non sono fully connected) e le long short term memory (un tipo particolare di rete ricorrente, quindi con collegamenti a loop).

Attention Is All You Need

Nel 2017 un team di Google pubblica il paper Attention Is All You Need, in cui si introduce l'architettura transformer, utilizzando la tecnica della self-attention introdotta l'anno precedente da Jianpeng Cheng e Mirella Lapata nell'articolo Neural summarization by extracting sentences and words. Questi tipi di reti sostituiscono le reti ricorrenti (come le long short term memory), affette dal già menzionato problema della scomparsa del gradiente, nel processare dati sequenziali come i liguaggi naturali. Questo approccio è alla base della maggior parte della cosiddetta intelligenza artificiale generativa (ChatGPT, DALL-E, AlphaFold, eccetera) ed è stato uno dei motori del cosidetto AI boom di questi ultimi anni.

Nel 2024, a testimonianza di quanto le reti neurali costituiscano uno dei campi di ricerca più importanti di questo periodo, sia il premio Nobel per la fisica che quello per la chimica sono stati assegnati a ricercatori nell'ambito delle reti neurali. Per la fisica il premio è stato assegnato al già citato Hinton (una delle figure più influenti nel campo dell'intelligenza artificiale) e a Hopfield (reti di Hopfield). Quello per la chimica ad Hassabis e Jumper, per lo sviluppo di AlphaFold di Google, in grado di prevedere la struttura proteica tridimensionale a partire dalla sequenza di amminoacidi, condiviso con Baker [...]