LUCRARE DE LABORATOR NR. 5
SIMULAREA SOFTWARE
A RETELELOR NEURONALE MLP ( II )
1. SCOPUL LUCRARII
In aceasta lucrare se studiaza o retea neuronala multi-layer perceptron ( MLP ), antrenata pentru recunoasterea de forme, care are intrari analogice. Reteaua este antrenata cu sabloanele salvate intr-un fisier text, dupa care ea este testata cu date de intrare noi, diferite de cele pe care le-a invatat. De asemenea, se studiaza caracteristicile generale ale simulatoarelor de retele neuronale.
2. BREVIAR TEORETIC
In general, o retea neuronala poate fi implementata in trei moduri distincte:
-simulata soft, pe un calculator secvential
-simulata soft pe un calculator paralel (un sistem cu mai multe procesoare)
-implementata hard
In privinta utilizarii simulatoarelor, pentru rezolvarea unei aplicatii concrete, trebuie avute in vedere urmatoarele aspecte:
-Alegerea tipului de retea neuronala
Majoritatea retelelor neuronale utilizate practic sunt de tipul perceptron multistrat ( MLP ) si utilizeaza algoritmul de backpropagation pentru invatare. Algoritmul de backpropagation foloseste eroarea intre iesirile actuale (rezultate prin calcul, propagand inainte valorile de pe intrari, specificate de sabloane) si iesirile asteptate (cele impuse de sablonul curent), pentru a ajusta fiecare pondere. Ajustarea ponderilor se face secvential, plecand de la ultimul strat (cel de iesire), spre primul strat (cel de intrare).
-Alegerea intrarilor (numarul si tipul lor)
In general alegerea intrarilor este o problema dificila. Iesirile retelei sunt mai clar impuse de problema concreta analizata, pe cand intrarile nu. O regula empirica de alegere a intrarilor este urmatoarea: 'cu cat mai multe date, cu atat mai bine!' Aceasta regula se aplica atat la numarul intrarilor unei retele, ca si la numarul sabloanelor de antrenare.
Intrarile suplimentare nu afecteaza acuratetea rezultatelor furnizate de retea in problema concreta rezolvata, chiar daca anumite intrari se dovedesc a fi neimportante in determinarea iesirii corecte. Totusi, toate simulatoarele au o limita superioara de neuroni pe care-i suporta, si deci si de intrari.
Trebuie ca atunci cand se strang date si se definesc intrarile retelei, sa nu se furnizeze retelei 2 vectori similari de intrari, care sa dea la iesire rezultate conflictuale. Spre exemplu, o retea ce recunoaste diverse fructe, ar putea sa identifice 'mar' sau 'pruna' (deci conflictual), bazat pe intrarile 'rotund' si 'rosu'. Pentru a rezolva conflictul, trebuie introduse intrari aditionale marime, gust, etc.).
La fel de importanta ca si strangerea unui numar suficient de date de intrare este si modalitatea de prezentare a acestora, retelei. Marea majoritate a simulatoarelor existente accepta intrari ce variaza intre 0 si 1, sau intre -1 si +1. De aceea, datele reale trebuie sa fie preprocesate pentru a fi aduse in aceasta gama. Cele mai multe simulatoare realizeaza chiar ele aceasta preprocesare. Modul cum se aleg intrarile semnificative pentru retea si modul de setare al parametrilor in simulator, au drept rezultat obtinerea unei retele neuronale performante sau nu.
Se pot utiliza 2 tipuri de baza pentru intrari in retele neuronale:
-intrari booleene (de tipul TRUE/FALSE)
Astfel, pentru o imagine alb-negru ce trebuie recunoscuta de retea, intrarile ( "0" - pixel alb, "1" - pixel negru ) sunt de tip boolean. Aceste intrari se mai cheama si intrari binare.
-intrari analogice sunt cele care iau valori continue intre o valoare minima si una maxima. De exemplu, intre 0 si 1. Pentru datele de pe intrari de tip analogic, se recomanda ca gama lor de variatie sa nu fie prea mare (diferenta intre valoarea maxima asteptata si valoarea minima asteptata). In acest scop, daca o intrare analogica are o plaja mare de valori, poate fi eventual inlocuita cu o alta intrare ce foloseste diferenta intre valoarea analogica curenta si cea anterioara. In acest fel, aplicand diferenta, gama scade.
Cele mai multe retele ce rezolva probleme reale au atat intrari binare cat si intrari analogice. Tipul de intrare folosit (binara sau analogica) poate afecta performantele retelei.
Numarul de intrari corespunde numarului de neuroni din stratul de intrare.
-Alegerea iesirilor
In general, numarul iesirilor este direct impus de aplicatie. Sunt necesari un numar de neuroni de iesire egal cu numarul de clase distincte pe care trebuie sa le recunoasca reteaua. De exemplu, o retea neuronala care trebuie sa recunoasca cifrele zecimale, va avea la iesire 10 neuroni. O retea ce trebuie sa recunoasca literele mari ale alfabetului, la iesire va avea 27 de neuroni.
Unele din regulile ce se aplica intrarilor, se aplica si pentru iesiri. De exemplu, o retea neuronala ce face o predictie asupra rezultatului unui joc sportiv, ofera rezultate mai bune daca la iesiri nu se asteapta valoarea absoluta a scorului, ci un rezultat de tipul invingator / egal / invins.
-Alegerea numarului de strate ascunse si a numarului de neuroni din ele
O alta decizie care trebuie facuta in proiectarea unei retele neuronale pentru o aplicatie concreta, este alegerea numarului de straturi ascunse si alegerea numarului de neuroni din fiecare strat ascuns. In probleme de clasificare (si nu de aproximare sau de modelare), cand la iesire reteaua recunoaste o clasa dintr-un set finit de clase posibile ( spre exemplu, recunoaste cifra 1 din 10 cifre posibile ), este suficient un singur strat ascuns. Se pot folosi eventual si mai multe straturi ascunse (desi este rar acest caz), pentru ca reteaua sa poata fi antrenata mai rapid.
Nu exista o formula dupa care sa se calculeze numarul de neuroni necesari intr-un strat ascuns. Acest numar se determina experimental. De aici, si necesitatea folosirii simulatoarelor, care permit modificarea numarului de neuroni folositi. In general cel mult 2 straturi ascunse sunt suficiente pentru marea majoritate a aplicatiilor.
-Antrenarea retelei
Pentru a simplifica procesul de antrenare, un simulator ar trebui sa permita si antrenarea in trepte a retelei. Initial, eroarea de invatare a sabloanelor se seteaza cu o valoare mare. De exemplu, pentru o retea ce trebuie sa invete sabloanele cu o toleranta finala de 1%, pentru a micsora timpul de antrenare, putem fixa initial eroarea la 10%. In acest fel , se castiga incredere ca reteaua converge. Apoi putem micsora aceasta eroare ( in trepte ), si sa reluam antrenarea cu ponderile gasite de la treapta precedenta. Repetam, pana cand se atinge eroarea impusa de 1%. Prin aceasta metoda de antrenare in trepte, adesea retelele neuronale converg mai rapid si generalizeaza mai bine.
In cazul in care dupa o alegere atenta a arhitecturii retelei, ea totusi nu converge sau generalizeaza prost, trebuie in general reanalizate sabloanele de antrenare folosite, modificandu-le. Se poate insa reantrena reteaua cu aceleasi sabloane, dar prezentate in alta ordine. Sau se poate antrena reteaua in modul 'batch': ajustarea ponderilor nu se mai face dupa fiecare sablon, ci, dupa prezentarea intregului set de sabloane.
De asemenea, atunci cand sunt probleme de convergenta sau de generalizare, se poate incerca folosirea mai multor retele neuronale interconectate, in loc de una singura.
3. DESFASURAREA LUCRARII
Se va edita si apoi executa programul descris in continuare, care simuleaza o retea neuronala cu intrari analogice.
Se prezinta ca date de intrare pentru reteaua neuronala, 10 valori numerice, numere reale pozitive. Ele reprezinta valorile ordonatelor unor puncte (pe axa Oy). Abscisele acestor puncte sunt egal distantate. Cele 10 valori, reprezentate grafic, determina o curba. Reteaua neuronala trebuie sa clasifice curba de pe intrarile ei, intr-una din urmatoarele clase:
-linie dreapta de panta zero (clasa 0)
-linie dreapta de panta pozitiva (clasa 1)
-linie dreapta de panta negativa (clasa 2)
-curba cu concavitate pozitiva (clasa 3)
-curba cu concavitate negativa (clasa 4)
In vederea rezolvarii problemei propuse, am folosit o retea neuronala MLP, cu 10 neuroni in stratul de intrare, un singur strat ascuns cu 5 neuroni, si 5 neuroni in stratul de iesire. Cele 5 iesiri (Y0,Y1,Y2,Y3,Y4) sunt atribuite fiecare, uneia din cele 5 clase de curbe. Reteaua a fost antrenata cu 15 sabloane (cate 3 pentru fiecare clasa de iesire).
Pentru valori numerice mari pe intrarile retelei, datorita functiei exponentiale din expresia functiei de transfer a unui neuron, se pot obtine ca rezultate intermediare numere foarte mari, si deci erori de depasire (overflow), la executia programului. De aceea valorile numerice de intrare (fie cele din sabloanele de antrenare, fie cele folosite la testarea retelei antrenate) se preproceseaza prin scalare, prin aducerea lor in gama 0..1. Astfel , intrarile neuronilor din primul strat sunt numere reale cuprinse in intervalul [0,1]. Formula de scalare folosita in cazul acestei aplicatii de clasificare curbe, este:
xScalat=(x-min)/(max-min), unde max si min sunt, respectiv, cea mai mare si cea mai mica din cele 10 valori numerice asteptate pe intrari.
Listingul programului
import java.util.*;
import java.io.*;
class RNLiniiwhile((c!='a')&&(c!='t'));
switch(c)//for
}//else a convers
break; //antrenare
case 't': //testare
incarcaPonderi();
for(;;)//for
break;//testare
}//switch
}//main
private static void initPonderi()
private static void incarcaSabloane()
//Citim valorile din sablon, pt. fiecare neuron de intrare:
/*Pentru a separa un string in articolele sale componente (separator implicit este caracterul blank), se foloseste clasa StringTokenizer si metoda nextToken( ).*/
StringTokenizer st=new StringTokenizer(linieCrt);
for(int i=0;i<NR_NEURONI_IN;i++)
//Citim linia cu iesirile sablonului ex:
linieCrt=fpBuf.readLine();
if(linieCrt==null)
//Citim valorile din sablon, pt. fiecare neuron de iesire:
st=new StringTokenizer(linieCrt);
for(int i=0;i<NR_NEURONI_OUT;i++)
sabloaneOut[ex][i]=
Double.valueOf(st.nextToken()).doubleValue();
}//for ex
fpBuf.close();
}catch(IOException e)
private static boolean antrenare()
//for
nrEpoci++;
eroareTotala=0;
for(ex=0;ex<NR_TOTAL_SABLOANE;ex++)
eroareTotala+=eroareIesireSablonCrt[ex];
System.out.println('Epoca nr: '+nrEpoci+
' eroare totala= '+eroareTotala);
if(eroareTotala <= EROARE_IMPUSA)
if(nrEpoci > NR_MAXIM_EPOCI)stop=true;
}//while
return converge;
private static void calculIesiriNeuroni(double yHidden[],
double yOut[],int ex)
//for i
for(i=0;i<NR_NEURONI_OUT;i++)//for i
private static void modificaPonderi(double yOut[],
double yHidden[],int ex)
for(i=0;i<NR_NEURONI_HIDDEN;i++)
for(j=0;j<NR_NEURONI_IN;j++)
w1[i][j]=alfa*w1[i][j]-eta*deltaHidden[i]*sabloaneIn[ex][j];
}//modificaPonderi
private static void afisareExtremePonderi()
for(i=0;i<NR_NEURONI_OUT;i++)
for(j=0;j<NR_NEURONI_HIDDEN;j++)
System.out.println('Ponderea maxima='+wMax+
' ponderea minima='+wMin);
}
private static void testare()
//for
//Metoda calculIesiriNeuroni(), calculeaza iesirile din retea,
//avand ca date la intrari, datele din sabloaneIn[][]
//De aceea, incarcam datele citite in sabloaneIn[0][]:
if(max!=min)//pt. a nu avea impartire cu 0:
for(i=0;i<10;i++)
sabloaneIn[0][i]=(valoriCurba[i]-min)/(max-min);
else for(i=0;i<10;i++)
sabloaneIn[0][i]=1;
calculIesiriNeuroni(yHidden,yOut,0);
System.out.println('Dreapta, panta 0 : '+yOut[0]);
System.out.println('Dreapta, panta poz. : '+yOut[1]);
System.out.println('Dreapta, panta neg. : '+yOut[2]);
System.out.println('Dreapta, concav. poz. : '+yOut[3]);
System.out.println('Dreapta, concav. neg. : '+yOut[4]);
}//testare
private static void salvare()
fpBuf.newLine();
}
//fpBuf.newLine(); st.nextToken() da erore pe linie goala!
for(i=0;i<NR_NEURONI_OUT;i++)
fpBuf.newLine();
}
fpBuf.close();
}catch(IOException e)
}
private static void incarcaPonderi()
StringTokenizer st=new StringTokenizer(linieCrt);
for(j=0;j<NR_NEURONI_IN;j++)
w1[i][j]=Double.valueOf(st.nextToken()).doubleValue();
}//for i
//Citim ponderile w2:
for(i=0;i<NR_NEURONI_OUT;i++)
StringTokenizer st=new StringTokenizer(linieCrt);
for(j=0;j<NR_NEURONI_HIDDEN;j++)
w2[i][j]=Double.valueOf(st.nextToken()).doubleValue();
}//for i
fpBuf.close();
}catch(IOException e)
}//end incarcaPonderi
}//class
Fisierul de sabloane, L5_1_sabloane.txt se editeaza cu editorul Notepad si are urmatoarea structura:
2 2 2 2 2 2 2 2 2
1 0 0 0 0
5 5 5 5 5 5 5 5 5 5
1 0 0 0 0
7 7 7 7 7 7 7 7 7 7
1 0 0 0 0
1 2 3 4 5 6 7 8 9 10
0 1 0 0 0
3 3.5 4 4.5 5 5.5 6 6.5 7
0 1 0 0 0
0.5 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 9.5
0 1 0 0 0
9 8 7 6 5 4 3 2 1
0 0 1 0 0
7 6.5 6 5.5 5 4.5 4 3.5 3 2.5
0 0 1 0 0
9.5 8.5 7.5 6.5 5.5 4.5 3.5 2.5 1.5 0.5
0 0 1 0 0
8 6 4 2 2 4 6 8 10
0 0 0 1 0
9.5 7.5 5.5 3.5 1.5 1.5 1.5 4 6 8
0 0 0 1 0
9 7 5 3 2 2.5 4 5 7 8
0 0 0 1 0
4 6 8 9 9 8 6 4 2
0 0 0 0 1
1 3 5 7 8 9 8.5 8 6 4
0 0 0 0 1
3 3.5 5 7 7.5 8 7 6 5 2
0 0 0 0 1
Tema
1. Sa se antreneze reteaua completand fisierul de sabloane cu altele noi.
2. Sa se modifice programul astfel incat datele cu care se testeaza reteaua sa nu fie introduse direct de la tastatura, ci sa se citeasca dintr-un fisier text de test.
3. Modificati programul astfel incat sa se realizeze o antrenare in trepte a retelei neuronale.
4. Sa se dezvolte un program de simulare a unei retele neuronale care recunoaste 2 forme de semnal: semnal dreptunghiular si semnal triunghiular.