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

📄 bpnetmulti.cpp

📁 BP神经网络
💻 CPP
字号:
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>

int nSamplesNum = 0;                //样本数量
int nNodesOfInput = 0;              //样本维数,等同于输入层的神经元的个数
int nNodesOfHide = 0;               //隐层神经元的个数
int nNodesOfOutput = 0;             //输出层神经元的个数

//
double **pDataSource = NULL;               //输入的训练数据
double **pDataDesti = NULL;                //输入的目标数据

//关于隐层的定义
double **pOutOfHide = NULL;                     //隐层的输出

//关于输出层的定义
double **pOutOfOutput = NULL;                   //输出层的输出

//阀值
double *pThrOfOutput = NULL;                   //输出层的阀值
double *pThrOfHide = NULL;                     //隐层的阀值

double *pOldThrOfOutput = NULL;                //上次输出层的阀值
double *POldThrOfHide = NULL;

//权值的定义
double **pPowHi2In = NULL;                     //输入层到隐层的权值
double **pPowOu2Hi = NULL;                     //隐层到输入层的权值

double **pOldPowHi2In = NULL;
double **pOldPowOu2Hi = NULL;

//学习率
double LearnOu2Hi = 0;                      //输出层至隐层的学习效率
double LearnHi2In = 0;                      //隐层至输入层的学习效率

//误差
double Pre_Error = 0;                       //预期误差
double Sum_Error = 0;                       //每次的总体误差
double Old_Sum_Error = 0;
long int Study = 0;                         //学习次数
//
double alpha;                           //动量因子,改进型bp算法使用


FILE *fp;
//
void GetData();
void InitializeNet();
void TrainNet();
void Input_Source(int m);
void Input_Desti(int m);
void Input_Hide();
void Hide_Output();
void Error_Output_Hide(int m);
void Error_Hide_Input(int m);
double Delta_K_L_P( int k,int l,int p );
double Delta_J_K_P(int j,int k,int p);

void Delta_Output_Hide();
void Delta_Hide_Input();
double Error_Sum();

