Utilizzo di reti neurali di tipo MLP e RBF per problemi di

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