Sei sulla pagina 1di 8

Neural Network Toolbox

In questa sede verr presentata una trattazione esauriente delle caretteristiche fondamentali del Neuron Network Toolbox presente come pacchetto supplementare al software Matlab ( si far riferimento alla versione 3.0 del Toolbox ). In particolare si cercher di illustrare le caratteristiche principali di questo potente pacchetto applicativo facendo riferimento alla notazione sintattica, essenziale per poter apprendere le basi per progettare una qualsisa rete neurale utilizzando le funzionalita' del toolbox. Infine, verranno presentate le topologie di reti pi semplici ma nello stesso tempo pi facili da comprendere per un eventuale approfondimento futuro. Una rete neurale composta da semplici elementi che operano in parallelo su uno o piu' livelli. L'idea di fondo quella di addestrare una rete neurale affinch approssimi il meglio possibile una certa funzione aggiustando i pesi delle connessioni tra gli elementi stessi. L'addestramento della rete pu avvenire in due modi distinti: in una modalit supervisionata, mediante l'utilizzo di un training set, ossia di un campione di coppie input / output effettivo, o, alternativamente, senza supervisore appoggiandosi su una competizione interna tra i neuroni. In questa trattazione verr presentato esclusivamente il primo modo di allenamento della rete. Il punto di partenza un insieme di coppie di ingressi e uscite reali. Tali input campione vengono dati in inserimento alla rete e il risultato della computazione viene confrontato con l'output effettivo. L'errore in questo modo calcolato ( a meno che i due risultati non coincidano ) viene utilizzato per aggiornare i pesi delle connessioni tra gli elementi e ripetere l'addestramento della "nuova" rete utilizzando tuttavia gli stessi campioni. Le modalit di addestramento sono varie e dipendono da molteplici fattori: da come viene intesa la funzione di errore tra uscita reale e quella della rete, dall'algoritmo di aggiornamento dei pesi delle connessioni, dal fatto di utilizzare un approccio incrementale, dove i pesi vengono modificati dopo l'esecuzione di ogni esempio, o un approccio post processing, in cui i pesi vengono modificati solo al termine di una epoca, vale a dire una sessione di allenamento completa sfruttando tutti gli esempi campione. Il toolbox permette di agire su tutti questi fattori e, come vedremo in seguito, ogni topologia di rete progettata dipende in parte dalla differenzazione di questi aspetti.

Modello del neurone


Il neurone l'unita fondamentale di una qualsiasi rete neurale. Esso schematizzato nella figura 1

Figura 1 - Schema di un neurone

In ingresso arrivano R valori di input, che possono essere o gli ingressi della rete qualora il neurone appartenga al primo livello della rete stessa, o le uscite degli R neuroni presenti nel livello precedente qualora il neurone in questione faccia parte di un livello intermedio ( o finale ). Di questi input si effettua una sommatoria pesata con i valori delle connessioni che portano gli ingressi al neurone. A tale sommatoria si aggiunge un ulteriore costante opzionale ( se posta a zero ) denominata bias, interpretabile come un peso addizionale in riferimento ad un ingresso unitario. L'uscita della sommatoria il seguente valore:

p1*w1 + p2*w2 + .... + pR*wR + b

Questa quantit viene passata in ingresso ad una funzione modellatrice la cui uscita rappresenta l'output del neurone. Tale output, a seconda di come strutturata la rete, pu essere interpretato come un valore di uscita della rete stessa, se il neurone collocato nel suo ultimo livello, o un ingresso dei neuroni del livello successivo, se il neurone analizzato collocato su un livello intermedio. E' importante sottolineare come il neurone venga caratterizzato quasi esclusivamente dal tipo di funzione di trasferimento scelta. In figura 2 vengono mostrate le tre funzioni pi utilizzate: la funzione gradino, la funzione lineare y = x e la funzione sigmoidale. Da notare come, se si utilizza il gradino l'uscita di ogni neurone vincolata ad assumere solo due valori, 0 e 1; se si utilizza il sigmoide i valori di uscita variano in modo continuo ma in un range limitato dagli estremi 0 e 1 mentre nel caso lineare l'uscita puo' assumere qualsiasi valore. Nonostante tali funzioni siano direttamente implementate nel toolbox, nessuno ci vieta di inizializzare una funzione di trasferimento personalizzata per le nostre reti.