void main ()
{
	int i,j,k;
	i=j=k=0;

	nNodesOfInput = 9;
	nNodesOfOutput = 9;

// 	nNodesOfHide = int((nNodesOfInput+nNodesOfOutput)/2.0+0.5);

	nNodesOfHide = 16;

	nSamplesNum = 9;
	//
	Pre_Error = 0.0000001;

//	LearnHi2In = 0.9*nSamplesNum;
//	LearnOu2Hi = 0.9*nSamplesNum;


	LearnHi2In = 0.9;
	LearnOu2Hi = 0.9;

	alpha = 0.5;

	Study = 0;
	Sum_Error = 0;
	

	//申请内存
	//数据
	pDataSource = new double *[nSamplesNum];
	for ( i=0;i<nSamplesNum;i++ )
	{
		pDataSource[i] = new double [nNodesOfInput];
	}

	pDataDesti = new double *[nSamplesNum];
	for ( i=0;i<nSamplesNum;i++ )
	{
		pDataDesti[i] = new double [nNodesOfOutput]; 
	}

    //关于隐层的定义
	pOutOfHide = new double *[nSamplesNum];
	for ( i=0;i<nSamplesNum;i++ )
	{
		pOutOfHide[i] = new double [nNodesOfHide];
	}

	//关于输出层的定义
	pOutOfOutput = new double *[nSamplesNum];
	for ( i=0;i<nSamplesNum;i++ )
	{
		pOutOfOutput[i] = new double [nNodesOfOutput];
	}
    //阀值
	pThrOfHide = new double [nNodesOfHide];
	POldThrOfHide = new double [nNodesOfHide];

	pThrOfOutput = new double [nNodesOfOutput];
	pOldThrOfOutput = new double [nNodesOfOutput];

	//权值
	pPowHi2In = new double *[nNodesOfHide];
	for ( i= 0;i<nNodesOfHide;i++ )
	{
		pPowHi2In[i] = new double [nNodesOfInput];
	}

	pOldPowHi2In = new double *[nNodesOfHide];
	for ( i= 0;i<nNodesOfHide;i++ )
	{
		pOldPowHi2In[i] = new double [nNodesOfInput];
	}

	pPowOu2Hi = new double *[nNodesOfOutput];
	for ( i=0;i<nNodesOfOutput;i++ )
	{
		pPowOu2Hi[i] = new double [nNodesOfHide];
	}

	pOldPowOu2Hi = new double *[nNodesOfOutput];
	for ( i=0;i<nNodesOfOutput;i++ )
	{
		pOldPowOu2Hi[i] = new double [nNodesOfHide];
	}
	//
	GetData();
	InitializeNet();
	TrainNet();

	//释放内存
	//数据
	for ( i=0;i<nSamplesNum;i++)
	{
		delete [] pDataSource[i];
	}
	delete []pDataSource;

	for ( i=0;i<nSamplesNum;i++)
	{
		delete [] pDataDesti[i];
	}
	delete []pDataDesti;

    //关于隐层的定义
	for ( i=0;i<nSamplesNum;i++)
	{
		delete [] pOutOfHide[i];
	}
	delete []pOutOfHide;

	//关于输出层的定义
	for ( i=0;i<nSamplesNum;i++)
	{
		delete [] pOutOfOutput[i];
	}
	delete []pOutOfOutput;

    //阀值
	delete []pThrOfHide;
	delete []POldThrOfHide;

	delete []pThrOfOutput;
	delete []pOldThrOfOutput;

	//权值
	for ( i=0;i<nNodesOfHide;i++)
	{
		delete [] pPowHi2In[i];
	}
	delete []pPowHi2In;

	for ( i=0;i<nNodesOfHide;i++)
	{
		delete [] pOldPowHi2In[i];
	}
	delete []pOldPowHi2In;
	
	for ( i=0;i<nNodesOfOutput;i++ )
	{
		delete [] pPowOu2Hi[i];
	}
	delete []pPowOu2Hi;

	for ( i=0;i<nNodesOfOutput;i++ )
	{
		delete [] pOldPowOu2Hi[i];
	}
	delete []pOldPowOu2Hi;
}
void TrainNet()
{
	bool Flag_IsOK = 0;                          //判断是否达到要求
	double Sum_Error_bak1 = 0.;
	double Sum_Error_bak2 = 0.;
	do 
	{
		Input_Hide();
		Hide_Output();

		Old_Sum_Error = Sum_Error;
		Sum_Error = Error_Sum();
		Study++;
		if(Study%100 ==0 )
		{
			printf("Study = %d,  Sum_Error = %lf\n",Study,Sum_Error);
		}
		if ( Study > 20000000 )
		{
			printf("The program is ended by itself because of error!\nThe learning times is surpassed!\n");
			break ;
		}
		if ( Sum_Error<= Pre_Error )
		{
			Flag_IsOK = 1;
		}
		else
		{
			Delta_Output_Hide();
			Delta_Hide_Input();
		}

		//动态修正学习率
		if ((Sum_Error == Sum_Error_bak1)&&(Sum_Error_bak1 == Sum_Error_bak2))
		{
			LearnHi2In = 0.8*LearnHi2In;
			LearnOu2Hi = 0.8*LearnOu2Hi;
		}
		Sum_Error_bak2 = Sum_Error_bak1;
		Sum_Error_bak1 = Sum_Error;

	} while( Flag_IsOK ==0 );

	printf("Study = %d,  Sum_Error = %lf  ,Pre_Error = %lf\n",Study,Sum_Error,Pre_Error );


	if((fp=fopen("result.txt","w"))==NULL)
	{
		printf("Cannot open file 'result.txt'!\n strike any key exit! \n");
		getch();
		exit(1);
	}

	fprintf( fp,"Study = %d,  Sum_Error = %lf  ,Pre_Error = %lf\n",Study,Sum_Error,Pre_Error );
	fclose( fp );


	if((fp=fopen("Hide_Input.txt","w"))==NULL)
	{
		printf("Cannot open file 'Hide_Input.txt'!\n strike any key exit! \n");
		getch();
		exit(1);
	}
	int i,j;

	fprintf( fp,"pPowHi2In\n" );
	for ( i=0;i<nNodesOfHide;i++ )
	{
		for ( j=0;j<nNodesOfInput;j++ )
		{
			fprintf( fp,"%5.4lf\t",pPowHi2In[i][j] );
		}
		fprintf( fp,"\n");
	}

	fprintf( fp,"\n");
	fprintf( fp,"\n");
	
	fprintf( fp,"pThrOfHide\n" );
	for ( i=0;i<nNodesOfHide;i++ )
	{
		fprintf( fp,"%5.4lf\t",pThrOfHide[i] );
	}
	fprintf( fp,"\n");
	fprintf( fp,"\n");
	fclose( fp );


	if((fp=fopen("Output_Hide.txt","w"))==NULL)
	{
		printf("Cannot open file 'Output_Hide.txt'!\n strike any key exit! \n");
		getch();
		exit(1);
	}

	fprintf( fp,"pPowOu2Hi\n" );
	for ( i=0;i<nNodesOfOutput;i++ )
	{
		for ( j=0;j<nNodesOfHide;j++ )
		{
			fprintf( fp,"%5.4lf\t",pPowOu2Hi[i][j] );
		}
		fprintf( fp,"\n");
	}

	fprintf( fp,"\n");
	fprintf( fp,"\n");
	
	fprintf( fp,"pThrOfOutput\n" );
	for ( i=0;i<nNodesOfOutput;i++ )
	{
		fprintf( fp,"%5.4lf\t",pThrOfOutput[i] );
	}
	fprintf( fp,"\n");
	fprintf( fp,"\n");
	
	fclose( fp );


}

