Sunteți pe pagina 1din 9

Algoritmul Backpropagation folosind PL/SQL

Bucureti 2012

Prezentarea aplicaiei
Algoritmul backpropagation este cel mai cunoscut si utilizat algoritm de invatare supervizata. Numit si algoritmul delta generalizat deoarece extinde modalitatea de antrenare a retelei adaline (regula delta), el se bazeaza pe minimizarea diferentei dintre iesirea dorita si iesirea reala, tot prin metoda gradientului descendent (gradientul ne spune cum variaza o functie in diferite directii). Metoda a fost propusa pentru prima data de Bryson si Ho (1969), dar la momentul respectiv a fost practic ignorata, deoarece presupunea un volum de calcule prea mare pentru vremea respectiva. A fost redescoperita apoi de Werbos (1974), insa abia la mijlocul anilor 80 a fost lansata de Rumelhart, Hinton si Williams (1986) ca instrument general acceptat de antrenare a perceptronului multistrat. Ideea de baza este gasirea minimului functiei de eroare e(w) in raport cu ponderile conexiunilor. Pentru a instrui reteaua neuronala trecem prin urmatorii pasi: 1. Initializarea 2. Epoca de antrenare 3. Propagarea semanlului inainte 4. Propagarea erorilor inapoi si ajustarea ponderilor 5. O noua interatie (daca mai sunt exemple ramase in epoca de antrenare se trece din nou la pasul 3) Retelele neuronale isi dovedesc in principal utilitatea in rezolvarea unor probleme dificile, cum sunt cele de estimare, identificare si predictie sau de optimizare complexa. Datorita independentei efectuarii operatiilor din interiorul componentelor fata de celelalte componente din sistem, modelele conexioniste au un potential mare de paralelism. Modul de memorare si procesare a datelor diferentiaza retelele neuronale artificiale de programele clasice, care urmeaza instructiunile intr-o ordine secventiala predefinita, iar informatia este memorata in zone bine definite. Datorita capacitatii lor de a rezolva probleme complexe pe baza unei multimi consistente de exemple, sistemele conexioniste au un spectru larg de aplicabilitate: de la sisteme de recunoastere de forme (caractere, semnaturi, etc.) sau de semnale sonore, pana la sisteme pentru controlul unor procese complexe, cum ar fi sistemele de auto-reglare sau pilotii automati. In acest proiect algoritmul backpropagation a fost construit folosind limbajul PL/SQL. Codul a fost scris pentru a permite introducerea oricarei functii de instruire(OR exclusiv sau orice alte exemple de instruire). Acest proiect simuleaza o retea cu doi neuroni de intrare, doi neuroni in stratul ascuns si un neuron in stratul de iesire. In continuarea voi descrie cum functioneaza aplicatia folosind forma logica XOR intrucat aceasta forma se poate calcula decat folosind algoritmul backpropagation. Valorile pentru X1, X2 si Output-ul Scop din functia XOR sunt: X1 X2 OS 1 1 0 0 0 0 1 0 1 0 1 1
2

In urma apelarii script-ului PL/SQL, in panoul de comanda se va cere introducerea numarului de exemple din epoca de antrenare, in cazul XOR prezentat mai sus avem patru exemple. Dupa introducerea numarului de exemple se cere introducerea valorilor pentru X1 din cele 4 exemple, valorile se introduc una dupa alta, separate prin virgula pentru a stii aplicatia sa le separe. Se repeta operatia de mai sus si pentru X2 si OS. Dupa ce se introduc valorile pentru cele trei variabile se afiseaza mesajul Exemplele de instruire au fost memorate! si sunt afisate valorile introduse pentru a se verifica daca au fost introduse corect. Dupa ce se verifica exemplele se continua cu initializarea ponderilor, a erorii admise si a ratei de invatare. Introducerea ultimei valori (rata de invatare) declanseaza instruirea retelei, in acest timp se afiseaza mesajul va rog sa asteptati instruirea retelei. La final aplicatia afiseaza valorile tuturor variabilelor din primele 2 iteratii si din ultima iteratie, plus numarul de iteratii si epoci necesare instruirii. Se ofera toate aceste informatii pentru a facilita verificarea calculelor. Aplicatia foloseste functia recursiva WHILE LOOP pentru a trece exemplele de instruire prin pasii algoritmului (activarea retelei, calculul erorii, calculul gradientului si ajustarea ponderilor) atat timp cat suma patratelor erorilor este mai mare decat eroarea admisa. Cand suma patratelor erorilor scade sub valoarea erorii admise atunci sunt afisate valorile din ultima iteratie. Astfel, pentru exemplul nostru vom folosi urmatoarele valori: w13= 0.5 w23= 0.4 w35= -1.2 TETA3= 0.8 Eroarea Admis= 0.001 w14= 0.9 w24= 1.0 w45= 1.1 TETA4= -0.1 = 0.1 TETA5= 0.3