Figura 2 - Tre delle pi comuni funzioni di uscita di un neurone: il gradino, la retta n = a e il sigmoide

Architettura di una rete neurale


Due o pi neuroni appena analizzati posso essere combinati in un livello e una rete pu contenere uno o pi di questi livelli. Consideriamo prima di tutto una rete neurale ad un solo livello. Nella figura 3 viene mostrata la tipologia di questa semplice rete, con R ingressi e S neuroni.

Figura 3 - Schema di un livello neuronale

In questa rete, ogni elemento del vettore P di input connesso a ciascun neurone dell'unico livello attraverso un opportuno peso. Per convenzione si definisce Wij il peso della connessione che collega il j-esimo input ( Pj ) all' i-esimo neurone, con 1 < i < S e 1 < j < R. I neuroni sono accomunati dal fatto di ricevere in ingresso gli stessi valori. Questi tuttavia vengono pesati in maniera differente. Se si tiene presente che il bias e la funzione di trasferimento possono variare a seconda del neurone, l'uscita degli stessi risulta generalmente distinta. Essendo il numero dei neuroni pari ad S e dato che ogni neurone calcola un proprio valore di output, in uscita all'unica livello della rete avremo S valori. Una rete a pi livelli concettualmente analoga alla tipologia di rete appena vista. Analizziamola maggiormente in dettaglio facendo riferimento alla figura 4.

. Figura 4 - Schema di una rete neuronale a pi livelli Nella figura rappresentata una rete a 3 livelli. L'ultimo livello di una rete siffatta quello pi significativo. I primi due invece vengono definiti livelli nascosti in quanto le loro uscite non vengono direttamente osservate in output alla rete ma bens fungono da ingressi per il livello successivo. Il numero di neuroni di ogni livello generalmente differente. Se si definisce Si il numero di neuroni che compongono l' i-esimo livello, Si sar anche il numero di ingressi al livello successivo ( ossia il livello i + 1 ). Infatti, caratteristica di una rete neurale, che i collegamenti tra neuroni possono avvenire solo in avanti tra livelli adiacenti. Di conseguenza non possibile che un neurone riceva in ingresso un valore in uscita da un neurone che appartiene ad un livello diverso da quello precedente. Il numero di uscite di questa rete sar uguale a S3 cio al numero di neuroni presenti nel suo ultimo livello. E' molto comodo identificare i valori degli elementi di una rete mediante l'utilizzo della notazione matriciale. P il vettore colonna di dimensione Rx1 in ingresso alla rete neurale. I pesi vengono rappresentati da matrici Wij, dove convenzionalmente si utilizza l'indice i per identificare il livello di destinazione e l'indice j per quello di partenza. Per esempio, con W32 si rappresenta la matrice dei pesi che collegano le uscite dei neuroni del secondo livello con gli ingressi ai neuroni del terzo. Ogni matrice Wij ha ordine Si X Sj : in ogni riga k-esima sono presenti i pesi delle connessioni che collegano gli Sj neuroni del livello j al k-esimo neurone del livello i. La cosa potrebbe sembare complicata ma in realt molto comoda per esprimere in forma matriciale la computazione di una rete neurale anche molto complessa. Di fatto, la stessa rete a 3 livelli vista sopra, pu essere schematizzata nella figura 5:

Figura 5 - Schema di una rete neuronale a pi livelli con parametri in forma matriciale a1 l'uscita del primo livello della rete e viene calcolata applicando la funzione alla quantit IW11 * P + B1, dove IW11 la matrice dei pesi relativa al primo livello ( I sta per ingresso appunto, il primo indice 1 sta a indicare che il livello di destinazione il primo mentre il secondo indice 1 relativo al livello precedente, che in questo caso non esiste essendo il primo della rete ) di dimensione S1 xR, P il vettore colonna di dimensione R x 1 degli ingressi e B1 il vettore colonna di dimensione S1 x 1 contenente i bias degli S1 neuroni del primo livello. Facendo un breve calcolo sulla dimensione di a1, questo risulta essere un vettore colonna di dimensione S1 x 1 come infatti ovvio che sia ( un uscita per ogni neurone del livello 1 ). Analogo discorso viene portato avanti per tutti gli altri livelli. Tenendo presente la relazione che sussiste tra gli ingressi del livello K e le uscite del livello K-1, facile costruire una dipendenza diretta tra le uscite della rete ( a3 ) e il vettore degli ingressi alla rete stessa ( P ) mediante un'equazione matriciale che altrimenti sarebbe stata estremamente lunga da definire. Le reti a pi livelli sono sufficientemente potenti. Si consideri infatti che una rete a 2 livelli, il cui primo livello caratterizzato da una funzione sigmoidale e il secondo da una lineare, pu essere addestrata per approssimare arbitrariamente bene qualsiasi funzione con un numero finito di discontinuit.

Simulazione concorrente e simulazione sequenziale


In questo paragrafo verranno analizzati gli effetti della simulazione di una rete alla luce dei differenti formati dei dati che possono essere portati in ingresso. La pi semplice situazione di simulazione di una rete si presenta quando la rete stessa statica ( priva di ritardi sugli ingressi e di feedback degli stessi ). In questo caso non necessario stabilire nessun ordine sulla sequenza dei dati in ingresso che vengono di fatto trattati in modo concorrente. In pratica, se N sono i vettori P di dati da inserire, il risultato come se ci fossero N reti dello stesso tipo ma distinte che operano in parallelo simulando ognuna uno di questi N vettori. L'uscita in relazione a un certo ingresso viene calcolata in modo indipendente, come se gli altri N-1 dati non esistessero. Dato che l'intento quello di progettare reti con il Toolbox di Matlab, vediamo un semplice esempio esplicativo di questa situazione. Prima di tutto necessario creare un neurone. In questo caso si scelto un neurone con una funzione lineare. Il comando dedicato newlin che accetta come dati di ingresso nell'ordine: 1. una matrice Rx2 dove nell' i-esima riga sono indicati il minimo e il massimo valore che pu assumere l'i-esimo elemento del vettore di ingresso ( di dimensione Rx1 ). 2. il numero S di neuroni del livello 3. il fattore di ritardo 4. il fattore di apprendimento

Nel nostro semplice esempio abbiamo un singolo neurone ( S = 1 ) e due ingressi, mentre non sar necessario specificare n il ritardo n il tasso di apprendimento di cui discuteremo pi avanti. Supponendo che gli ingressi possano variare in una range [ -3 ; 3 ] la rete a un livello si costruisce in questo modo:

net = newlin( [ -3 3; -3 3 ], 1 );

