📄 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 + -