BP神经网络实现异或功能(C++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include "iostream.h"
#include "iomanip.h"
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
#include "time.h"
#include "fstream.h"
#define N 4 //学习样本个数
#define T_N 4 //检验样本的个数
#define IN 2 //输入层神经元数目
#define HN 3 //隐层神经元数目
#define ON 1 //输出层神经元数目
//一般化误差数组
double delta_ON[N][ON];
double delta_HN[N][HN];
// double delta_IN[N][IN];
// double P[IN]; //单个样本输入数据double P[N][IN]; //单个样本输入数据
// double T[ON]; //单个样本教师数据double T[N][ON]; //单个样本教师数据
double W[HN][IN]; //输入层至隐层权值double V[ON][HN]; //隐层至输出层权值double X[HN]; //隐层的输入
double Y[ON]; //输出层的输入
// double H[HN]; //隐层的输出
double H[N][HN]; //隐层的输出
double O[ON]; //输出层的输出
double YU_HN[HN]; //隐层的阈值
double YU_ON[ON]; //输出层的阈值
// double err_m[N]; //第m个样本的总误差
double err_m[N][ON]; //第m个样本的总误差double sum_err_m[N];
double a1; //输出层至隐层的学习效率
double a2;
double b1; //隐层至输入层学习效率
double b2;
ofstream out_test_result( "test_result.txt", ios::out );
//定义一个放学习样本的结构
struct {
double input[IN]; //输入在上面定义是一个
double teach[ON]; //输出在上面定义也是一个
}Study_Data[N];//学习样本
//定义一个放检测样本的结构
struct {
double input[IN]; //输入在上面定义是一个double teach[ON]; //输出在上面定义也是一个
}Test_Data[T_N];//检测样本
///////////////////////////
//初始化权、阈值子程序/////
///////////////////////////
initial()
{
//隐层权、阈值初始化//
srand( (unsigned)time( NULL ) );
for(int i=0;i<HN;i++)
for(int j=0;j<IN;j++)
W[i][j]= rand()/double(RAND_MAX);
for(int ii=0;ii<ON;ii++)
for(int jj=0;jj<HN;jj++)
V[ii][jj]=rand()/double(RAND_MAX);
for(int k=0;k<HN;k++)
YU_HN[k]=rand()/double(RAND_MAX);
for(int kk=0;kk<ON;kk++)
YU_ON[kk]=rand()/double(RAND_MAX);
return 1;
}//子程序initial()结束
////////////////////////////////
////第m个学习样本输入子程序///
///////////////////////////////
Train_input_P(int m)
{
for (int i=0;i<IN;i++)
P[m][i]=Study_Data[m].input[i];
//获得第m个样本的数据
return 1;
}//子程序Train_input_P(m)结束
Test_input_P(int m)
{
for (int i=0;i<IN;i++)
P[m][i]=Test_Data[m].input[i];
//获得第m个样本的数据
return 1;
}//子程序Test_input_P(m)结束
/////////////////////////////
////第m个样本教师信号子程序//
/////////////////////////////
Train_input_T(int m)
{
for (int k=0;k<ON;k++)
T[m][k]=Study_Data[m].teach[k]; return 1;
}//子程序Train_input_T(m)结束
Test_input_T(int m)
{
for (int k=0;k<ON;k++)
T[m][k]=Test_Data[m].teach[k]; return 1;
}//子程序Test_input_T(m)结束
/////////////////////////////////
//隐层各单元输入、输出值子程序///
/////////////////////////////////
H_I_O(int m)
{
double sigma;
for (int j=0;j<HN;j++)
{
sigma=0.0;
for (int i=0;i<IN;i++)
sigma+=W[j][i]*P[m][i];//求隐层内积
X[j]=sigma - YU_HN[j];
H[m][j]=1.0/(1.0+exp(-X[j]));//求隐层输出siglon算法}
return 1;
}//子程序H_I_O()结束
///////////////////////////////////
//输出层各单元输入、输出值子程序///
///////////////////////////////////
O_I_O(int m)
{
double sigma;
for (int k=0;k<ON;k++)
{
sigma=0.0;
for (int j=0;j<HN;j++)
sigma+=V[k][j]*H[m][j];
Y[k]=sigma-YU_ON[k]; //求输出层净输入
O[k]=1.0/(1.0+exp(-Y[k]));//求输出层输出
}
return 1;
}//子程序O_I_O()结束
////////////////////////////////////
//输出层至隐层的一般化误差子程序////
////////////////////////////////////
// double d_err[ON];
Err_O_H(int m)
{
double abs_err[ON];//每个样本的绝对误差都是从0开始的
double sqr_err=0;//每个样本的平方误差计算都是从0开始的
sum_err_m[m]=0.0;
for (int k=0;k<ON;k++)
{
abs_err[k]=T[m][k]-O[k];
sqr_err+=(abs_err[k])*(abs_err[k]);//求第m个样本下输出层的平方误差
delta_ON[m][k]=abs_err[k]*O[k]*(1.0-O[k]);
err_m[m][k]=sqr_err/2;
}
for(int j=0;j<ON;j++)
sum_err_m[m] +=err_m[m][j];
return 1;
}//子程序Err_O_H(m)结束
////////////////////////////////////
//隐层至输入层的一般化误差子程序////
////////////////////////////////////
// double e_err[HN];
Err_H_I(int m)
{
double sigma;
for (int j=0;j<HN;j++)
{
sigma=0.0;
for (int k=0;k<ON;k++)
sigma +=delta_ON[m][k]*V[k][j];
delta_HN[m][j]=sigma*H[m][j]*(1-H[m][j]);
}
return 1;
}//子程序Err_H_I()结束
////////////////////////////////////////////////////////
//输出层至隐层的权值调整、输出层阈值调整计算子程序////// ////////////////////////////////////////////////////////
Delta_O_H()
{
for (int k=0;k<ON;k++)
{
for (int j=0;j<HN;j++)
{
double temp1=0.0;
for(int m=0;m<N;m++)
temp1 +=delta_ON[m][k]*H[m][j];
V[k][j] +=a1*temp1;
}
double temp2=0.0;
for(int i=0;i<N;i++)
temp2 +=delta_ON[i][k];
YU_ON[k] -=a2*temp2;//输出层至隐层的阈值调整}
return 1;
}//子程序Delta_O_H()结束
/////////////////////////////////////////////////////
//隐层至输入层的权值调整、隐层阈值调整计算子程序/////
/////////////////////////////////////////////////////
// Delta_H_I(int m)
Delta_H_I()
{
for (int j=0;j<HN;j++)
{
for (int i=0;i<IN;i++)
{
double temp1=0.0;
for(int m=0;m<N;m++)
temp1 +=delta_HN[m][j]*P[m][i];
W[j][i] +=b1*temp1;
}
double temp2=0.0;
for(int k=0;k<N;k++)
temp2 +=delta_HN[k][j];
YU_HN[j] -=b2*temp2;
}
return 1;
}//子程序Delta_H_I()结束
/////////////////////////////////
//N个样本的全局误差计算子程序////
/////////////////////////////////
double Err_Sum()
{
double total_err=0;
for (int m=0;m<N;m++)
total_err+=sum_err_m[m];
return total_err;
}//子程序Err_sum()结束
GetTrainingData()
{
ifstream GetTrainingData ( "训练样本.txt", ios::in );
for(int m=0;m<N;m++)
{
for(int i=0;i<IN;i++)
GetTrainingData>>Study_Data[m].input[i]; //取得输入数据
for(int j=0;j<ON;j++)
GetTrainingData>>Study_Data[m].teach[j]; //取得输出数据
}
GetTrainingData.close();
return 1;
}
GetTestingData()
{
ifstream GetTestingData ( "检测样本.txt", ios::in );
for(int m=0;m<T_N;m++)
{
for(int i=0;i<IN;i++)
GetTestingData>>Test_Data[m].input[i]; //取得输入数据
for(int j=0;j<ON;j++)
GetTestingData>>Test_Data[m].teach[j]; //取得输出
数据
}
GetTestingData.close();
return 1;
}
void savequan()
{
ofstream outQuanFile( "权值.txt", ios::out );
ofstream outYuFile( "阈值.txt", ios::out );
outQuanFile<<"A\n";
for(int i=0;i<HN;i++)
{
for(int j=0;j<IN;j++)
outQuanFile<<W[i][j]<<" ";
outQuanFile<<"\n";
}
outQuanFile<<"B\n";
for(int ii=0;ii<ON;ii++)
{
for(int jj=0;jj<HN;jj++)
outQuanFile<<V[ii][jj]<<" ";
outQuanFile<<"\n";
}
outYuFile<<"输出层的阈值为:\n";
for(int k=0;k<ON;k++)
outYuFile<<YU_ON[k]<<" "; //输出层阈值写入文本
outYuFile<<"\n隐层的阈值为:\n";
for(int kk=0;kk<HN;kk++)
outYuFile<<YU_HN[kk]<<" "; //隐层阈值写入文本
outYuFile.close();
outQuanFile.close();
}
/**********************/
/**程序入口,即主程序**/
/**********************/
void main()
{
double sum_err;
int study=0;//训练次数
a1 = 0.5;
a2 = 0.1;
b1 = 0.5;
b2 = 0.1;
double Pre_error=0.001 ; //预定误差
GetTrainingData();
initial(); //隐层、输出层权、阈值初始化(1)
do
{
++study;
for (int m=0;m<N;m++)
{
Train_input_P(m); //输入第m个学习样本(2)
Train_input_T(m);//输入第m个样本的教师信号(3)
H_I_O(m); //第m个学习样本隐层各单元输入、输出值(4)
O_I_O(m); //第m个学习样本输出层各单元输
入、输出值(5)
Err_O_H(m); //第m个学习样本输出层至隐层一般化误差(6)
Err_H_I(m); //第m个学习样本隐层至输入层一般化误差(7)
} //全部样本训练完毕
Delta_O_H();
Delta_H_I();
sum_err=Err_Sum(); //全部样本全局误差计算(10)
cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;
}while(sum_err>Pre_error); //while (study<2000);//while ((sum_err > Pre_error)||study < 2000);
cout<<"网络已经学习了"<<study<<"次,学习的均方误差为"<<sum_err<<endl;
savequan();
GetTestingData();
for (int m=0;m<T_N;m++)
{
Test_input_P(m); //输入第m个检验样本
Test_input_T(m);//输入第m个样本的教师信号
H_I_O(m); //第m个检验样本隐层各单元输入、输出值
O_I_O(m); //第m个检验样本输出层各单元输入、输出值
out_test_result<<m<<"次检测输出结果:";
for(int i=0;i<ON;i++)
out_test_result<<O[i]<<" ";
out_test_result<<m<<"次理论输出结果为:";
for(int j=0;j<ON;j++)
out_test_result<<Test_Data[m].teach[j]<<" ";
out_test_result<<"\n";
// out_test_result.close();
}
}
(注:文档可能无法思考全面,请浏览后下载,供参考。
可复制、编制,期待你的好评与关注)。