⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bp_algorithm.cpp

📁 基于MATLAB完成的神经网络源程序
💻 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 + -