Esercitazione N°2 Data Fitting con Modelli Lineari Premessa: La regressione lineare rientra nel problema più generale dell’approssimazione di funzioni. Nel caso specifico, l’obiettivo è quello di individuare il legame funzionale lineare che rende minimo lo scarto da un insieme di punti campionato. L’ipotesi più importante che occorre formulare nella regressione è proprio il tipo di legame funzionale che si definisce. Il legame lineare, in genere, non consente di ottenere scarti molto bassi, ma il fatto di disporre di un modello lineare di un sistema è un sicuro vantaggio, quindi, ogni volta che risulta possibile, per effettuare una regressione, si preferisce utilizzare un legame lineare. L’obiettivo del calcolo è quello di definire i coefficienti della funzione lineare, che possono essere ricavati per via analitica, oppure con un algoritmo di ricerca, tipicamente basati sul gradiente. Questo secondo approccio è direttamente collegato all’apprendimento neurale. Esercizio 1 – Regressione lineare Una rete neurale come quella in figura: wi uscita S ingresso bias è un regressore lineare a tutti gli effetti. Infatti i coefficienti della funzione lineare sono dati dai pesi delle connessioni wi , mentre il termine costante è dato dal peso della connessione con il nodo di bias. Utilizziamo a questo scopo il tool neurale di Matlab. Avviamo NNTool. Tramite l’interfaccia grafica costruiamo una rete neurale formata da un solo neurone lineare, avente un solo ingresso. Di seguito è riportata la finestra per la definizione di tale rete. Ci poniamo l’obiettivo di costruire una rete per fare la regressione dei seguenti campioni: IN: [1 2 3 4 5 6 7 8 9 10 11 12] OUT:[1.72 1.9 1.57 1.83 2.13 1.66 2.05 2.23 2.89 3.04 2.72 3.18] Con le seguenti istruzioni di Matlab: >>y=[1.72 1.9 1.57 1.83 2.13 1.66 2.05 2.23 2.89 3.04 2.72 3.18]; >> plot(y,’*’) visualizziamo il grafico dei punti su cui vogliamo fare la regressione lineare. Tornando alla finestra per la costruzione della rete neurale, con il tasto View possiamo visualizzare una rappresentazione grafica della rete. Con il comando Create creiamo una nuova rete nello spazio di lavoro di NNTool. L’opzione (design) nella definizione della rete, fa sì che i pesi della rete corrispondano alla soluzione analitica del problema. Per visualizzare le prestazioni della rete, calcoliamo le uscite in corrispondenza dei valori di IN. Allo scopo, dalla finestra principale, clicchiamo il pulsante New Data… e inseriamo una riga con i numeri interi tra 1 e 12. Nel campo Data Type specifichiamo che si tratta di ingressi. Con il pulsante Create creiamo questo vettore nello spazio di lavoro di NNTool. A questo punto, dalla finestra principale, selezioniamo la rete neurale e clicchiamo su Simulate… Appare la seguente finestra: nella quale indichiamo che come input si deve utilizzare il vettore degli ingressi che abbiamo appena creato. Con il pulsante Simulate Network calcoliamo l’uscita in corrispondenza degli ingressi. L’esito di questo calcolo viene memorizzato nella variabile il cui nome si trova nel campo Outputs. Per visualizzare le uscite della rete esportiamo la variabile delle uscite, appena creata, nello spazio di lavoro di Matlab. Allo scopo clicchiamo sul pulsante Export… nella finestra principale di NNTool. A questo punto possiamo visualizzare come la rete neurale che effettua la regressione lineare approssima la sequenza data dei campioni. Fissiamo la figura precedente, in modo da sovrapporre nella stessa immagine i campioni e la regressione operata dalla rete Modificando i pesi delle connessioni, otteniamo rette che effettuano un’approssimazione meno efficiente della sequenza di punti. Nella finestra principale di NNTool selezioniamo la rete creata in precedenza e poi clicchiamo il pulsante View. Selezioniamo, quindi, la form Weigths. >> hold on >> plot(network1_outputs) La retta coincide con la soluzione analitica. Tramite il menù a tendina accediamo ai vari gruppi di connessioni della rete, in questo caso solo due gruppi di una connessione ciascuno. Imponiamo, successivamente, le seguenti combinazioni di pesi, effettuando, ogni volta, la simulazione della rete, e salvando il risultato in una nuova variabile: w=1 w = -1 w = 0,5 w=1 b=1 b=1 b=2 b = -1 Ogni modifica, per essere operativa, richiede la pressione del tasto Set Weight. Nella finestra principale di NNTool appaiono, nel campo Outputs:, le uscite della rete in corrispondenza delle 4 diverse combinazioni dei pesi. Le esportiamo nello spazio di lavoro di Matlab per diagrammarle insieme al risultato precedente. Verifichiamo la presenza di tali variabili con il solito comando: >> whos Con il seguente risultato: Name Size network1_out1 network1_out2 network1_out3 network1_out4 network1_outputs y 1x12 Bytes Class 1x12 1x12 1x12 1x12 1x12 96 double array 96 double array 96 double array 96 double array 96 double array 96 double array Grand total is 72 elements using 576 bytes Se la figura precedente è ancora attiva, con i seguenti comandi possiamo diagrammare nella stessa figura le rette corrispondenti alle quattro nuove soluzioni. >> hold on >> plot(network1_out1,'r') >> plot(network1_out2,'g') >> plot(network1_out3,'k') >> plot(network1_out4,'m') % rosso % verde % nero % magenta Al di là della percezione visiva, abbiamo bisogno di un criterio analitico per affermare che la retta blu sia quella che effettua la migliore approssimazione. Questo criterio è l’errore quadratico medio, su cui si basa la determinazione analitica della retta che meglio si adatta ai punti (best fit). Calcoliamo questi errori nello spazio di lavoro di Matlab: >> [ mse(y-network1_outputs) mse(y-network1_out1) mse(y-network1_out2) mse(y-network1_out3) mse(y-network1_out4)] Si può notare che la soluzione analitica (in blu) è quella che assicura la migliore approssimazione. Il risultato è il seguente: 0.0672 36.5362 75.4829 10.6612 19.5096 Esercizio 2 – Superficie di Prestazione Nell’esercizio precedente abbiamo visto come si può utilizzare una rete neurale per creare un regressore lineare. Abbiamo anche visto che la retta di regressione dipende dal peso delle connessioni, e che se si assegnano pesi uguali alla soluzione trovata analiticamente, si ottiene un valore minimo dell’errore quadratico medio, calcolato in corrispondenza dei campioni. In generale si parla di “Superficie di Prestazione” intendendo il legame funzionale tra i pesi delle connessioni e il criterio di errore, nel caso esaminato l’errore quadratico medio. Tale superficie, per la rete dell’Es.1, è una funzione del tipo: e = e(w, b) quindi suscettibile di una rappresentazione nello spazio R 3. Vogliamo descrivere questa superficie. A questo scopo dobbiamo far variare parametricamente i pesi delle connessioni e, per ciascuna combinazione, calcolare l’errore commesso rispetto ai campioni. Ricreiamo la rete utilizzata nell’esercizio precedente (v.) ed esportiamola nello spazio di lavoro di Matlab. Per poter agire più comodamente sulle connessioni, vi accediamo nell’ambiente di Matlab. Digitando il nome della rete: >> network1 visualizziamo i campi della rete. Per accedere al contenuto di un campo digitiamo il nome della rete e del campo, separati da un punto. Per esempio: >> network1.numInputs visualizza il numero di ingressi alla rete. Alcuni campi sono delle strutture di celle, riconoscibili dal fatto che nell’architettura le dimensioni sono indicate tra parentesi graffe In particolare siamo interessati ai pesi delle connessioni. I campi relativi sono: >> network1.IW >> network1.LW >> network1.b % pesi del primo strato % pesi del secondo strato % valori di bias Trattandosi di variabili strutturate, per accedere al loro contenuto, indichiamo tra parentesi graffe la cella della quale vogliamo visualizzare o modificare il contenuto: >> network1.IW{1} ans = 0.1389 A parte l’uso delle parentesi graffe, anziché quelle tonde, le modalità di accesso alle celle di una struttura sono le stesse di quelle con le quali si accede agli elementi di una matrice. Attraverso un doppio ciclo iterativo, calcoliamo le uscite della rete in corrispondenza di una griglia di punti nel piano (w, b). Allo scopo inseriamo le istruzioni nel seguente script di Matlab: function e = suppres(net,in,tgt); i=0; w = 0:0.01:0.5; %peso della connessione w b = 1:0.01:1.5; %valore del bias for i = 1:length(w) net.IW{1} = w(i); for j = 1:length(b) net.b{1} = b(j); %errore quadratico medio: e(i,j)=mse(tgt-sim(net,in)); end end mesh(w,b,e); %grafico dell'errore Queste istruzioni devono essere riportate in un file di nome suppres.m, nella directory attuale di Matlab, che si avvia con il seguente comando dal prompt: Nell’esempio è stata esplorata un’area del piano (w , b) in cui già sapevamo essere compreso il punto di minimo. La funzione visualizza il seguente grafico: e = suppres(net,in,tgt); La funzione che abbiamo creato richiede come parametri la rete neurale (net) per la quale calcolare la superficie di prestazione, gli ingressi (in) in corrispondenza dei quali calcolare le uscite della rete, i valori dei campioni (tgt) rispetto ai quali calcolare l’errore quadratico medio. La simulazione della rete si effettua con il comando: >> y = sim(net,in); Che richiede, come parametri, la rete neurale e gli ingressi. L’errore quadratico medio si calcola con la funzione: >> e = mse(y - tgt); dove y e tgt sono due vettori. 8 6 4 2 0 1.8 1.6 0.5 0.4 1.4 0.3 0.2 1.2 1 0.1 0 Premendo il pulsante per la rotazione 3D è possibile cambiare il punto di vista. Esercizio 3 – Adattamento con l’algoritmo LMS Il calcolo della rete di cui agli esercizi precedenti può essere addestrata con un algoritmo di ricerca del minimo dell’errore per approssimazioni successive. Con NNTool creiamo una rete simile a quella degli esercizi precedenti: Notiamo che questa volta selezioniamo la versione (train) dello strato lineare, e questo comporta la necessità di fornire un diverso insieme di dati per la definizione. Tra gli altri notiamo in particolare il tasso di apprendimento. Premere il pulsante Create per costruire la rete. Ora occorre definire gli ingressi e le uscite desiderate della rete. Dalla finestra principale di NNTool premiamo il pulsante New Data… Definiamo quindi i due vettori degli ingressi: ingressi = [1 2 3 4 5 6 7 8 9 10 11 12] Con il pulsante Train Network avviamo l’apprendimento: e delle uscite desiderate: uscdes = [1.72 1.9 1.57 1.83 2.13 1.66 2.05 2.23 2.89 3.04 2.72 3.18] A questo punto possiamo procedere con l’addestramento. Dalla finestra principale di NNTool selezioniamo la rete e premiamo il pulsante Train… Negli appositi campi indichiamo i dati da utilizzare come ingressi e come target durante l’apprendimento. Gli altri parametri di apprendimento sono stati fissati prima. Apparirà automaticamente il grafico dell’andamento dell’errore quadratico medio delle uscite della rete rispetto a uscdes. Dalla form Weights rileviamo che i pesi finali valgono: w = 0.142 b = 1.314 molto prossimi alla soluzione analitica. Lo studente valuti l’influenza del tasso di apprendimento sull’andamento dell’errore. Esercizio 4 – Regressione Multipla Vediamo, infine, un esempio in cui i punti sono definiti in uno spazio di 2 dimensioni. Anziché utilizzare il tool grafico, ci serviamo dei comandi del prompt di Matlab. Assegnamo alla matrice xy e al vettore z, rispettivamente, gli ingressi e le uscite desiderate riportate a lato. Per creare lo strato lineare in modalità (train) usiamo il comando: >> net = newlin(PR,S,ID,LR) dove: PR = range degli ingressi S = numero di neuroni di uscita ID = ritardi nello strato di ingresso LR = tasso di apprendimento Nel caso in esame: >> net = newlin([0 1; 0 1], 1, [0], 0.001); 1) 2) 3) 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) 17) 18) 19) 20) 21) 22) ingressi 0.9501 0.2311 0.6068 0.4860 0.8913 0.7621 0.4565 0.0185 0.8214 0.4447 0.6154 0.7919 0.9218 0.7382 0.1763 0.4057 0.9355 0.9169 0.4103 0.8936 0.0579 0.3529 0.8132 0.0099 0.1389 0.2028 0.1987 0.6038 0.2722 0.1988 0.0153 0.7468 0.4451 0.9318 0.4660 0.4186 0.8462 0.5252 0.2026 0.6721 0.8381 0.0196 0.6813 0.3795 uscdes 3.9389 2.2061 2.4105 2.9089 2.9134 1.4044 2.4586 1.1510 2.0747 0.6050 0.8217 4.0544 1.4854 0.7587 1.9903 -0.2024 0.6051 2.0313 2.8901 0.5566 4.1289 2.7272 Possiamo procedere con l’addestramento: >> net.trainParam.epochs = 4000; >> net.trainParam.goal = 0.001; >> init(net); >> net = train(net,xy,z); La costruzione della rete corrispondente alla soluzione analitica (modalità design) si effettua con il seguente comando: >> net = newlind(P,T,Pi); dove: P = matrice degli ingressi T = uscite desiderate Pi = ritardi nello strato di ingresso Nel caso in esame: >> netd = newlind(xy,z); E’ interessante confrontare i pesi finali che si ottengono con le due istruzioni: w L’errore quadratico medio si stabilizza ad un valore di poco inferiore a 2*10-3 net b 3.0032 -2.5464 1.6351 netd 3.0018 -2.5487 1.6370