Il passo successivo quello di settare i pesi delle connessioni e il valore del bias. Come abbiamo visto in precedenza necessario costruire una matrice Wij per i pesi delle connessioni tra il livello j e il livello successivo i. Ogni matrice sar di dimensione Si x Sj. La notazione del toolbox per richiamare ( in lettura e scrittura ) la matrice Wij la seguente: net.IW{1,1}nel caso si voglia referenziare la matrice dei pesi che collegano gli ingressi della rete al primo livello e net.LW{i,j} nel caso si voglia referenziare la matrice dei pesi che collega due livelli adiacenti intermedi. Una volta creata la rete ( denominata nell'esempio con net ), possibile visualizzare un elenco completo di tutti i suoi attributi semplicemento digitando il nome della rete stessa come se fosse un comando effettivo di Matlab. Nell'esempio la matrice IW dei pesi ha dimensione 1X2 ( 2 ingressi e 1 neurone di destinazione ), mentre il bias di indice 1 ( ossia il vettore colonna di bias riferito al primo livello ) sar un semplice scalare avendo a disposizione un unico neurone:

net.IW{1,1} = [ 1 2 ]; net.b{1} = 0;

Una simulazione avviene solo in corrispondenza di certi dati in ingresso. Se vogliamo simulare il comportamento di una rete in corrispondenza di N vettori di input distinti non necessario operare N simulazioni differenti. Tutto dipende da come si strutturano i dati da inserire nella rete. Se il vettore dei dati in ingresso ha dimensione Rx1 sufficiente creare una matrice P di ordine RxN. Nella colonna j-esima di tale matrice si leggono i valori degli ingressi del j-esimo vettore di input. E' importante sottolineare come in una rete a simulazione concorrente l'ordine delle colonne non significativo e tale matrice pu essere costruita come una qualunque permutazione dei vettori colonna di ingresso.Non ci resta ora che definire il comando per simulare il comportamento della rete net in relazione agli N vettori di input concatenati nella matrice P. Il comando matlab e sim( net, P ) e restituisce un vettore riga di dimensione 1xS dove S sono le uscite (una per ogni neurone ). P = [ 1 2 2 3; 2 1 3 1]; A = sim( net, P ); Nel caso avessimo a che fare con reti dinamiche, l'ordine in cui sono presentati i vettori di ingresso fondamentale. Questo accade particolarmente per le reti con ritardo, come illustrato in figura

Figura 6 - Rete dinamica a un solo ritardo Si tratta di una semplice rete neurale ad un singolo ritardo. Questo significa che l'uscita della rete in corrispondenza dell' i-esimo vettore di input viene calcolata utilizzando anche le informazioni contenute nel vettore di ingresso precedente ( i -1 ). In figura si enfatizza il legame tra i vettori degli

ingressi con il tempo discreto t, ma il significato rimane invariato. E' quindi facile comprendere come l'ordine relativo dei vettori input significativo. Ogni permutazione delle colonne della matrice P degli ingressi comporta generalmente un differente vettore riga di uscita dalla rete dopo la simulazione. Per realizzare una rete di questo tipo sufficiente riprendere i comandi analizzati in precedenza. Si costruisce sempre il solito livello lineare ad un neurone questa volta specificando anche il ritardo. Il settaggio dei pesi e del bias non cambia anche se bisogna sottolineare che la dimensione della matrice dei pesi dipende da quanti ritardi caratterizzata la rete. Nel nostro esempio consideriamo una rete con un solo ingresso e un ritardo. La matrice dei pesi avr quindi dimensione 1x2. In generale se D sono i ritardi, la matrice dei pesi ha dimensione1x(D+1). In pratica, anche se l'ingresso di questa rete un semplice scalare, l'effetto quello invece di un vettore di ingressi lungo D+1 in quanto il neurone riceve come input non solo l'ingresso effettivo ma anche i D ingressi precedenti. La matrice degli ingressi viene definita come un array di celle. Ogni cella un vettore di input e la sua posizione all'interno dell'array , ribadiamo, caratterizzazione fondamentale della simulazione neurale. Di fatto, anche l'uscita della simulazione un array di celle, ciascuna relativa al vettore input di riferimento.

net = newlin( [-3 3; 3 3 ], 1, [0 1] ); net.b{1} = 0; net.IW{1,1} = [ 1 2 ]; P = { [1] [2] [3] [4] }

Addestramento di una rete neurale


Affinch una rete neurale approssimi nella sua simulazione una certa funzione degli ingressi, necessario effettuare un lavoro graduale di aggiornamento dei vari pesi e dei bias mediante l'impiego di un certo numero di esempi predefiniti di cui si conosce esattamente l'output reale che la rete dovrebbe emettere in funzione dei rispettivi ingressi. Questa fase, successiva al progetto della rete, prende comunemente il nome di training. Gli algoritmi di addestramento sono numerosi: se la memoria occupata non una limitazione del nostro problema, il pi adatto in questo senso risulta essere il Levenberg-Marquardt, mentre l'algoritmo di backpropagation puro rimane sempre un ottima soluzione che integra velocit computazionale e risparmio di risorse. Non intenzione di questa trattazione analizzare tutti gli algoritmi esistenti in letteratura e implementati nel Neural Toolbox. Vi rimando al capitolo 5 del manuale del toolbox per una pi approfondita analisi. Ci basti sapere che per reti semplici possono essere utilizzati algoritmi non troppo elaborati ( come nei nostri esempi ). Le modalit di addestramento di una rete si suddividono in due classi fondamentali: incremental training e batch training.

Addestramento incrementale
La filosofia che sta alla base dell'allenamento incrementale quella di aggiornare i pesi e i bias della rete ogni volta che un vettore input del training set si presenta in ingresso alla rete stessa. Questa modalit, sebbene adattabile a tutte le tipologie di rete, maggiormente utilizzata per quelle dinamiche, come i filtri adattativi. Prendiamo in considerazione una banale rete di quelle trattate sino ad ora e vediamo come si procede in pratica all'addestramento della rete, secondo la modalit incrementale.

net = newlin( [ -1 1 ; -1 1 ], 1, 0, 0.1 ); net.IW{1,1} = [ 0 0 ]; net.b{1} = 0;

Dovrebbe essere tutto chiaro in quanto non stato introdotto nulla di nuovo. Si noti come il quarto parametro di ingresso alla funzione newlin sia il fattore di apprendimento che stato settato a 0.1.

Supponiamo di voler allenare una rete a due ingressi affinch simuli la seguente funzione

t = p1 + p2

e di avere un training set di 4 vettori. Allenando la rete in modalit incrementale, l'ordine con cui questi 4 vettori si presentano al suo ingresso determinante su come la rete stessa venga addestrata. Ricordando la notazione del toolbox su vettori di ingresso sequenziali, il training set P viene espresso mediante un array di celle e cos anche per le uscite predefinite T ( che si conoscono ) associate a ciascuno di questi ingressi:

P = { [ -1 ; 2 ] [ 2 ; 1 ] [ 2 ; 3 ] [ 3; 1 ] }; T = { 4 5 7 7 }; [ net, a, e ] = adapt( net, P, T );

Il comando per eseguire l'addestramento della rete il seguente:

Semplicemente si passa in ingresso alla funzione adapt la rete da addestrare e il training set ( la matrice P degli ingressi e quella T delle uscite ). Come parametri di uscita si ha: 1. la rete addestrata, con i nuovi valori di pesi e bias 2. il vettore a contenente le uscite della rete dopo l'addestramento in funzione degli ingressi del training set 3. il vettore e contenente gli errori tra l'uscita reale T e l'uscita della rete a Non infatti detto che dopo l'allenamento la rete riesca a trovare una corretta valutazione dei pesi e dei bias affinche tutto il training set si comporti come desiderato. Questo dipende da tanti fattori, non da meno la tipologia della rete, del training set, della funzione di trasferimento e via dicendo. Se realizzassimo questa semplice situazione con il toolbox noteremo infatti che il vettore a molto discordante dal vettore T.

Batch training
E' la modalit di addestramento della rete per la quale i pesi e i bias vengono modificati solo dopo che tutti gli esempi del training set sono stati utilizzati come ingressi alla rete stessa. Rispetto all'allenamento incrementale, dove era necessario costrutire il training set come una sequenza ordinata di esempi, la strutturazione dello stesso dipende dalla morfologia della rete. Di conseguenza se indichiamo con P il training set, questo sar un array di celle nel caso di reti dimaniche o una matrice nel caso di reti statiche. Nel breve esempio proposto in seguito viene mostrato come implementare il batch training di una rete statica.

net = newlin( [ -3 3; -3 3 ], 1, 0, 0.1 ); net.IW{1,1} = [ 0 0 ]; net.b{1} = 0; P = [ 1 2 2 3; 2 1 3 1 ]; T = [ 4 5 7 7 ]; net.train( net, P, T );

L'unica differenza con quanto abbiamo visto nell'allenamento incrementale l'utilizzo della funzione train al posto di adapt. Train accetta in ingresso la rete e il training set e aggiorna i pesi delle connessioni e i bias solo al termine dell'addestramento. Per verificare che i valori di questi elementi siano stati realmente modificati, sufficiente accedere ad essi in lettura con i comandi net.IW{1,1} e net.b{1}. E' possibile utilizzare ancora il comando adapt ma solo per il batch training di reti statiche. E' consigliabile comunque l'utilizzo di train che sfrutta algoritmi pi sofisticati. L'ultimo aspetto da sottolineare come, solitamente, il train usato nel modo descritto sopra, poco utile in quanto se

simuliamo la rete con il training set dopo l'addestramento noteremo che i valori in uscita sono assai diversi da quelli che ci aspettiamo. L'idea quella di iterare l'addestramento per un certo numero di volte ( epoche ) cosi' da raffinare sempre meglio i valori dei pesi e dei bias. Questa iterazione viene implementata automaticamente dalla funzione train settando il numero di epoche di allenamento:

net.trainParam.epochs = 10;

Si ricordi tuttavia che se una rete, per sua struttura, non in grado di implementare certe funzioni, anche aumentando a dismisura il numero di epoche non si avr mai la piena convergenza tra uscite di rete e uscite reali del training set. Banalmente se il training set costituito da questi due esempi:

P = [ 3 3 ]; T = [ 0 1 ];

nessuna rete sar in grado di addestrarsi in modo corretto in quanto non possibile che in relazione allo stesso input ( 3 ) si abbiano due uscite distinte ( 0 e 1 ). Altre situazioni analoghe verranno presentate quando affronteremo la tipologia di rete pi semplice ma pi solida, il percettrone.