Reteaua va ajunge va ajunge la ponderile corecte dupa 225452 de iteratii, adica 56363 de epoci. Valorile din prima iteratie sunt: w13= 0.5038 w23= 0.4038 w35= -1.2067 TETA3= 0.7962 w14= 0.8985 w24= 0.9985 w45= 1.0888 TETA4= -0.0985 TETA5= 0.3127

Valorile din ultima iteratie sunt: w13= 4.7519 w23= 4.7521 w35= -10.3907 TETA3= 7.2916 w14= 6.3827 w24= 6.3827 w45= 9.7766 TETA4= 2.8401
3

TETA5= 4.5608

si suma patratelor erorilor dupa ultima epoca va fi 0.000999997948. Pentru a verifica daca valorile finale sunt corecte, se apeleaza din nou algoritmul de calcul si se introduc valorile obtinute. Astfel, vom observa ca aplicatia se va opri dupa o singura epoca intrucat suma patratelor erorilor (0.000999997948) indeplineste conditia de a fi mai mica decat eroarea admisa (0.001). CODE:
set verify off; set feedback off; set serveroutput on format wrapped; clear screen; drop table exemplu_instruire; create table exemplu_instruire(x1 number,x2 number,os number); create or replace type rezultat_numeric as table of number; / --------package---------------------create or replace package back_propagation is procedure exemple_instruire (p_nr_ex number, p_x1 varchar2, p_x2 varchar2, p_os varchar2); procedure algoritm_bp (p_13 number,p_14 number, p_23 number, p_24 number, p_35 number, p_45 number, p_t3 number, p_t4 number, p_t5 number, p_ea number, p_a number); function valori_exemple (p_sir varchar2) return rezultat_numeric; end; / -------package body------------------create or replace package body back_propagation is -------functia---------function valori_exemple (p_sir varchar2) return rezultat_numeric is v_delimiter varchar2(1):=','; v_rezultat rezultat_numeric:=rezultat_numeric(); v_sir varchar2(255):=p_sir||v_delimiter; v_poz pls_integer; begin v_poz:=instr(v_sir,v_delimiter); while nvl(v_poz,0)>0 loop v_rezultat.extend(); v_rezultat(v_rezultat.count):=trim(substr(v_sir,1,v_poz-1)); v_sir:=trim(substr(v_sir,v_poz+1)); v_poz:=instr(v_sir,v_delimiter); end loop; return v_rezultat; end valori_exemple; ----procedura exemple--------------procedure exemple_instruire (p_nr_ex number, p_x1 varchar2, p_x2 varchar2, p_os varchar2) is type bk_intrari is table of number index by binary_integer;

valori_x1 bk_intrari; valori_x2 bk_intrari; valori_os bk_intrari; valoare number; nr_ex number:=p_nr_ex; v_x1 varchar2(50):=p_x1; v_x2 varchar2(50):=p_x2; v_os varchar2(50):=p_os; begin delete from exemplu_instruire; commit; for i in 1..nr_ex loop select z.column_value into valoare from( select rownum rn, x.* from table(valori_exemple(v_x1))x)z where z.rn=i; valori_x1(i):=valoare; select z.column_value into valoare from( select rownum rn, x.* from table(valori_exemple(v_x2))x)z where z.rn=i; valori_x2(i):=valoare; select z.column_value into valoare from( select rownum rn, x.* from table(valori_exemple(v_os))x)z where z.rn=i; valori_os(i):=valoare; insert into exemplu_instruire values(valori_x1(i),valori_x2(i),valori_os(i)); commit; end loop; end exemple_instruire; -------procedura algoritm bp---------------procedure algoritm_bp (p_13 number,p_14 number, p_23 number, p_24 number, p_35 number, p_45 number, p_t3 number, p_t4 number, p_t5 number, p_ea number, p_a number) is x1 number; x2 number; x13 number; x14 number; x23 number; x24 number; x35 number; x45 number; os1 number; oc3 number; oc4 number; oc5 number; w13 number:=p_13;

w14 number:=p_14; w23 number:=p_23; w24 number:=p_24; w35 number:=p_35; w45 number:=p_45; teta3 number:=p_t3; teta4 number:=p_t4; teta5 number:=p_t5; ea number:=p_ea; e5 number; er number:=1; iteratii number:=0; epoci number:=0; alfa number:=p_a; delta3 number; delta4 number; delta5 number; --variabile pentru corectie cw35 number; cw45 number; cteta5 number; cw13 number; cw23 number; cteta3 number; cw14 number; cw24 number; cteta4 number; begin while er>ea loop er:=0; for xy in (select x.x1, x.x2, x.os, rowid from exemplu_instruire x group by x.x1, x.x2, x.os, rowid order by rowid)loop x1:=xy.x1; x2:=xy.x2; x13:=x1; x14:=x1; x23:=x2; x24:=x2; os1:=xy.os; --activarea oc3:=1/(1+exp(-(x13*w13+x23*w23-teta3))); oc4:=1/(1+exp(-(x14*w14+x24*w24-teta4))); x35:=oc3; x45:=oc4; oc5:=1/(1+exp(-(x35*w35+x45*w45-teta5))); ---calculam eroarea e5:=os1-oc5; --instruirea ponderilor delta5:=oc5*(1-oc5)*e5; cw35:=alfa*oc3*delta5; cw45:=alfa*oc4*delta5; cteta5:=alfa*(-1)*delta5; ---calculul gradientului

delta3:=oc3*(1-oc3)*delta5*w35; delta4:=oc4*(1-oc4)*delta5*w45; --corectiile ponderilor cw13:=alfa*x1*delta3; cw23:=alfa*x2*delta3; cteta3:=alfa*(-1)*delta3; cw14:=alfa*x1*delta4; cw24:=alfa*x2*delta4; cteta4:=alfa*(-1)*delta4; --ajustarea ponderilor w13:=w13+cw13; w14:=w14+cw14; w23:=w23+cw23; w24:=w24+cw24; w35:=w35+cw35; w45:=w45+cw45; teta3:=teta3+cteta3; teta4:=teta4+cteta4; teta5:=teta5+cteta5; er:=er+power(e5,2); iteratii:=iteratii+1; if iteratii between 1 and 2 then dbms_output.new_line; dbms_output.put_line('Valorile din iteratia '||iteratii||' sunt:'); dbms_output.new_line; dbms_output.put_line('valoare x1: '||round(x1,4)); dbms_output.put_line('valoare x2: '||round(x2,4)); dbms_output.put_line('valoare x13: '||round(x13,4)); dbms_output.put_line('valoare x14: '||round(x14,4)); dbms_output.put_line('valoare x23: '||round(x23,4)); dbms_output.put_line('valoare x24: '||round(x24,4)); dbms_output.put_line('valoare x35: '||round(x35,4)); dbms_output.put_line('valoare x45: '||round(x45,4)); dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoaer dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare alfa: '||round(alfa,4)); delta3: '||round(delta3,4)); delta4: '||round(delta4,4)); delta5: '||round(delta5,4)); w13: '||round(w13,4)); w14: '||round(w14,4)); w23: '||round(w23,4)); w24: '||round(w24,4)); w35: '||round(w35,4)); w45: '||round(w45,4)); teta3: '||round(teta3,4)); teta4: '||round(teta4,4)); teta5: '||round(teta5,4));

dbms_output.put_line('valoare oc3: '||round(oc3,4)); dbms_output.put_line('valoare oc4: '||round(oc4,4)); dbms_output.put_line('valoare oc5: '||round(oc5,4)); dbms_output.put_line('valoare eroare: '||round(e5,4)); dbms_output.new_line; end if; end loop; epoci:=epoci+1; end loop;

dbms_output.new_line; dbms_output.put_line('Valorile din ultima iteratie sunt:'); dbms_output.new_line; dbms_output.put_line('valoare x1: '||round(x1,4)); dbms_output.put_line('valoare x2: '||round(x2,4)); dbms_output.put_line('valoare x13: '||round(x13,4)); dbms_output.put_line('valoare x14: '||round(x14,4)); dbms_output.put_line('valoare x23: '||round(x23,4)); dbms_output.put_line('valoare x24: '||round(x24,4)); dbms_output.put_line('valoare x35: '||round(x35,4)); dbms_output.put_line('valoare x45: '||round(x45,4)); dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoaer dbms_output.put_line('valoare dbms_output.put_line('valoare dbms_output.put_line('valoare alfa: '||round(alfa,4)); delta3: '||round(delta3,4)); delta4: '||round(delta4,4)); delta5: '||round(delta5,4)); w13: '||round(w13,4)); w14: '||round(w14,4)); w23: '||round(w23,4)); w24: '||round(w24,4)); w35: '||round(w35,4)); w45: '||round(w45,4)); teta3: '||round(teta3,4)); teta4: '||round(teta4,4)); teta5: '||round(teta5,4));

dbms_output.put_line('valoare oc3: '||round(oc3,4)); dbms_output.put_line('valoare oc4: '||round(oc4,4)); dbms_output.put_line('valoare oc5: '||round(oc5,4)); dbms_output.put_line('valoare eroare: '||round(e5,4)); dbms_output.put_line('suma patratelor erorilor: '||er); dbms_output.new_line; dbms_output.put_line('Instruirea retelei a necesitat '||iteratii||' iteratii si de '||epoci||' epoci!'); dbms_output.new_line; end algoritm_bp; end back_propagation; / PROMPT --EXEMPLELE DE INSTRUIRE--; ACCEPT NR1 PROMPT 'Introduceti numarul de exemple de instruire: '; ACCEPT NR2 PROMPT 'Introduceti valorile lui X1 (separate prin virgula) din cele &nr1 exemple: '; ACCEPT NR3 PROMPT 'Introduceti valorile lui X2 (separate prin virgula) din cele &nr1 exemple: '; ACCEPT NR4 PROMPT 'Introduceti valorile output-ului scop (separate prin virgula) din cele &nr1 exemple: '; execute back_propagation.exemple_instruire(&nr1,'&nr2','&nr3','&nr4'); clear screen; PROMPT Exemplele de instruire au fost memorate!; PROMPT Valorile din cele &nr1 exemple sunt:; select* from exemplu_instruire; PROMPT PROMPT --INITIALIZAREA ELEMENTELOR--; ACCEPT NR5 PROMPT 'Introduceti valoarea pentru W13: '; ACCEPT NR6 PROMPT 'Introduceti valoarea pentru W14: '; ACCEPT NR7 PROMPT 'Introduceti valoarea pentru W23: '; ACCEPT NR8 PROMPT 'Introduceti valoarea pentru W24: '; ACCEPT NR9 PROMPT 'Introduceti valoarea pentru W35: '; ACCEPT NR10 PROMPT 'Introduceti valoarea pentru W45: '; ACCEPT NR11 PROMPT 'Introduceti valoarea pentru TETA3: '; ACCEPT NR12 PROMPT 'Introduceti valoarea pentru TETA4: '; ACCEPT NR13 PROMPT 'Introduceti valoarea pentru TETA5: '; ACCEPT NR14 PROMPT 'Introduceti valoarea pentru EROAREA ACCEPTATA: ';

ACCEPT NR15 PROMPT 'Introduceti valoarea pentru UNITATEA DE CORECTIE: '; PROMPT PROMPT VA ROG SA ASTEPTATI INSTRUIREA RETELEI; execute back_propagation.algoritm_bp(&nr5,&nr6,&nr7,&nr8,&nr9,&nr10,&nr11,&nr12,&nr13,&nr14,& nr15);

S-ar putea să vă placă și