Che cos'è una rete neurale?

Come tante parole in italiano, rete neurale non ha solo un significato.
In ambito biologico indica un sistema di neuroni che concorrono a una determinata funzione fisiologica. In campo informatico, o meglio, nel contesto dell’ intelligenza artificiale, una rete neurale è un modello matematico che permette di simulare il funzionamento del cervello umano.
Si può pensare a una rete neurale come un modello matematico che è in grado di costruire, in modo approssimativo, una qualsiasi funzione a partire da dei dati di input. Schematizziamo quindi una funzione f(x) come una funzione definita da più funzioni g(x) che a loro volta possono essere composte da altre funzioni.
Entrando nello specifico, una rete si compone di nodi chiamati neuroni artificiali e viene suddivisa in almeno 3 strati o layer.
Il primo layer è quello degli input e viene chiamato input layer . Nell'immagine rappresentata l'input è composto da una matrice (o vettore riga) X di dimensione 1×3 che trasposta diventa una matrice (o vettore colonna) Xᵀ di dimensione 3×1 rappresentata in figura dai 3 nodi iniziali.
Il secondo layer, chiamato hidden layer il risultato della trasformazione della matrice Xᵀ in una nuova matrice G di dimensione 5×1 tramite l'utilizzo delle funzioni g(x) che compongono f(x). Una rete neurale può essere composta da più hidden layer se il problema da risolvere, o la funzione da approssimare fossero molto complessi.
L' ultimo layer, denominato output layer è il risultato di tutte le operazioni precedenti, è la trasformazione della matrice G nel risultato di f(X). Generalizzando ancor di più è importante ricordare che l'output layer può essere composto da più nodi, questo significa che è possibile ricercare più funzioni a partire dagli stessi dati.
Questo tipo di rete viene chiamato feedforward dato che il suo grafico procede in maniera rettilinea e non ciclica.

Ma come funziona un neurone artificiale?

I neuroni che compongono una rete hanno il compito di elaborare i dati in input e di restituire un output a seconda di fari fattori e dei calcoli che si andranno a svolgere.
Per semplificare, si può prendere come esempio un neurone che riceve come input n elementi (nell'esempio i1 = 1.5 i2 = 1.0 i3 = 2.0) che vengono moltiplicati ciascuno per un opportuno valore chiamato weight (nell'esempio w1 = 0.5 w2 = 3.0 w3 = -1.0). I risultati delle moltiplicazioni vengono poi sommati (nell'esempio U = Σ(ik × wk) = 1.75 ). Il risultato di queste operazione viene poi utilizzato come x in una funzione f(x) chiamata funzione di attivazione. Il risultato di f(x) se supera un certo valore di soglia che dipende dalla funzione attiva o meno il neurone facendo uscire come output la differenza tra x - f(x). Esistono varie funzioni di attivazioni, nell'esempio a destra viene utilizzata una funzione sigmoidea f(x) = (1 + e-x)-1 . Questa funzione attiva il neurone se f(x0) > 0.5. Completando i calcoli dell'esempio f(1.75) ≈ 0.85 > 0.5 → P = 1.75 - f(1.75) ≈ 0.90.
Questo modello appena illustrato non descrive solo i neuroni dell'hidden layer ma anche quelli dell'output layer.
Se estendiamo l'esempio appena descritto con un modello a matrici si possono riscrivere i calcoli con una matrice input I di dimensione 1×3, I = (1.5 1.0 2.0) e con una matrice weights W di dimensione 1×3, W = (0.5 3.0 -1.0). Il risultato prima della funzione di attivazione sarà U = I × Wᵀ e dato che le 2 matrici hanno dimensione uguale e una sola riga il risultato sarà un numero scalare che sarà utilizzato come x nella funzione di attivazione.

Cosa rappresentano i valori di weights?

Nella spiegazione precedente è stato introdotto il concetto di valore di weight. Questo concetto non è fine a sè stesso, è un valore che indica una cosa fondamentale per le reti neurali.
Questo valore indica infatti il peso e l'importanza che ha un collegamento neurale. Se per esempio un input è più importante di un altro, avrà dei valori di weights maggiori per fornire una connessione "preferenziale", una connessione che la rete neurale potrà seguire più facilmente. Due neuroni quindi comunicheranno utilizzando maggiormente quelle connessioni dove i valori di weights sono più elevati. Bisogna ricordare che durante lo sviluppo di una rete neurale e durante il suo apprendimento questi valori di weights non saranno mai 0 e quindi una rete neurale non eliminerà mai del tutto un percorso neurale.

Metodi di apprendimento

Ora la domanda sorge spontanea: come fanno le reti neurali ad imparare?

Esistono 4 grandi tipi di apprendimento che vengono utilizzati per istruire le reti neurali: apprendimento supervisionato, apprendimento non supervisionato, apprendimento per rinforzo, apprendimento profondo.
L'apprendimento supervisionato si basa sulla disponibilità di dati per l'addestramento ( training set) della rete neurale. Questi dati sono composti da esempi di input con i relativi output così che la rete neurale sia in grado di capire e imparare la relazione che collega un dato al suo risultato. Mediante opportuni algoritmi vengono modificati i valori di weights della rete in modo tale che l'errore tra il risultato previsto dalla rete e il risultato effettivo tenda a 0. Uno dei principali algoritmi che minimizza l'errore è quello noto come backpropagation. Dopo la fase di training, si passa alla fase di test. Se il training ha avuto successo, la rete neurale avrà imparato la relazione tra i dati di input e di output e sarà in grado di fare previsioni su nuovi dati che dovrebbero dare risultati in linea con i risultati precedenti. Questo tipo di apprendimento è utile ed efficace in problemi di regressione e di classificazione.
L'apprendimento non supervisionato si basa su algoritmi che modificano i valori di weights partendo solo da dati di input. Questi algoritmi cercano delle corrispondenze tra i vari dati forniti, raggruppano e classificano gli input e in seguito cercano di fare una previsioni autonomamente. Questi tipi di algoritmi sono molto efficaci con input di tipo numerico dato che possono utilizzare molte tecniche che derivano dalla statistica.
Il terzo tipo è l'apprendimento per rinforzo che si basa sull'individuazione di un certo modo di operare partendo dall'osservazione di ciò che accade all'ambiente esterno. Ogni output della rete produce un effetto sull'ambiente che a sua volta produce un'azione sulla rete neurale. Questa azione che l'ambiente produce può essere negativa o positiva, la rete neurale aggiusterà i valori di weights (e talvolta anche la propria struttura) per minimizzare le risposte negative e per massimizzare quelle positive. Un esempio di apprendimento per rinforzo sono gli algoritmi genetici di cui verrà approfondita la spiegazione in seguito.
L'apprendimento profondo è particolare rispetto a tutti gli altri metodi di apprendimento perchè si basa su reti neurali molto complesse e fa affidamento sia all'apprendimento supervisionato sia a quello non supervisionato. Questo metodo di apprendimento è molto utilizzato per l'elaborazione di immagini grazie anche all'utilizzo di reti neurali convoluzionali che si ispirano alla corteccia visiva animale.

Flappy Bird

Questo è un esempio di applicazione di una rete neurale ad un videogioco. Il videogioco può essere giocato normalmente ma selezionando la modalita AI e premendo PLAY il gioco verrà interrotto e il computer inizierà a imparare a giocare autonomamente.

CONTROLLI

Questi sono i settaggi di gioco. Puoi scegliere la modalità di gioco Normale e giocare tu; oppure puoi scegliere AI e lasciare che il computer impari a giocare.

Imposta la modalità di gioco:

Velocità:

0

Carica uccellino preaddestrato:

Carica

Come funziona?

L'esempio di Flappy Bird si basa su una rete neurale composta da 5 nodi di input, un hidden layer con 8 nodi e un output layer di 2 nodi.
Gli input che riceve la rete neurale sono: la distanza dei tubi dall'uccellino, l'altezza del tubo superiore, quella del tubo inferiore, la posizione y dell'uccellino e la sua velocità.
Il numero di nodi dell'hidden layer è stato scelto arbitrariamente, mentre 2 sono gli output dato che se o 1 > o 2 l'uccellino volerà, al contrario cadrà.

Quale metodo di apprendimento è stato utilizzato?

Per permettere a questa rete neurale di evolversi è stato utilizzato un apprendimento con rinforzo, più precisamente un algoritmo genetico.
Il gioco parte con una popolazione di 500 uccellini tutti con una rete neurale settata randomicamente. Ogni qualvolta un uccellino tocca un tubo ad esso viene attribuito un valore di fitness (o di idoneità) in base alla distanza percorsa e verranno eliminati dal gioco. Questo valore di fitness è, in certo senso, l'azione che l'ambiente provoca nella rete neurale. Infatti più sarà alto questo valore di fitness più sarà probabile che la rete neurale sopravviva rispetto alle altre. Ogni volta che tutti gli uccellini della popolazione saranno eliminati inizia il processo di creazione di una nuova popolazione di 500 uccellini. Questa volta però le reti neurali non saranno configurate casualmente ma subiranno un processo di evoluzione. In termini darwiniani possiamo dire che maggiore è il valore di fitness maggiore sarà la probabilità che quel specifico uccellino si riproduca. Durante il processo di riproduzione la rete neurale non resta uguale ma i valori di weights subiscono dei piccoli cambiamenti casuali. Una volta ricreata una popolazione di 500 uccellini il gioco riparte con lo stesso ciclo.