📄 xor_2.cpp
字号:
/*
SCOP PROGRAM: studiul retelelor neuronale feed-forward.
SPECIFICATII: Scrieti un program ce creeaza si antreneaza
o retea ce trebuie sa invete functia XOR, cu 2 intrari.
Arhitectura retelei: 2 neuroni in stratul de intrare,
2 neuroni in stratul ascuns, 1 neuron in stratul de iesire.
*/
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <alloc.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <dos.h>
#define EROARE_LIMITA 0.01
/* Arhitectura retelei cu notatiile de ponderi:
0---w0--2
\ \w4
w1 \ 4
w2 /
/ / w5
1----w3--3
*/
void main(void)
{
float eta=1.0; /** rata de invatare **/
float alfa=1.0; /** rata moment **/
float eroareCrtToateExemplele;
float eroareMaxToateExemplele;
float w0,w1,w2,w3,w4,w5;
float out[4];
float yCalculat, yDorit;
float exempluOut[4]={0,1,1,0};//{0.1,0.9,0.9,0.1};
float exempluIn[4][2]={0,0,
0,1,
1,0,
1,1};
//{0.1,0.1,0.1,0.9,0.9,0.1,0.9,0.9};
/* Experimental, cu 0.0 si 1.0 nu reusea sa invete! Se bloca pe la
eroare globala 0.3 . Nu scadea de loc! */
float delta2,delta3,delta4;
float eroareCrtUnExemplu[4];
int nrCrtEpoci;
int converged;
int ex,c;
clrscr();
randomize();
w0=(float)rand()/RAND_MAX- 0.5;//fara (float) se obtine mereu -0.5
w1=(float)rand()/RAND_MAX -0.5;
w2=(float)rand()/RAND_MAX -0.5;
w3=(float)rand()/RAND_MAX -0.5;
w4=(float)rand()/RAND_MAX -0.5;
w5=(float)rand()/RAND_MAX -0.5;
converged=0;
nrCrtEpoci=0;
//Algoritmul de backpropagation:
while(!converged){
for(ex=0;ex<4;ex++){
//propagare inainte:
out[0]=exempluIn[ex][0];
out[1]=exempluIn[ex][1];
out[2]=1/(1+exp(-w0*out[0]-w2*out[1]));
out[3]=1/(1+exp(-w1*out[0]-w3*out[1]));
yDorit=exempluOut[ex];
yCalculat=1/(1+exp(-w4*out[2]-w5*out[3]));
eroareCrtUnExemplu[ex]=0.5*(yCalculat-yDorit)*(yCalculat-yDorit);
//modifica ponderi:
//Formula de ajustare ponderi: w_ji=alfa*w_ji - eta*out[i]*delta_j
//Daca j este nod din ultimul strat:
//delta_j=(yCalculat_j-yDorit_j)*derivata functiei de transfer
delta4=(yCalculat-yDorit)*(1-yCalculat)*yCalculat;
w4=alfa*w4-eta*out[2]*delta4;
w5=alfa*w5-eta*out[3]*delta4;
// ATENTIE : delta2=w4*delta4; GRESIT!
//delta_j = (suma ponderata delta noduri fii ai lui j)*derivata functiei
//de transfer in raport cu intrarea totala, calculata in nodul j
//Pt. functie de transfer sigmoida f=1/(1+exp(-x)), avem:
//f'(x)=f(1-f). Deci in nodul j: out[j]*(1-out[j])
delta2=w4*delta4*(1-out[2])*out[2];
// delta3=w5*delta4; GRESIT! Eroarea totala crestea in loc sa scada!
delta3=w5*delta4*(1-out[3])*out[3];
w0=alfa*w0-eta*out[0]*delta2;
w1=alfa*w1-eta*out[0]*delta3;
w2=alfa*w2-eta*out[1]*delta2;
w3=alfa*w3-eta*out[1]*delta3;
}//for
nrCrtEpoci++;
eroareCrtToateExemplele=0;
for(ex=0;ex<4;ex++)
eroareCrtToateExemplele+=eroareCrtUnExemplu[ex];
printf("\nEpoca %d: w0=%.3f w1=%.3f Eroare totala pt. 4 exemple =%f",
nrCrtEpoci,w0,w1,eroareCrtToateExemplele);
if(eroareCrtToateExemplele<=EROARE_LIMITA)converged=1;
}//while
//afisare ponderi:
printf("\nw0=%f",w0);printf("\nw1=%f",w1); printf("\nw2=%f",w2);
printf("\nw3=%f",w3); printf("\nw4=%f",w4);printf("\nw5=%f",w5);
getch();
}//main
/*
INTREBARI:
1. Rulati de mai multe ori programul. De ce se obtin de fiecare
data alte valori pentru ponderi ?
2. Rulati programul si cu alte valori de EROARE_LIMITA
3. Modificati programul astfel incit sa invete (aceeasi retea) si
functiile: OR si apoi AND.
4. Modificati programul astfel incit:
-EROARE_LIMITA sa se citeasca de la tastatura
-Antrenarea sa se poata opri fortat, prin apasarea tastei ESC
-Ponderile gasite, daca antrenarea a convers, sa fie salvate
intr-un fisier text.
5. Modificati arhitectura retelei neuronale: folositi 3 neuroni in
stratul ascuns. Scrieti un nou program de antrenare a acestei
retele.
Comparati viteza de convergenta la invatarea functiei XOR, intre
cele 2 arhitecturi de retele feed forward.
6. Modificati arhitectura retelei neuronale: folositi doar 1 neuron
in stratul ascuns.
7. Modificati programul astfel incit sa permita antrenarea in trepte
a retelei. (Se specifica la inceput o eroare mai mare, iar dupa
ce a convers se specifica o eroare mai mica, folosind ponderile
gasite la treapta precedenta, ca ponderi initiale ale retelei).
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -