版权声明:所有文章都是自己编写整理,可以转载分享。--Zen in Zen https://blog.csdn.net/weixin_32393347/article/details/86098597
BP网络函数逼近
题目选择2)
流程图如下
源代码
//////////////////////////////////////////////////
//题目函数逼近(2)z=sin(x)sin(y)
//////////////////////////////////////////////////
///////////////////头文件////////////////////////
#include<iostream.h>
#include <math.h>
#include<fstream.h>
#include <time.h>
#include <stdlib.h>
#include <cstring>
//本BP网络采用三层神经网络,并且隐含层的结点数为3.样本数量为225
/////////////////定义全局变量//////////////////
double step=0.5,f,ne;//定义学习步长、平均误差
int pass=0,i,j,k;
double sigmoid(double x);//作用函数为S型函数
double DER_sigmoid (double z);//作用函数的导数
double x[225][2]={0.0};//样本输入
double X[225][3]={0};
double O2[225][3]={0.0};//第二层的输出
double X2[225][4]={0};//第三层的输入
double Y[225]={0};//理想输出
double y[225]={0.0};//实际输出
double E,max;//每次训练的200个样本误差累加,每次训练的最大误差
double W2[3][3]={0.0};//第2层网络的权值
double W3[4]={0.0};//第3层网络的权值
double derW2,derW1;//权值调整量
//double EN1[200][4]={0},EN2[225][3]={0}; //误差对W的偏导数,分别是第3层、第2层;
/////////////////////定义作用函数//////////////////////////////
double sigmoid(double x)//第2,3层作用函数
{
f=exp(x)/(exp(x)+1);
return f;
}
void main()
{
///////////////////////权值初始值///////////////////////
srand((unsigned)time(NULL));//以时间为种子
ofstream out("函数逼近(2)题.txt");//输出文件
out<<"输出隐含层连接权值初始值:"<<"\n";
for (i=0;i<3;i++)
{
for (j=0;j<3;j++)
{
W2[i][j]=(rand()%60);
W2[i][j]=W2[i][j]/100-0.3;//第2层权值初始值的设定在[-0.3,0.3]内取
out<<"W["<<i<<"]["<<j<<"]="<<W2[i][j]<<" ";
}
out<<"\n";
}
out<<"输出层权值初始值:"<<"\n";
for (i=0;i<4;i++)
{
W3[i]=(rand()%60);//第3层权值初始值的设定在[-0.3,0.3]内取
W3[i]=W3[i]/100-0.3;
out<<"W["<<i<<"]="<<W3[i]<<"\n";
}
out<<"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"<<"\n";
////////////////////////////取225个样本/////////
int n=0;
double D1=(3*3.1415926)/15;
double D2=(3*3.1415926)/16;
double x1[15]={0},y1[15]={0};
for (i=0;i<15;i++)
{
x1[i]=D1*n;//在[0,3pai]之间均匀取15个x
y1[i]=D2*(n+1);//在[0,3pai]之间均匀取15个y
n++;
}
i=0;
for (j=0;j<15;j++)
{
k=0;
while (k<15)
{
x[i][0]=x1[j];
x[i][1]=y1[k];
Y[i]=sin(x1[j])*sin(y1[k]);
k++;
i++;
}
}
///////////////////训练BP网络/////////////////////////
//////////////输入的X[225][3]/////////
for (i=0;i<225;i++)
{
for (j=0;j<3;j++)
{
switch(j)
{
case 0: X[i][0]=-1;
case 1:X[i][1]=x[i][0];
case 2:X[i][2]=x[i][1];
}
//out<<"输入X["<<i<<"]["<<j<<"]="<<X[i][j]<<" \n";
}
}
double e=0;
double p1,p2;//第2,3层的活化值
do
{
/////////////////////////网络学习//////////////////////////
e=0;
++pass;
for (i=0;i<225;i++)
{
for (j=0;j<3;j++)
{
p1=0;//第2层活化值置0
for (k=0;k<3;k++)
{
p1=p1+X[i][k]*W2[k][j];
}
O2[i][j]=sigmoid(p1);
//out<<"O2["<<i<<"]["<<j<<"]="<<O2[i][j]<<"\n";
}
}
///////////////第3层的输入/////////
for (i=0;i<225;i++)
{
for (k=0;k<4;k++)
{
switch(k)
{
case 0: X2[i][0]=-1;
case 1: X2[i][1]=O2[i][0];
case 2: X2[i][2]=O2[i][1];
case 3: X2[i][3]=O2[i][2];
}
//out<<"输入X2["<<i<<"]["<<k<<"]="<<X2[i][k]<<" \n";
}
p2=0;//第3层活化值置0
for (j=0;j<4;j++)
{
p2=p2+X2[i][j]*W3[j];
}
y[i]=sigmoid(p2);//实际输出
e=e+0.5*(Y[i]-y[i])*(Y[i]-y[i]);
ne=e/(i+1);
//////////////////////////权值修改/////////////////////////////////
for (j=0;j<4;j++)//第3层权值修改
{
double x1=0;
x1=x1-(Y[i]-y[i])*y[i]*(1-y[i])*X2[i][j];
W3[j]=W3[j]-step*x1;
}
for (k=0;k<3;k++)
{
for (j=0;j<3;j++)//第2层权值修改
{
double x2=0;
x2=x2-O2[i][k]*(1-O2[i][k])*(Y[i]-y[i])*y[i]*(1-y[i])*X[i][j];
W2[j][k]=W2[j][k]-step*x2;
}
}
}
} while(ne>0.02&&pass<6000);
out<<"训练样本次数:"<<pass<<" 小于最大训练6000次数,结果可靠!\n";
out<<"最大误差:"<<ne<<"\n";
out<<"最后一个周期200个样本的误差累计和为:"<<e<<"\n";
out<<"输出隐含层连接权值:"<<"\n";
for (i=0;i<3;i++)
{
for (j=0;j<4;j++)
{
out<<"W["<<i<<"]["<<j<<"]="<<W2[i][j]<<" ";
}
out<<"\n";
}
out<<"输出层权值:"<<"\n";
for (j=0;j<4;j++)
{
out<<"W["<<j<<"]="<<W3[j]<<"\n";
}
/////////////////验证第3个样本/////////
{
i=3;
for (j=0;j<3;j++)
{
p1=0.0;//第2层活化值置零
for (k=0;k<3;k++)
{
p1=p1+X[i][k]*W2[k][j];
}
O2[i][j]=sigmoid(p1);
out<< O2[i][j]<<" \n";
}
for (k=0;k<4;k++)
{
switch(k)
{
case 0: X2[i][0]=-1;
case 1: X2[i][1]=O2[i][0];
case 2: X2[i][2]=O2[i][1];
case 3: X2[i][3]=O2[i][2];
}
out<<"输入X2["<<i<<"]["<<k<<"]="<<X2[i][k]<<" \n";
}
p2=0.0;//第3层活化值置零
for (j=0;j<4;j++)
{
p2=p2+X2[i][j]*W3[j];
}
y[i]=sigmoid(p2);//实际输出
e=fabs(Y[i]-y[i]);
out<<"第三个样本的误差e:"<<e<<"\n";
}
}