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