BP网络函数逼近 C++实现

版权声明:所有文章都是自己编写整理,可以转载分享。--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"; 
	}
}

结果截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_32393347/article/details/86098597