?? bp_algorithm.cpp
字號:
#include <stdio.h>
#include <stdlib.h>
#include <fstream.h>
#include <math.h>
#define input_Num 6
#define hidden_Num 4
#define output_Num 1
#define high 0.999
#define low 0.001
double f(double x)
{
double d;
// d=0.5*(1.0+tanh(x));
d=1.0/(1.0+exp(-(x)));
if(d>high)
d=high;
if(d<low)
d=low;
return d;
}
struct inputNeuro
{
double input[6];
double teacher[1];
}indata[64];
double output_IL[input_Num];
double output_HL[hidden_Num];
double output_OL[output_Num];
double input_HL[hidden_Num];
double input_OL[output_Num];
double weight_IH[input_Num][hidden_Num];
double weight_HO[hidden_Num][output_Num];
double var_weight_IH[input_Num][hidden_Num];
double var_weight_HO[hidden_Num][output_Num];
double error;
double errorlimit;
double error_HL[hidden_Num];
double error_OL[output_Num];
double yita;
double alpha;
double beta;
double threshold_HL[hidden_Num];
double threshold_OL[output_Num];
void main()
{
int i,j,k,loop;
ofstream outError( "E:\\Downloads\\BP\\誤差.txt", ios::out );
void save();//函數聲明
/*網絡初始化*/
errorlimit=0.01;
for(i=0;i<64;i++)
{
if(i<32)
indata[i].input[5]=0;
else
indata[i].input[5]=1;
if(i<16||(i<48&&i>31))
indata[i].input[4]=0;
else
indata[i].input[4]=1;
if(i<8||(i>15&&i<24)||(i<40&&i>31)||(i<56&&i>47))
indata[i].input[3]=0;
else
indata[i].input[3]=1;
if(i<4||(i<12&&i>7)||(i<20&&i>15)||(i<28&&i>23)||
(i<36&&i>31)||(i<44&&i>39)||(i<52&&i>47)||(i<60&&i>55))
indata[i].input[2]=0;
else
indata[i].input[2]=1;
if(i<2||(i<6&&i>3)||(i<10&&i>7)||(i<14&&i>11)||
(i<18&&i>15)||(i<22&&i>19)||(i<26&&i>23)||
(i<30&&i>27)||(i<34&&i>31)||(i<38&&i>35)||(i<42&&i>39)||
(i<46&&i>43)||(i<50&&i>47)||(i<54&&i>51)||(i<58&&i>55)||
(i<62&&i>59))
indata[i].input[1]=0;
else
indata[i].input[1]=1;
if(!(i%2))
indata[i].input[0]=0;
else
indata[i].input[0]=1;
switch(i)
{
case 0:
case 12:
case 18:
case 30:
case 33:
case 45:
case 51:
case 63:indata[i].teacher[0]=high;break;
default:indata[i].teacher[0]=low;break;
}
}
for(j=0;j<hidden_Num;j++)
input_HL[j]=0.0;
for(j=0;j<output_Num;j++)
input_OL[j]=0.0;
for(j=0;j<input_Num;j++)
for(k=0;k<hidden_Num;k++)
weight_IH[j][k]=((double(rand()%11-10))/10.0);//0.1
for(j=0;j<hidden_Num;j++)
for(k=0;k<output_Num;k++)
weight_HO[j][k]=((double(rand()%11-10))/10.0);//0.1
for(j=0;j<input_Num;j++)
for(k=0;k<hidden_Num;k++)
var_weight_IH[j][k]=0.0;
for(j=0;j<hidden_Num;j++)
for(k=0;k<output_Num;k++)
var_weight_HO[j][k]=0.0;
for(j=0;j<hidden_Num;j++)
threshold_HL[j]=-0.1;//-1.8,-0.1
for(j=0;j<output_Num;j++)
threshold_OL[j]=-2;//-0.1,-2
yita=0.3;//yita一般取值為0.2~0.3//0.36效果不錯
alpha=0.8;//alpha一般取值為0.7~0.8
beta=0.00000002;//0.01,0.00000002
loop=0;//迭代次數
/*網絡初始化完成*/
while(loop<1000000)
{
error=0.0;
for(j=0;j<hidden_Num;j++)
error_HL[j]=0.0;
for(j=0;j<output_Num;j++)
error_OL[j]=0.0;
for(i=0;i<64;i++)
{
/*輸入層的輸出*/
for(j=0;j<input_Num;j++)
{
output_IL[j]=indata[i].input[j];
output_IL[j]=f(output_IL[j]);
}
/*隱層的輸入*/
for(j=0;j<hidden_Num;j++)
input_HL[j]=0.0;
for(k=0;k<hidden_Num;k++)
for(j=0;j<input_Num;j++)
input_HL[k]+=(weight_IH[j][k]*output_IL[j]);
for(k=0;k<hidden_Num;k++)
input_HL[k]+=threshold_HL[k];
/*隱層輸出*/
for(k=0;k<hidden_Num;k++)
{
output_HL[k]=f(input_HL[k]);
}
/*輸出層的輸入*/
for(j=0;j<output_Num;j++)
input_OL[j]=0.0;
for(k=0;k<output_Num;k++)
for(j=0;j<hidden_Num;j++)
input_OL[k]+=(weight_HO[j][k]*output_HL[j]);
for(k=0;k<output_Num;k++)
input_OL[k]+=threshold_OL[k];
/*輸出層的輸出*/
for(k=0;k<output_Num;k++)
{
output_OL[k]=f(input_OL[k]);
}
for(j=0;j<output_Num;j++)
{
error_OL[j]=(((output_OL[j]-indata[i].teacher[j])));
error+=0.5*(fabs(error_OL[j])*fabs(error_OL[j]));
}
/*隱層與輸出層間的權值變化量*/
for(j=0;j<hidden_Num;j++)
for(k=0;k<output_Num;k++)
var_weight_HO[j][k]=
(-yita*(error_OL[k]*(output_OL[k]*(1.0-output_OL[k])))*output_HL[j]
+alpha*var_weight_HO[j][k]);
/*對隱層與輸出層間的權值以及輸出層的閾值進行修正*/
for(j=0;j<hidden_Num;j++)
for(k=0;k<output_Num;k++)
weight_HO[j][k]+=var_weight_HO[j][k];
for(k=0;k<output_Num;k++)
threshold_OL[k]+=(beta*error_OL[k]);
/*輸入層與隱層間的權值變化量*/
for(j=0;j<input_Num;j++)
for(k=0;k<hidden_Num;k++)
var_weight_IH[j][k]=
(-yita*(((error_OL[0]*(output_OL[k]*(1.0-output_OL[0])))*weight_HO[k][0])
*(output_HL[k]*(1.0-output_HL[k])))*output_IL[j]
+alpha*var_weight_IH[j][k]);
/*對輸入層與隱層間的權值以及隱層的閾值進行修正*/
for(j=0;j<input_Num;j++)
for(k=0;k<hidden_Num;k++)
weight_IH[j][k]+=var_weight_IH[j][k];
for(k=0;k<hidden_Num;k++)
threshold_HL[k]+=(beta*(error_OL[0]*(output_OL[k]*(1.0-output_OL[0]))*weight_HO[k][0]));
// threshold_HL[k]+=(beta*error_OL[k]);
}
//將誤差數據倒出到文本文件中
if(loop==0)
outError<<"迭代次數 誤差\t迭代次數 誤差\t迭代次數 誤差\t迭代次數 誤差\n";
outError<<(loop+1)<<"\t "<<error<<"\t ";
if((loop+1)%4==0)
outError<<"\n";
printf("%d\t%lf\n",loop+1,error);
loop++;
if(error<errorlimit)
break;
}
if(error<errorlimit&&loop<1000000)
{
printf("\nThe iteration number of the program is %d!",loop);
printf("\nThe final error is %lf!\n",error);
printf("\nSuccessful!\n");
for(i=0;i<64;i++)
{
for(j=0;j<input_Num;j++)
{
output_IL[j]=indata[i].input[j];
output_IL[j]=f(output_IL[j]);
printf("%1.0f ",indata[i].input[j]);
}
printf("\n");
output_OL[0]=0.0;
for(j=0;j<hidden_Num;j++)
input_HL[j]=0.0;
for(j=0;j<output_Num;j++)
input_OL[j]=0.0;
/*隱層的輸入*/
for(k=0;k<hidden_Num;k++)
for(j=0;j<input_Num;j++)
input_HL[k]+=(weight_IH[j][k]*output_IL[j]);
for(k=0;k<hidden_Num;k++)
input_HL[k]+=threshold_HL[k];
/*隱層輸出*/
for(k=0;k<hidden_Num;k++)
{
output_HL[k]=f(input_HL[k]);
}
/*輸出層的輸入*/
for(k=0;k<output_Num;k++)
for(j=0;j<hidden_Num;j++)
input_OL[k]+=(weight_HO[j][k]*output_HL[j]);
for(k=0;k<output_Num;k++)
input_OL[k]+=threshold_OL[k];
/*輸出層的輸出*/
for(k=0;k<output_Num;k++)
{
output_OL[k]=f(input_OL[k]);
}
// /*輸出層的誤差*/
printf("\n%lf\n\n",output_OL[0]);
}
save();
}
else
printf("error!");
}
void save()
{
int m,n;
ofstream outQuanFile( "E:\\Downloads\\BP\\權值.txt", ios::out );
ofstream outYuFile( "E:\\Downloads\\BP\\閾值.txt", ios::out );
outQuanFile<<"輸入層與隱含層之間的連接權\n";
for(m=0;m<input_Num;m++)//ofstream out("g:\\bp\\e.txt");
{
for(n=0;n<hidden_Num;n++)
{
outQuanFile<<weight_IH[m][n]<<" ";
}
outQuanFile<<"\n";
}
outQuanFile<<"隱含層與輸出層之間的連接權\n";
for(m=0;m<hidden_Num;m++)
{
for(n=0;n<output_Num;n++)
{
outQuanFile<<weight_HO[m][n]<<" ";
}
outQuanFile<<"\n";
}
outYuFile<<"\n隱層的閾值為:\n";
for(n=0;n<hidden_Num;n++)
{
outYuFile<<threshold_HL[n]<<" "; //隱層閾值寫入文本
}
outYuFile<<"\n輸出層的閾值為:\n";
for(m=0;m<output_Num;m++)
{
outYuFile<<threshold_OL[m]<<" "; //輸出層閾值寫入文本
}
// outQuanFile.close();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -