📄 rn.java
字号:
/*
Program de simulare a unei retele neuronale ce clasifica o imagine binara de 5x5 pixeli (imaginea unei piese in forma de T) in 4 clase: piesa orientata cu capul sus (T), spre dreapta, in jos, spre stanga.
*/
import java.util.*;
import java.io.*;
class rn{
static final int NR_NEURONI_IN=5*5;
static final int NR_NEURONI_OUT=4;
static final int NR_NEURONI_HIDDEN=20;
static final int NR_TOTAL_SABLOANE=4;
static final double EROARE_IMPUSA=0.01;
//experimental : 0.01 in aproximativ 1000 de epoci.
static final int NR_MAXIM_EPOCI=20000;
static double w1[][]=
new double[NR_NEURONI_HIDDEN][NR_NEURONI_IN];
static double w2[][]=
new double[NR_NEURONI_OUT][NR_NEURONI_HIDDEN];
//sabloaneIn - contine intrarile a 4 sabloane fiecare avand cate
//25 de valori binare. Este deci un array ce contine 4 array-uri:
static int sabloaneIn[][]= { {1,1,1,1,1,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0},
{0,0,0,0,1,
0,0,0,0,1,
1,1,1,1,1,
0,0,0,0,1,
0,0,0,0,1},
{0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
0,0,1,0,0,
1,1,1,1,1},
{1,0,0,0,0,
1,0,0,0,0,
1,1,1,1,1,
1,0,0,0,0,
1,0,0,0,0} };
//Obs.: prezenta acoladelor interioare este obligatorie, pt. ca Java
//sa poata determina dimensiunile array-ului.
//sabloaneOut - contine iesirile a 4 sabloane, fiecare avand cate
//4 valori (corespunzatoare celor 4 orientari):
static int sabloaneOut[][]={ {1,0,0,0},
{0,1,0,0},
{0,0,1,0},
{0,0,0,1} };
public static void main(String args[])
{
boolean converge;
//antrenare retea:
initPonderi();
converge=antrenare();
if(converge==false)
System.out.println("Nu a convers in nr. de epoci specificat !");
else{
System.out.println("A convers. !");
testare();
}
}//main
private static void initPonderi()
{
int i,j;
Random r=new Random();
//initializare primul strat de ponderi:
for(i=0;i<NR_NEURONI_HIDDEN;i++)
for(j=0;j<NR_NEURONI_IN;j++)
w1[i][j]=r.nextDouble()-0.5;
//initializare stratul al doilea de ponderi:
for(i=0;i<NR_NEURONI_OUT;i++)
for(j=0;j<NR_NEURONI_HIDDEN;j++)
w2[i][j]=r.nextDouble()-0.5;
}
private static boolean antrenare()
{
double yHidden[]=new double[NR_NEURONI_HIDDEN];
double yOut[]=new double[NR_NEURONI_OUT];
double eroareIesireSablonCrt[]=
new double[NR_TOTAL_SABLOANE];
double eroareTotala;
int nrEpoci=0;
boolean converge=false;
boolean stop=false;
int i,ex;
while(!stop){
for(ex=0;ex<NR_TOTAL_SABLOANE;ex++){
calculIesiriNeuroni(yHidden,yOut,ex);
eroareIesireSablonCrt[ex]=0;
for(i=0;i<NR_NEURONI_OUT;i++)
eroareIesireSablonCrt[ex]+=0.5*(yOut[i]-
sabloaneOut[ex][i])*(yOut[i]-sabloaneOut[ex][i]);
modificaPonderi(yOut,yHidden,ex);
}//for ex
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)
{converge=true;stop=true;}
if(nrEpoci > NR_MAXIM_EPOCI)stop=true;
}//while
return converge;
}
private static void calculIesiriNeuroni(double yHidden[],
double yOut[],int ex)
{
int i,j;
double xTotal_i;
for(i=0;i<NR_NEURONI_HIDDEN;i++){
xTotal_i=0;
for(j=0;j<NR_NEURONI_IN;j++)
xTotal_i=xTotal_i+sabloaneIn[ex][j]*w1[i][j];
yHidden[i]=1/(1+Math.exp(-xTotal_i));
}//for i
for(i=0;i<NR_NEURONI_OUT;i++){
xTotal_i=0;
for(j=0;j<NR_NEURONI_HIDDEN;j++)
xTotal_i=xTotal_i+yHidden[j]*w2[i][j];
yOut[i]=1/(1+Math.exp(-xTotal_i));
}//for i
}
private static void modificaPonderi(double yOut[],
double yHidden[],int ex)
{
double deltaOut[]=new double[NR_NEURONI_OUT];
double deltaHidden[]=new double[NR_NEURONI_HIDDEN];
int i,j,k;
double sumaPonderataDeltaFii;
double alfa=1.0;
double eta=1.0;
for(i=0;i<NR_NEURONI_OUT;i++)
deltaOut[i]=(yOut[i]-sabloaneOut[ex][i])*
(1-yOut[i])*yOut[i];
for(i=0;i<NR_NEURONI_OUT;i++)
for(j=0;j<NR_NEURONI_HIDDEN;j++)
w2[i][j]=alfa*w2[i][j]-eta*deltaOut[i]*yHidden[j];
for(i=0;i<NR_NEURONI_HIDDEN;i++){
sumaPonderataDeltaFii=0;
for(j=0;j<NR_NEURONI_OUT;j++)
sumaPonderataDeltaFii+=w2[j][i]*deltaOut[j];
deltaHidden[i]=sumaPonderataDeltaFii*
(1-yHidden[i])*yHidden[i];
}
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 testare()
{
int i,j;
//iesiri neuroni din strat hidden:
double yHidden[]=new double[NR_NEURONI_HIDDEN];
//iesiri neuroni din stratul aut (cele calculate):
double yOut[]=new double[NR_NEURONI_OUT];
//intrarile pt. testarea retelei:
int inTest[]=new int[NR_NEURONI_IN];
double xTotal_i;
System.out.println("Dati cele " + NR_NEURONI_IN+
" valori binare de pe intrari: ");
ConsoleReader cr=new ConsoleReader(System.in);
for(i=0;i<NR_NEURONI_IN;i++){
System.out.print("Valoarea pixelului "+i+" : ");
inTest[i]=cr.readInt();
}//for
//Propagare inainte:
for(i=0;i<NR_NEURONI_HIDDEN;i++){
xTotal_i=0;
for(j=0;j<NR_NEURONI_IN;j++)
xTotal_i=xTotal_i+inTest[j]*w1[i][j];
yHidden[i]=1/(1+Math.exp(-xTotal_i));
}//for i
for(i=0;i<NR_NEURONI_OUT;i++){
xTotal_i=0;
for(j=0;j<NR_NEURONI_HIDDEN;j++)
xTotal_i=xTotal_i+yHidden[j]*w2[i][j];
yOut[i]=1/(1+Math.exp(-xTotal_i));
}//for i
System.out.println("Orientare sus : "+yOut[0]);
System.out.println("Orientare dreapta : "+yOut[1]);
System.out.println("Orientare jos : "+yOut[2]);
System.out.println("Orientare stanga : "+yOut[3]);
}//testare
}//class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -