RNN – Come funzionano le Recurrent Neural Network

AI, INTELLIGENZA ARTIFICIALE

Le RNN o Recurrent Neural Network sono molto interessanti perchè, a differenza delle feed forward, in cui l’informazione/segnale può andare solo in un verso ed ogni neurone può essere interconnesso con uno o più neuroni della catena successiva,

in questo tipo ti reti, i neuroni  possono ammettere anche dei loop e/o possono essere interconnessi anche a neuroni di un precedente livello.

Le reti ricorrenti prevedono, in sostanza, collegamenti all’indietro o verso lo stesso livello. Questa caretteristica rende  questo tipo di rete neurale molto interessante,  perchè il concetto di ricorrenza introduce intrinsecamente il concetto di memoria di una rete. In una rete RNN, infatti, l’output di un neurone può influenzare se stesso, in uno step temporale successivo o può influenzare neuroni della catenza precedente che a loro volta interferiranno con il comportamento del neurone su cui si chiude il loop. Ovviamente non esiste un solo modo di implementare una  rete RNN, infatti nel tempo sono stati proposti e studiati diversi tipi di rete RNN tra le più note ricordiamo quelle che si basano  sulle LSTM (Long Short Term Memory) e le GRU (Gated Recurrent Units), di cui parlermo in seguito.

Quando possiamo o dovremmo usare dunque le reti RNN?

Facciamo un esempio per capire bene il contesto. Se stessi analizzando una foto, in cui volessi osservare ad esempio degli oggetti di interesse,  dovrei fornire ad una rete neurale informazioni statiche nel tempo, ovvero i pixel della foto. Quest’ultimo scenario è facilmente gestibile attraverso una rete feed-forward ad esempio  una CNN opportunamente addestrata, il cui livello di input sarà costituito da tanti neuroni quanti sono i pixel che dovrò trattare moltiplicati per 3 qualora stessi usando immagini a colori  RGB.

Ma cosa devo fare, se invece di un’immagine statica avessi un video? Se volessi riconoscere ancora una volta degli oggetti, non cambierebbe nulla e  potrei continuare ad usare una rete feed-forward, ma se volessi, invece,  osservare un comportamento le cose sarebbero completamente diverse.

Riconoscere un comportamento presuppone l’analisi nel tempo di un’azione e solo l’insieme delle informazioni raccolte potrà darci indicazione sul tipo di comportamento avuto: Una cosa infatti è quella di  riconoscere una persona in un video ben diverso è capire se  la persona sta ad esempio bevendo o soffiando in una bottiglia.

Per comprendere meglio l’importanza della sequenza temporale,  basti pensare al linguaggio dei segni in cui non sarà sufficente riconoscere solo la mano ma sarà necessario comprendere la sequenza dei movimenti per interpretare il significato del gesto.

Il  nostro obiettivo dunque sarà quello di comprendere come trattare informazioni dinamiche nel tempo e quindi imparare a costruire ed istruire una rete con memoria (RNN) in modo che sia in grado di osservare i cambiamenti e riconoscere azioni diverse. Come abbiamo, già, più volte ripetuto, la soluzione al nostro problema è la RNN, che nella sua forma più semplice è  schematizzabile come una cella RNN. Vediamo di cosa si tratta.

Prima di spiegare la cella RNN dobbiamo assolutamente comprendere che le stesse lavorano nel tempo, per cui a differenza delle rete feed-forward classiche in cui il dato fornito era statico, il tipo di dato che la rete RNN è in grado di trattare è una sequenza temporale o serie temporale. Proviamo a fornire qualche esempio.

Una squenza temporale o serie temporale può essere considerata come una funzione campionata in più istanti di tempo. Ad esempio può essere la forma d’onda di una voce campionata, l’andamento di un  titolo di borsa o una frase.

 

Nel caso di una sequenza costituita da una frase, i campioni saranno, dunque, le singole parole opportunamente codificate. In tal caso la cella RNN riceverà come input, nel tempo, le singole parole, che  verrebbero trattate in funzione, anche, della parola precedente o delle parole precendenti, questo dipenderà dal tipo di cella RNN che si utilizzerà.

In sintesi, nella cella RNN ad ogni instante t, il livello  riceverà  oltre all’input X(t) anche il suo output S(t-1). La retroazione dell’output consentirà alla rete di basare, in definitiva,  le sue decisioni sulla storia passata. In questo tipo di approccio è, dunque, evidente che sarà fondamentale fissare il numero massimo di iterazioni da trattare, altrimenti come è facilmente intuibile la rete entrerebbe in un loop.

Capito dunque che una rete RNN può essere rappresnetata da una cella con un loop a stati finiti, cerchiamo di capire come sia possibile addestrarla.

Introduciamo allo scopo il concetto di  unfolding della rete , che si traduce, in sostanza, in un’operazione di trasformazione di una rete RNN in una di tipo feed-forward. Se si guarda, infatti, la figura seguente si può facilmente capire che la rete neurale RNN è diventanta una rete neurale feedforward.

Cerchiamo di formalizzare un pò il concetto di cui sopra. Una cella RNN è una parte di rete ricorrente che preserva uno stato interno h(t) per ogni istante temporale. Essa è costituita da un numero prefissato di neuroni e può essere considerata come una sorta di livello della rete. Nella nostra rete ad ogni istante l’output sarà h_{t}=f(h_{(t-1)},X_{t}) dove  h_{t} dipende dall’input X_{t} e dallo stato precedente h_{(t-1)}.

In definitiva procedere con l’unfolding della rete significa fissare a priori il numero di passi temporali su cui effettuare l’analisi. Per cui una rete neurale RNN unfolded su 10 step equivale ad una DNN feed-forward con 10 livelli.

Se riprendiamo per un istante il funzionamento di un neurone con due ingressi  ricorderemo che  la funzione di uscita, come spiegato nell’articolo dedicato alle reti feed-forward,  è qualcosa del tipo:

A=x_{1}*w_{1}+x_{2}*w_{2} mentre la Y=\frac{1}{1+e^{-(x_{1}*w_{1}+x_{2}*w_{2})}} ove la sigmoide in tal caso è la funzione di attivazione,che chiameremo in generale \varphi, e b=0

Applicando lo stesso ragionamento alla RNN avremo : h(t) = \varphi (x_{t}*w_{x}+h_{(t-1)}*w_{h}+b) ove w_{x} e w_{h} sono i pesi, b è il bias e \varphi è la funzione di attivazione.

Le celle più semplici così come enunciate avranno un limite nella capacità di apprendimento, ovvero nel ricordare gli input di step lontani, questo limite potrebbe diventare un problema, quando si ha la necessità di tener traccia anche di eventi lontani. Nel caso di una frase ad esempio diventa fondamentale il contesto delle parole. In una frase, infatti, non è rilevante solo la presenza di specifiche parole ma è importante anche come le stesse siano tra di loro legate, pertanto  ricordare in una sequenza di parole solo quella immediatamentee precedente  non da nessun valore aggiunto. In tal caso avremo bisogno di celle di memoria più complesse, quali le  LSTM o le GRU di cui, però, parleremo nel prossimo articolo.

Comments