double Error_Sum()
{
	int m,i;
	double total_err = 0;
	double err = 0;

	for ( m=0;m<nSamplesNum;m++ )
	{
		err = 0;
		for ( i=0;i<nNodesOfOutput;i++ )
		{
			err += pow((pDataDesti[m][i] - pOutOfOutput[m][i]),2);
		}
		total_err += err;
	}
	total_err /=2;

//	total_err /=nSamplesNum;

	return total_err;
}

void Delta_Hide_Input()
{
	int i,j,k,p;

	double temp = 0;

	for ( j=0;j<nNodesOfHide;j++ ) //隐层
	{
		for ( i=0;i<nNodesOfInput;i++ ) //输入层
		{
			//计算wji
			temp = 0;
			for ( p=0;p<nSamplesNum;p++ )
			{
				for ( k=0;k<nNodesOfOutput;k++ )
				{
					temp += ((pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]))
						*pPowOu2Hi[k][j]*pOutOfHide[p][j]*(1.0-pOutOfHide[p][j])*pDataSource[p][i];
				}
			}

//			temp /= nSamplesNum;
			pPowHi2In[j][i] += (alpha*(pPowHi2In[j][i]-pOldPowHi2In[j][i]))+ (LearnHi2In*temp);
			pOldPowHi2In[j][i] = pPowHi2In[j][i];
		}
	}

	for ( j=0;j<nNodesOfHide;j++ ) //隐层
	{
		//计算j
		temp = 0;
		for ( p=0;p<nSamplesNum;p++ )
		{
			for ( k=0;k<nNodesOfOutput;k++ )
			{
				temp += ((pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]))
					*pPowOu2Hi[k][j]*pOutOfHide[p][j]*(1.0-pOutOfHide[p][j]);
			}
		}

//		temp /= nSamplesNum;		

		pThrOfHide[j] -= (LearnHi2In*(pThrOfHide[j]-POldThrOfHide[j])+LearnHi2In*temp);
		POldThrOfHide[j] = pThrOfHide[j];
	}
	
}

double Delta_K_L_P( int k,int l,int p )
{
	double temp = 0;

	temp = (pDataDesti[p][l]-pOutOfOutput[p][l])*pOutOfOutput[p][l]*(1-pOutOfOutput[p][l]);

	return temp;
}

void Delta_Output_Hide()
{
	int k,j,p;

	double temp = 0;


	for ( k=0;k<nNodesOfOutput;k++ ) //输出层
	{
		for ( j=0;j<nNodesOfHide;j++ ) //隐层
		{
			temp = 0;
			for ( p=0;p<nSamplesNum;p++ )
			{
				temp += (pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k])*pOutOfHide[p][j];
			}

//			temp /= nSamplesNum;
			pPowOu2Hi[k][j] += (alpha*(pPowOu2Hi[k][j]-pOldPowOu2Hi[k][j]))+ (LearnOu2Hi*temp);
			pOldPowOu2Hi[k][j] = pPowOu2Hi[k][j];
		}
	}

	for ( k=0;k<nNodesOfOutput;k++ )
	{
		temp = 0;
		for ( p=0;p<nSamplesNum;p++ )
		{
			temp += (pDataDesti[p][k]-pOutOfOutput[p][k])*pOutOfOutput[p][k]*(1.0-pOutOfOutput[p][k]);
		}

//		temp /= nSamplesNum;
		pThrOfOutput[k] -= (LearnOu2Hi*(pThrOfOutput[k]-pOldThrOfOutput[k])+LearnOu2Hi*temp);

		pOldThrOfOutput[k] = pThrOfOutput[k];
	}
	


}

double Delta_J_K_P(int j,int k,int p)
{
	double temp = 0;
	for ( int l=0;l<nNodesOfOutput;l++ )
	{
		temp += Delta_K_L_P(k,l,p)*pOutOfHide[p][k]*(1-pOutOfHide[p][k]);
	}
	return temp;
}

void Hide_Output()
{
	int k,j,p;
	//
	for( p=0;p<nSamplesNum;p++) //样本
	{
		for ( k=0;k<nNodesOfOutput;k++ )
		{
			pOutOfOutput[p][k] = 0;
			for ( j=0;j<nNodesOfHide;j++ )
			{
				pOutOfOutput[p][k] += pPowOu2Hi[k][j]*pOutOfHide[p][j];
			}

			pOutOfOutput[p][k] -= pThrOfOutput[k];
		    pOutOfOutput[p][k] = 1.0 /( 1.0+exp( -pOutOfOutput[p][k] ) );
		}
	}
}

void Input_Hide()
{
	int i,j,p;
	//
	for( p=0;p<nSamplesNum;p++) //样本
	{
		for ( j=0;j<nNodesOfHide;j++ )
		{
			pOutOfHide[p][j] = 0;
			for ( i=0;i<nNodesOfInput;i++ )
			{
				pOutOfHide[p][j] += pPowHi2In[j][i]*pDataSource[p][i];
			}
			pOutOfHide[p][j] -= pThrOfHide[j];
		    pOutOfHide[p][j] = 1.0 /( 1.0+exp( -pOutOfHide[p][j] ) );
		}
	}
}


void InitializeNet()
{

	int i,j,k;
	i = j = k =0;
	for ( j=0;j<nNodesOfHide;j++ )
	{
		for ( i=0;i<nNodesOfInput;i++ )
		{
			pPowHi2In[j][i] = ((double(rand())/RAND_MAX)*2-1);
			pOldPowHi2In[j][i] =  pPowHi2In[j][i];
		}
	}

	for ( k=0;k<nNodesOfOutput;k++)
	{
		for ( j=0;j<nNodesOfHide;j++)
		{
			pPowOu2Hi[k][j] = ((double(rand())/RAND_MAX)*2-1);
			pOldPowOu2Hi[k][j] = pPowOu2Hi[k][j];
		}
	}

	for ( i=0;i<nNodesOfHide;i++ )
	{
 		pThrOfHide[i] = ((double(rand())/RAND_MAX)*2-1);


		POldThrOfHide[i] = pThrOfHide[i];
	}
	for ( i=0;i<nNodesOfOutput;i++ )
	{
 		pThrOfOutput[i] = ((double(rand())/RAND_MAX)*2-1);


		pOldThrOfOutput[i] = pThrOfOutput[i];
	}

	printf("InitializeNet over !\n");
}

void GetData()
{
	/*读取训练样本*/
	int i,j,k;
	double datr;
	datr = 0;
	i = j = k =0;

	if((fp=fopen("datas1.txt","r"))==NULL)
	{
		printf("Cannot open file 'datas1.txt'!\n strike any key exit! \n");
		getch();
		exit(1);
	}

	k = 0;
	i = j =0;

	while(fscanf(fp,"%lf",&datr)!=EOF)
	{
		if ( k<nSamplesNum*nNodesOfInput)
		{
			pDataSource[i][j] = datr;
			j++;
			if ( j==nNodesOfInput)
			{
				j = 0;
				i++;
			}
			k++;
		}
		else
		{
			if ( k == nSamplesNum*nNodesOfInput)
			{
				i = j =0;
			}

			pDataDesti[i][j] = datr;
			j++;
			if ( j==nNodesOfOutput)
			{
				j = 0;
				i++;
			}
			k++;
		}
	}
	fclose(fp);
	printf("\nThere are [%d] datats that have been loaded successfully!\n",k);
	return ;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -