Referat Simularea SOFTWARE
Mai jos puteti citi fragmente din
Referat Simularea SOFTWARE si de asemenea puteti face
Download Referat Simularea SOFTWARE Citeste fragmente din Referat Simularea SOFTWARE
LUCRARE DE LABORATOR NR. 5
SIMULAREA SOFTWARE
A REÅ¢ELELOR NEURONALE MLP ( II )
1. SCOPUL LUCRĂRII
În această lucrare se studiază o reţea neuronală multi-layer
perceptron ( MLP ), antrenată pentru recunoaşterea de forme, care are
intrări analogice. Reţeaua este antrenată cu şabloanele salvate
într-un fişier text, după care ea este testată cu date de intrare
noi, diferite de cele pe care le-a învăţat. De asemenea, se studiază
caracteristicile generale ale simulatoarelor de reţele neuronale.
2. BREVIAR TEORETIC
În general, o reţea neuronală poate fi implementată în trei moduri
distincte:
-simulată soft, pe un calculator secvenţial
-simulată soft pe un calculator paralel (un sistem cu mai multe
procesoare)
-implementată hard
În privinţa utilizării simulatoarelor, pentru rezolvarea unei
aplicaţii concrete, trebuie avute în vedere următoarele aspecte:
-Alegerea tipului de reţea neuronală
Majoritatea reţelelor neuronale utilizate practic sunt de tipul
perceptron multistrat ( MLP ) şi utilizează algoritmul de
backpropagation pentru învăţare. Algoritmul de backpropagation
foloseşte eroarea între ieşirile actuale (rezultate prin calcul,
propagând înainte valorile de pe intrări, specificate de şabloane)
ÅŸi ieÅŸirile aÅŸteptate (cele impuse de ÅŸablonul curent), pentru a
ajusta fiecare pondere. Ajustarea ponderilor se face secvenţial,
plecând de la ultimul strat (cel de ieşire), spre primul strat (cel de
intrare).
-Alegerea intrărilor (numărul şi tipul lor)
În general alegerea intrărilor este o problema dificilă. Ieşirile
reţelei sunt mai clar impuse de problema concretă analizată, pe când
intrările nu. O regulă empirică de alegere a intrărilor este
următoarea: "cu cât mai multe date, cu atât mai bine!" Această
regulă se aplică atât la numărul intrărilor unei reţele, ca şi la
numărul şabloanelor de antrenare.
Intrările suplimentare nu afectează acurateţea rezultatelor
furnizate de reţea în problema concretă rezolvată, chiar dacă
anumite intrări se dovedesc a fi neimportante în determinarea ieşirii
corecte. Totuşi, toate simulatoarele au o limită superioară de
neuroni pe care-i suportă, şi deci şi de intrări.
Trebuie ca atunci când se strâng date şi se definesc intrările
reţelei, să nu se furnizeze reţelei 2 vectori similari de intrări,
care să dea la ieşire rezultate conflictuale. Spre exemplu, o reţea
ce recunoaşte diverse fructe, ar putea să identifice "măr" sau
"prună" (deci conflictual), bazat pe intrările "rotund" şi "roşu".
Pentru a rezolva conflictul, trebuie introduse intrări adiţionale (
mărime, gust, etc.).
La fel de importantă ca şi strângerea unui număr suficient de date
de intrare este şi modalitatea de prezentare a acestora, reţelei.
Marea majoritate a simulatoarelor existente acceptă intrări ce
variază între 0 si 1, sau intre -1 si +1. De aceea, datele reale
trebuie să fie preprocesate pentru a fi aduse în această gamă. Cele
mai multe simulatoare realizează chiar ele această preprocesare. Modul
cum se aleg intrările semnificative pentru reţea şi modul de setare
al parametrilor în simulator, au drept rezultat obţinerea unei
reţele neuronale performante sau nu.
Se pot utiliza 2 tipuri de bază pentru intrări în reţele neuronale:
-intrări booleene (de tipul TRUE/FALSE)
Astfel, pentru o imagine alb-negru ce trebuie recunoscută de reţea,
intrările ( “0†- pixel alb, “1†- pixel negru ) sunt de tip
boolean. Aceste intrări se mai cheamă şi intrări binare.
-intrări analogice sunt cele care iau valori continue între o valoare
minimă şi una maximă. De exemplu, între 0 şi 1. Pentru datele de pe
intrări de tip analogic, se recomandă ca gama lor de variaţie să nu
fie prea mare (diferenţa între valoarea maximă aşteptată şi
valoarea minimă aşteptată). În acest scop, dacă o intrare analogica
are o plajă mare de valori, poate fi eventual înlocuită cu o altă
intrare ce foloseşte diferenţa între valoarea analogică curentă şi
cea anterioară. În acest fel, aplicând diferenţa, gama scade.
Cele mai multe reţele ce rezolva probleme reale au atât intrări
binare cât şi intrări analogice. Tipul de intrare folosit (binară
sau analogică) poate afecta performanţele reţelei.
Numărul de intrări corespunde numărului de neuroni din stratul de
intrare.
-Alegerea ieÅŸirilor
În general, numărul ieşirilor este direct impus de aplicaţie. Sunt
necesari un număr de neuroni de ieşire egal cu numărul de clase
distincte pe care trebuie să le recunoască reţeaua. De exemplu, o
reţea neuronală care trebuie să recunoască cifrele zecimale, va avea
la ieşire 10 neuroni. O reţea ce trebuie să recunoască literele mari
ale alfabetului, la ieÅŸire va avea 27 de neuroni.
Unele din regulile ce se aplică intrărilor, se aplică şi pentru
ieşiri. De exemplu, o reţea neuronală ce face o predicţie asupra
rezultatului unui joc sportiv, oferă rezultate mai bune dacă la
ieşiri nu se aşteaptă valoarea absolută a scorului, ci un rezultat
de tipul învingător / egal / învins.
-Alegerea numărului de strate ascunse şi a numărului de neuroni din
ele
O altă decizie care trebuie făcută în proiectarea unei reţele
neuronale pentru o aplicaţie concretă, este alegerea numărului de
straturi ascunse şi alegerea numărului de neuroni din fiecare strat
ascuns. ÃŽn probleme de clasificare (ÅŸi nu de aproximare sau de
modelare), când la ieşire reţeaua recunoaşte o clasă dintr-un set
finit de clase posibile ( spre exemplu, recunoaÅŸte cifra 1 din 10 cifre
posibile ), este suficient un singur strat ascuns. Se pot folosi
eventual ÅŸi mai multe straturi ascunse (deÅŸi este rar acest caz),
pentru ca reţeaua să poată fi antrenată mai rapid.
Nu există o formulă după care să se calculeze numărul de neuroni
necesari într-un strat ascuns. Acest număr se determină experimental.
De aici, si necesitatea folosirii simulatoarelor, care permit
modificarea numărului de neuroni folosiţi. În general cel mult 2
straturi ascunse sunt suficiente pentru marea majoritate a
aplicaţiilor.
-Antrenarea reţelei
Pentru a simplifica procesul de antrenare, un simulator ar trebui să
permită şi antrenarea în trepte a reţelei. Iniţial, eroarea de
învăţare a şabloanelor se setează cu o valoare mare. De exemplu,
pentru o reţea ce trebuie să înveţe şabloanele cu o toleranţă
finală de 1%, pentru a micşora timpul de antrenare, putem fixa
iniţial eroarea la 10%. În acest fel , se câştigă încredere că
reţeaua converge. Apoi putem micşora această eroare ( în trepte ),
şi să reluăm antrenarea cu ponderile găsite de la treapta
precedentă. Repetăm, până când se atinge eroarea impusă de 1%.
Prin această metodă de antrenare în trepte, adesea reţelele
neuronale converg mai rapid şi generalizează mai bine.
În cazul în care după o alegere atentă a arhitecturii reţelei, ea
totuşi nu converge sau generalizează prost, trebuie în general
reanalizate şabloanele de antrenare folosite, modificându-le. Se poate
însă reantrena reţeaua cu aceleaşi şabloane, dar prezentate în
altă ordine. Sau se poate antrena reţeaua în modul "batch": ajustarea
ponderilor nu se mai face după fiecare şablon, ci, după prezentarea
întregului set de şabloane.
De asemenea, atunci când sunt probleme de convergenţă sau de
generalizare, se poate încerca folosirea mai multor reţele neuronale
interconectate, în loc de una singură.
3. DESFĂŞURAREA LUCRĂRII
Se va edita şi apoi executa programul descris în continuare, care
simulează o reţea neuronala cu intrări analogice.
Se prezintă ca date de intrare pentru reţeaua neuronală, 10 valori
numerice, numere reale pozitive. Ele reprezintă valorile ordonatelor
unor puncte (pe axa Oy). Abscisele acestor puncte sunt egal distanţate.
Cele 10 valori, reprezentate grafic, determină o curbă. Reţeaua
neuronală trebuie să clasifice curba de pe intrările ei, într-una
din următoarele clase:
-linie dreaptă de pantă zero (clasa 0)
-linie dreaptă de pantă pozitivă (clasa 1)
-linie dreaptă de pantă negativă (clasa 2)
-curbă cu concavitate pozitivă (clasa 3)
-curbă cu concavitate negativă (clasa 4)
În vederea rezolvării problemei propuse, am folosit o reţea
neuronală MLP, cu 10 neuroni în stratul de intrare, un singur strat
ascuns cu 5 neuroni, şi 5 neuroni în stratul de ieşire. Cele 5
ieÅŸiri (Y0,Y1,Y2,Y3,Y4) sunt atribuite fiecare, uneia din cele 5 clase
de curbe. Reţeaua a fost antrenată cu 15 şabloane (câte 3 pentru
fiecare clasă de ieşire).
Pentru valori numerice mari pe intrările reţelei, datorită funcţiei
exponenţiale din expresia funcţiei de transfer a unui neuron, se pot
obţine ca rezultate intermediare numere foarte mari, şi deci erori de
depăşire (overflow), la execuţia programului. De aceea valorile
numerice de intrare (fie cele din ÅŸabloanele de antrenare, fie cele
folosite la testarea reţelei antrenate) se preprocesează prin scalare,
prin aducerea lor în gama 0..1. Astfel , intrările neuronilor din
primul strat sunt numere reale cuprinse în intervalul [0,1]. Formula de
scalare folosită în cazul acestei aplicaţii de clasificare curbe,
este:
xScalat=(x-min)/(max-min), unde max ÅŸi min sunt, respectiv, cea mai
mare şi cea mai mică din cele 10 valori numerice aşteptate pe
intrări.
Listingul programului
import java.util.*;
import java.io.*;
class RNLinii{
static final int NR_NEURONI_IN=10;
static final int NR_NEURONI_OUT=5;
static final int NR_NEURONI_HIDDEN=10;
static final int NR_TOTAL_SABLOANE=3*NR_NEURONI_OUT;
static final double EROARE_IMPUSA=0.01;
static final int NR_MAXIM_EPOCI=20000;
static double sabloaneIn[][]=
new double[NR_TOTAL_SABLOANE][NR_NEURONI_IN];
static double sabloaneOut[][]=
new double[NR_TOTAL_SABLOANE][NR_NEURONI_OUT];
static double w1[][]=
new double[NR_NEURONI_HIDDEN][NR_NEURONI_IN];
static double w2[][]=
new double[NR_NEURONI_OUT][NR_NEURONI_HIDDEN];
public static void main(String args[])
{
boolean converge;
ConsoleReader cr=new ConsoleReader(System.in);
char c,raspuns;
do{
System.out.print("a (antrenare) sau t (testare) ? [a/t] : ");
c=cr.readChar();
}while((c!= a )&&(c!= t ));
switch(c){
case a ://antrenare
initPonderi();
incarcaSabloane();
converge=antrenare();
if(!converge)System.out.println("Nu a convers in nr.
de epocii specificat !");
else{
System.out.println("A convers. !");
afisareExtremePonderi();
System.out.print("Salvare ponderi in fisier ? [d/n] : ");
raspuns=cr.readChar();
if(raspuns== d )salvare();
for(;;){
System.out.print("Testare ? [d/n] : ");
raspuns=cr.readChar();
if(raspuns== d )testare();
else break;
}//for
}//else a convers
break; //antrenare
case t : //testare
incarcaPonderi();
for(;;){
testare();
System.out.print("Testare ? [d/n] : ");
raspuns=cr.readChar();
if(raspuns== n )break;
}//for
break;//testare
}//switch
}//main
private static void initPonderi()
{
int i,j;
Random r=new Random();
//initializare primul strat de ponderi:
for(i=0;i
max)max=valoriCurba[i];
if(valoriCurba[i] < min)min=valoriCurba[i];
}//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()
{
StringBuffer nume=new StringBuffer("L5_1_ponderi.");
System.out.println("Numele fisierului in care salvam ponderi este:
L5_1_ponderi.xxx ");
System.out.println("Extensia (xxx) a numelui, este variabila.
Exemplu de nume fisier: ");
System.out.println("L5_1_ponderi.001");
System.out.print("Introduceti extensia numelui fisierului: ");
ConsoleReader cr=new ConsoleReader(System.in);
String extensie=cr.readLine();
nume.append(extensie);
String numeF=nume.toString();
int i,j;
try{
FileWriter fp=new FileWriter(numeF);
BufferedWriter fpBuf=new BufferedWriter(fp);
for(i=0;i