Utilizzo di reti neurali di tipo MLP e RBF per problemi di classificazione: riconoscimento di forme geometriche piane descritte da un insieme di coppie (x, y) Davide Anastasia, Nicola Cogotti 10 novembre 2005 1 Descrizione del problema rumore, in cui gli 8 punti sono scelti casualmente all’interno della forma). Le varie forme sono locaIn questa esercitazione si intendono utilizzare le re- lizzate all’interno di un quadrato 10000x10000. Il ti neurali di tipo Multi-Layer Perceptron (MLP) e file “forme.xls” contiene 2000 campioni per ciascuRadiai Basis Function (RBF) per risolvere problemi na delle 6 forme bi-dimensionali, per un totale di di classificazione. Si supponga di avere, disposte su 12000 campioni. I campioni sono disposti nel file di un piano, varie forme geometriche regolari (esem- in ordine casuale. pio: cerchio, quadrato, ecc) e varie forme irregolari Ogni riga del file, corrispondente ad un (rumore), di diversa grandezza e posizionate in zo- campione, contiene i seguenti 25 campi numerici: ne arbitrarie. Obiettivo dell’esercitazione è quello • ID: numero d’ordine della riga (da 1 a 12000); di progettare una rete MLP e una rete RBF, capaci di classificare le forme (tipo di forma o rumore). Si • ID forma: identificatore della forma (1=cerconfrontino le performance delle due reti, al variare chio, 2=quadrato, 3=triangolo, 4=dianiante, dei rispettivi parametri di progetto. 5=linea, 6=rumore); 1.1 Descrizione dei dati da classificare • cerchio: =1 se si tratta di cerchio, O altrimenti; II dati contenenti la descrizione delle fonne da classificare sono contenuti nel file “forme.xls”. Tale file contiene le seguenti forme (il rumore viene considerato anch’esso come una forma): • quadrato: =1 se si tratta di quadrato, O altrimenti; • triangolo: =1 se si tratta di triangolo, O altrimenti; 1. cerchio; • diamante: =1 se si tratta di diamante, O altrimenti; 2. quadrato; 3. triangolo (equilatero); • linea: =1 se si tratta di linea, O altrimenti; 4. diamante (quadrato ruotato di 45 gradi); • rumore: =1 se si tratta di rumore, O altrimenti; 5. linea (orizzontale); • larghezza: dimensione orizzontale della forma (da 100 a 1000); 6. rumore (8 punti scelti a caso). Ogni forma ha una larghezza compresa tra 100 e 1000, ed è descritta mediante 8 punti scelti in senso orario lungo il suo perimetro (escluso nel caso di • X1, Y1: coordinate del punto centrale più a sinistra 1 Ora abbiamo gli indici che utilizzeremo per creare il nostro insieme di addestramento, abbiamo selezionato le 2500 righe della matrice data con questi indici e tutte le colonne come mostrato di seguito: • X2, Y2,. . . , X8, Y8: coordinate degli altri punti localizzati in senso orario sul perimetro della forma (il rumore è localizzato in maniera casuale all’interno della forma). ingresso = data(randomindex1, :); NB: II file di Excel può essere caricato in Matlab mediante la seguente istruzione: [data, labels] = xlsread(forme.xls’); 2 Da questa matrice, chiamata ingresso, selezioniamo solo gli elementi logicamente collegati tra di loro (ovvero solo le coordinate delle figure che la nostra rete dovrà riconoscere): Soluzione del problema lset = ingresso(:, 10:25); 2.1 Soluzione basata sulla rete MLP Successivamente si è reso necessario fare la trasposizione di questa matrice. Dalla matrice denominata ingresso si sono selezionati i target necessari per l’addestramento della rete in maniera analoga a quello che si era fatto precedentemente ma selezionando le colonne che vanno dalla 3 alla 8 e successivamente si è eseguita la trasposizione della stessa. Creazione della rete MLP Come primo passo si è aperto il file che è stato fornito contenente i dati da elaborare al fine di avere una prima visione dei dati e per capire come fossero organizzati all’interno del file. Successivamente si è utilizzata la funzione xlsread, che consente di caricare i dati da un file .xls in Matlab mediante la seguente linea di comando: target = ingresso( :, 3:8); targettras=target’; [data, labels] = xlsread(xforme.xls’); Abbiamo cosi ottenuto tutto quello che ci occorre per procedere alla creazione e all’addestramento della rete MLP. Questa funzione carica i dati contenuti nel file “forme” i cui valori numerici vengono caricati nella matrice data mentre le etichette vengono salvate nella matrice labels. Dopo aver fatto questo si è scelto di selzionare in maniera random 2500 campioni da dare alla rete come set di addestramento. Per fare questo si sono create 2 variabili, N e k, che indicassero il numero di campioni e il numero di neuroni rispettivamente. Descrizione della rete MLP Per strutturare la rete MLP si è deciso di utilizzare 8 neuroni nello strato nascosto e 6 neuroni nello stato di uscita (uno ogni figura che la rete à chiamata a riconoscere). I neuroni d’uscita hanno una funzione di tipo tansig, mentre quelli nello strato nascosto hanno una funzione di tipo logsig. Benché si siano usate diverse configurazioni in questo abito non si sono notate differenze particolarmente significative. Discorso diverso, invece, va fatto riguardo la funzione scelta per l’addestramento. Inizialmente, infatti, si era optato per l’uso della funzione trainrp in quanto questa avrebbe dovuto, almeno in teoria, offrire diversi vantaggi come: N = [2500]; %numero di campioni k = [6]; %numero di neuroni massimi della rete RBF Per selezionare in maniera random i 2500 campioni si è fatto uso della funzione Matlab random che genera 2500 numeri casuali con distribuzione uniforme in un range che va da 1 a 12000 (il range è stato scelto in base alla dimensione della matrice data che è di 12000 righe). Tali numeri sono stati salvati in un vettore colonna come mostrato di seguito. • Limitare i problemi derivanti dall’ordine di grandezza delle componenti del gradiente che tendono ad annullarsi quando i neuroni sono prossimi alla saturazione; randomindex = random(’unif’, 1, 12000, N(1), 1); Dovendo essere usati come indici di una matrice si è reso necessario l’uso di una funzione che rendesse gli indici generati da random interi. Per ottenere questo si è usato round: • Utilizzare solo l’informazione sul segno delle singole derivate per determinare la direzione della variazione dei pesi della rete; randomindex1 = round(randomindex); 2 • Attenuare le difficoltà di apprendimento derivate dalla diversa dimensione delle figure proposte alla rete. sufficiente ad addestrarla correttamente e che quindi essa non sia in grado di settare i pesi in modo adeguato per il riconoscimento delle figure che verranno poi presentate nella fase di test; con la seconda soluzione esiste il problema inverso, ovvero che la rete impari troppo bene il set di addestramento e non sia in grado di generalizzare bene quando le verranno presentati campioni differenti a quelli usati nell’addestramento. Come descritto prima noi abbiamo costruito un insieme di dati per l’addestramento che risulta essere composto di 2500 campioni (circa il 28% del numero totale di campioni) avendo constatato dopo numerose prove che questi erano sufficienti alla rete per essere addestrata. Si è, quindi, “privileggiato” l’insieme di test che verrà usato per la fase di testing della rete. Per quanto riguarda i parametri dell’addestramento si è provato a simulare la rete provando un diverso numero di epoche e diversi valori del parametro di stop (il goal). Come mostrato dal grafico seguente con le scelte fatte si sono ottenuti ottimi risultati della rete. In realtà, però, l’uso di questa funzione di addestramento si è dimostrata non molto efficace in un numero abbastanza elevato di situazioni, facendoci quindi optare per una nuova scelta. La funzione di addestramento scelta alla fine è stata la trainlm, che si è dimostrata essere la migliore sia sul piano dei risultati sia su quello della velocità di addestramento della rete. Anche con un numero di epoche relativamente basso e con un numero di neuroni nello strato nascosto molto basso1 la rete lavora correttamente. Di seguito viene mostrato il codice usato per la creazione della rete: net = newff(minmax(mm), [8 6], {’tansig’ ’logsig’}, ’ trainlm’); net = init(net); Una volta creata la rete si è potuto procedere con il settaggio dei parametri di addestramento e l’addestramento vero e proprio. Addestramento della rete MLP Inizialmente si sono avuti problemi con l’addestramento della rete, dovuti al fatto che il numero di campioni presentati nell’addestramento erano troppo pochi. La scelta del numero dei campioni da presentare alla rete durante l’addestramento può, infatti, seguire due correnti di pensiero: 1. Si può scegliere di presentare un numero di campioni di addestramento alla rete relativamente piccolo in modo da “conservare” un insieme di campioni più grande da utilizzare nella fase di simulazione (o test); Figura 1: Risultato addestramento rete MLP 2. Al contrario della precedente, presentare alla rete un numero relativamente grande alla rete Vengono ora mostrati i settagli dei parametri per di campioni durante l’addestramento e riserval’addestramento della rete: re un numero relativamente piccolo per la fase di test. net.trainParam.goal = 0.001; net.trainParam.epochs = 1000; Entrambe le soluzioni presentano vantaggi e svantaggi: con la prima scelta si corre il rischio che il numero di campioni presentato alla rete non sia La fase di testing della rete La scelta dell’insieme di test è cruciale per verificare la bontà della rete. In particolare l’insieme di test deve avere tre caratteristiche fondamentali che sono: 1 la rete è stata testata con un numero diverso di neuroni nello strato nascosto mostrando che anche con soli 6 neuroni si ottengono buoni risultati 3 • Il contenuto dell’insieme deve avere una parentela con il contenuto dell’insieme usato per la fase di addestramento (per parentela si intende una correlazione logica tra i dati contenuti nei due insiemi); % numero uguale a 0 if randomindex2 (j)==0 || randomindex(j)>12000 % se si verifica uno dei due casi visti sopra calcolo un nuovo % numero in maniera random • Sia l’insieme di test che l’insieme di training devono essere dei dati rappresentativi di ciò che la rete sarà chiamata ad affrontare nell’applicazione reale; randomindex2 (j)= random (’unif’,1,12000,1,1); end end • L’insieme dei dati di test deve essere diverso da quello presentato nella fase di addestramento per evitare che la rete impari mnemonicamente i dati e quindi che perda la capacitá di generalizzazione. Simulazione della rete MLP Ottenuto cosı̀ l’insieme di test si potuto procedere con la simulazione della rete utilizzando la funzione del Matlab sim, utilizzando il seguente codice: Per soddisfare le proprietà sopra elencate si è cercato di generare un insieme di test che fosse sicuramente diverso da quello di training. Si è scelto, inoltre, di non usare tutti i dati disponibili per il test, riservandone una parte per un altro eventuale insieme che può essere utilizzato per simulare una applicazione reale della rete addestrata e testata. Nulla vieta, tuttavia, di apportare una semplicissima modifica al codice sorgente per fare in modo che vengano selezionati tutti i dati non utilizzati nell’addestramento (questo è ottenibile con una semplice modifica del ciclo for che andremo a descrivere in seguito). Di seguito verrà mostrato il codice usato per la selezione dell’insieme di test. randomindextest = round (randomindex2’); appoggio = data( randomindextest, :); testset = appoggio (:, 10:25); % simulo y ts mlp = sim (net, testset’); 2.2 Realizzazione della rete neurale RBF e conclusioni Per quanto riguarda la realizzazione della rete neurale RBF sostanzialmente si è riusato lo stesso codice creato per la rete neurale di tipo MLP relativo alla generazione delle matrici utilizzate per l’addestramento e per il test. Durante la realizzazione della rete neurale di Breve descrizione del codice Esso consiste in un ciclo for che va da 1 al numero di campioni tipo RBF, tuttavia, si sono incontrate maggiori scelto per l’insieme di test, a ogni iterazione del difficoltà. Per ottenere risultati simili a quelli ottenuti con ciclo semplicemente si somma 1 all’insieme usato precedentemente per la fase di training essendo cosı̀ la rete neurale di tipo MLP, infatti, si è dovuto sicuri che gli indici non potranno mai essere uguali optare per una struttura della rete diversa. In partra i due insiemi. Infine si svolge un controllo per ticolare si è dovuto aumentare il numero di neuroni essere sicuri che non vengano generati indici che nello strato nascosto e sono state necessari numeeccedano la matrice: se questo avviene si genera un rosi tentativi per determinare il valore ottimale del nuovo numero random con distribuzione uniforme parametro di spread (per la trattazione di questo parametro si rimanda alla relazione del laboratosu un intervallo da 1 a 12000. rio 1 - pag. 3). Si è notato che con l’aumentare di questo valore, l’accuratezza della rete aumentafor j =1 : N(1) va notevolmente fino a stabilizzarsi o a migliorare %in questo modo sono sicuro che non verra mai poco significativamente. Da quanto visto e appreso generato un numero uguale %al caso precedente durante il l’esercitazione 1, in base al dimensionarandomindex2 (j) = randomindex (j) +1; mento dello spread si è reso necessario dimensionare il numero di neuroni nello strato nascosto della re% controllo di non eccedere il numero delle righe o di te. È questo, infatti, il caso in cui la rete ha a che generare un 4 Con 2500 campioni la rete è mediamente in grado di riconoscerne percentuali vicine al 90%. Il grafico relativo al training prodotto da Matlab non risulta particolarmente significativo ai fini della valutazione della rete, ma ne mostriamo comunque l’andamento. fare con dati che variano molto l’uno dall’altro (per posizione delle figure nel piano e per la dimensione delle stesse). Risulta quindi necessario utilizzare uno spread relativamente elevato abbinato ad un numero di neuroni nello strato nascosto elevato. Una volta determinato il numero di neuroni e il valore di spread più appropriato, rispetto alla situazione in cui la rete si trovava ad operare, si sono ottenuti risultati molto vicini a quelli della rete MLP con l’unica differenza (non banale) che, per quanto detto sopra, la rete RBF risultava molto più complessa della MLP (un numero maggiore di neuroni e di pesi), molto più lenta (conseguenza diretta della maggiore complessità della rete stessa) e, fattore da non sottovalutare, necessitava di un numero maggiore di campioni per essere addestrata in maniera soddisfacente (questo perché avendo una maggiore complessità rispetto alla MLP necessita di un numero molto più elevato di campioni per aggiustare e determinare il valore dei pesi più appropriato). Concludendo, benché i risultati finali siano molto vicini la rete MLP, quest’ultima è risultata molto più performante ed efficace rispetto alla rete neurale RBF in questa particolare applicazione. Performance is 940.382, Goal is 0.01 4 10 3 10 Training−Blue Goal−Black 2 10 1 10 0 10 −1 10 −2 10 −3 10 0 5 10 15 20 40 Epochs 25 30 35 40 Figura 2: Risultato addestramento rete RBF Codice RBF Per completezza viene riportato il codice della RBF. Determinazione dell’accuratezza Per determinare l’accuratezza della rete RBF si è usato, come verrà mostrato nel seguito, un metodo per determinare quanti campioni la rete riuscisse a riconoscere su quelli mostrati. Questo metodo di misurare l’errore si è rilevato indispensabile in quanto il grafico prodotto da Matlab durante il training (che verrà mostrato successivamente) non era significativo per la valutazione delle prestazioni della rete RBF. Come si potrà notare, infatti, benché il grafico mostri che la performance della rete sia molto scarsa, la variabile check rileva che la rete riesce a riconoscere mediamente il 90% dei campioni presentati. Il codice usato per calcolare la variabile check è: N = [2500]; %numero di campioni k = [40]; %numero di neuroni massimi della rete RBF randomindex = random(’unif’, 1, 12000, N(1) ,1); % rendo i numeri interi mediante la funzione round randomindex1 = round(randomindex); % utilizzo i numeri cosi calcolati come indici delle righe della matrice % data per selezionarmi un campione di ingresso per l’ addestramento ingresso = data(randomindex1, :); % da questo campione ”scremo” i dati utili da quelli non utili lset = ingresso(:, 10:25); % ora seleziono dalla matrice ingresso i target che mi servono % nell’addestramento target = ingresso(:, 3:8); check = [0]; %controllo del test set for n = 1 : N(1) % sostituire N(1) con 12000 per avere tutto l’insieme if result(n, :) == target ts(n, :) check(1) = check(1) + 1; % verifico quanti campioni riesce a riconoscere end end net = newrb(lset’, target’, 0.01, 45000, k(1), 5); % costruisco un insieme di test per la rete diverso da quello usato per addestrarla % che verra usato successivamente per il test for j =1 : N(1) check 5 %in questo modo sono sicuro che non verra mai generato un numero uguale %al caso precedente randomindex2 (j) = randomindex (j) +1; % controllo di non eccedere il numero delle righe o di generare un % numero uguale a 0 if randomindex2 (j)==0 || randomindex(j)>12000 % se si verifica uno dei due casi visti sopra calcolo un nuovo % numero in maniera random randomindex2 (j)= random (’unif’,1,12000,1,1); end end % come sopra mi seleziono la matrice per il test randomindextest = round(randomindex2’); appoggio = data(randomindextest, :); % Da tutta la matrice dei punti possibili come test set % %testset = data(:, 10:25); %target ts = data(:, 3:8); testset = appoggio(:, 10:25); % insieme di test diverso da quello di train target ts = appoggio(:, 3:8); % simulo y ts rbf = sim (net, testset’); result = compet(y ts rbf)’; check = [0]; %controllo del test set for n = 1 : N(1) % sostituire N(1) con 12000 per avere tutto l’insieme if result(n, :) == target ts(n, :) check(1) = check(1) + 1; % verifico quanti campioni riesce a riconoscere end end check 6