最近论文在弄神经网络方面,用c++模拟了BP算法,只有一个学习因子,暂且命名为1.0版本吧,以后会更新版本,添加因子并且和牛顿法相结合
有技术硬伤还请牛人指点
#include<iostream>
#include<iomanip>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define N 4
#define IN 2
#define HN 2
#define ON 1
double P[IN];
double T[ON];
double W[HN][IN];
double V[ON][HN];
double X[HN];
double Y[ON];
double H[HN];
double O[ON];
double sita[HN];
double gama[ON];
double err_m[N];
double d_err[ON];
double e_err[HN];
double alpha;
double beta;
struct
{
double input[IN];
double teach[ON];
}Study_Data[N][IN];
void initial() //初始化权值、阈值
{
int i,j,k;
for(j=0;j<HN;j++)
{
for(i=0;i<IN;i++)
{
W[j][i]=(double)((rand()%19999-9999)*0.00001);
}
sita[j]=(double)((rand()%19999-9999)*0.00001);
}
for(k=0;k<ON;k++)
{
for(j=0;j<HN;j++)
{
V[k][j]=(double)((rand()%19999-9999)*0.00001);
}
gama[k]=(double)((rand()%19999-9999)*0.00001);
}
}
void input_P(int m)
{
for(int i=0;i<IN;i++)
P[i]=Study_Data[m]->input[i];
}
void input_T(int m)
{
for(int k=0;k<m;k++)
T[k]=Study_Data[m]->teach[k];
}
void H_I_O()
{
double sigma;
int i,j;
for(j=0;j<HN;j++)
{
sigma=0.0;
for(i=0;i<IN;i++)
sigma+=W[j][i]*P[i];
X[j]=sigma-sita[j];
H[j]=1.0/(1.0+exp(-X[j]));
}
}
void O_I_O()
{
double sigma;
int j,k;
for(k=0;k<ON;k++)
{
sigma=0.0;
for(j=0;j<HN;j++)
sigma+=V[k][j]*H[k];
Y[k]=sigma-gama[k];
O[k]=1.0/(1.0+exp(-Y[k]));
}
}
void Err_O_H(int m)
{
double abs_err[ON];
double sqr_err=0.0;
for(int k=0;k<ON;k++)
{
abs_err[k]=T[k]-O[k];
sqr_err+=abs_err[k]*abs_err[k];
d_err[k]=abs_err[k]*O[k]*(1.0-O[k]);
}
err_m[m]=sqr_err/2;
}
void Err_H_I()
{
double sigma;
for(int j=0;j<HN;j++)
{
sigma=0.0;
for(int k=0;k<ON;k++)
sigma+=d_err[k]*V[k][j];
e_err[j]=sigma*H[j]*(1-H[j]);
}
}
void Delta_O_H(int m)
{
for(int k=0;k<ON;k++)
{
for(int j=0;j<HN;j++)
V[k][j]+=alpha*d_err[k]*H[j];
gama[k]+=alpha*d_err[k];
}
}
void Delta_H_I(int m)
{
for(int j=0;j<HN;j++)
{
for(int i=0;i<IN;i++)
W[j][i]+=beta*e_err[j]*P[i];
sita[j]+=beta*e_err[j];
}
}
double Err_Sum()
{
double total_err=0.0;
for(int m=0;m<N;m++)
total_err+=err_m[m];
return total_err;
}
int main()
{
double sum_err;
int study=0;
cout<<"请输入输出层到隐含层学习效率:alpha=\n";
cin>>alpha;
cout<<"请输入隐含层到输入层学习效率:beta=\n";
cin>>beta;
double Pre_error;
cout<<"请输入预定误差:Pre_error=\n";
cin>>Pre_error;
int Pre_times;
cout<<"请输入预定最大学习次数:Pre_times=\n";
cin>>Pre_times;
cout<<"请输入学习样本数据\n";
for(int m=0;m<N;m++)
{
cout<<"请输入第"<<m+1<<"组学习样本"<<endl;
for(int i=0;i<IN;i++)
cin>>Study_Data[m]->input[i];
}
for (int m=0;m<N;m++)
{
cout<<"请输入第"<<m+1<<"组教师样本"<<endl;
for (int k=0;k<ON;k++)
cin>>Study_Data[m]->teach[k];
}
initial();
bool flag=true;
do
{
++study;
for(int m=0;m<N;m++)
{
input_P(m);
input_T(m);
H_I_O();
O_I_O();
Err_O_H(m);
Err_H_I();
Delta_O_H(m);
Delta_H_I(m);
for(int k=0;k<ON;k++)
{
if(k==0&&O[k]<=0.1)
flag=false;
cout<<setiosflags(ios::fixed)<<setprecision(4)<<O[k]<<endl;
}
}
sum_err=Err_Sum();
cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;
}while(flag);
cout<<"共学习了"<<study<<"次"<<endl;
system("pause");
return 0;
}