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

📄 bp.cpp

📁 一个我做的BP神经网用于分类和测试的程序。是一个我第一个独立完成的程序。希望对大家有所帮助!
💻 CPP
字号:
// BP.cpp: implementation of the CBP class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "stdlib.h"
#include "time.h"
#include "BP.h"
#include <math.h>
#include<iostream>

using namespace std;

#define BP_LEARNING	(float)(0.6)	// 学习系数

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBP::CBP()
{
	
}

CBP::~CBP()
{
	
}

CBP::CBP(int f,int sh,int be,int layer)
{
	front=f;
	shadow=sh;
	behind=be;
	layernumber=layer;
	
}

void CBP::initial()
{
	int i,j;
	first=(double**)calloc(shadow,sizeof(double*));   //输入层权值数组分配内存
	for(i=0;i<shadow;i++)
	{
		first[i]=(double*)calloc(front,sizeof(double));
	}
	
	srand((unsigned)time(NULL));
	for(i=0;i<shadow;i++)                               //给权值分配随机数
		for(j=0;j<front;j++)
		{
			 first[i][j]=rand()/32767.0;
		/*	first[i][j]=0.09;*/
/*			cout<<first[i][j]<<endl;*/
		}
		second=(double**)calloc(behind,sizeof(double*));        //隐含层到输出层权值开辟动态空间
		for(i=0;i<behind;i++)
		{
			second[i]=(double*)calloc(shadow,sizeof(double));
		}
		for(i=0;i<behind;i++)                                   //隐含层到输出层权值赋随机值
			for(j=0;j<shadow;j++)
			{
				second[i][j]=rand()/32767.0;
				/*second[i][j]=0.08;*/
				
			}
			
			yuzhi1=(double*)calloc(shadow,sizeof(double));
			yuzhi2=(double*)calloc(behind,sizeof(double));
			for(i=0;i<shadow;i++)
			{
				yuzhi1[i]=rand()/32767.0;
				/*yuzhi1[i]=0.05;*/                           //域值统一赋为0.05
			}
			for(i=0;i<behind;i++)
			{
				yuzhi2[i]=rand()/32767.0;
				/*yuzhi2[i]=0.05;*/                         //域值统一赋为0.05
			}
		behindlayer=pow(2,behind);	
		firstweight=(double ***)calloc(behindlayer,sizeof(double **));
		for(i=0;i<behindlayer;i++)
		{
			*(firstweight+i)=(double **)calloc(shadow,sizeof(double *));
		}
		for(i=0;i<behindlayer;i++)
			for(j=0;j<shadow;j++)
			{
				*(*(firstweight+i)+j)=(double *)calloc(front,sizeof(double));
			}
		secondweight=(double ***)calloc(behindlayer,sizeof(double **));
		for(i=0;i<behindlayer;i++)
		{
			*(secondweight+i)=(double **)calloc(behind,sizeof(double *));
		}
		for(i=0;i<behindlayer;i++)
			for(j=0;j<behind;j++)
			{
				*(*(secondweight+i)+j)=(double *)calloc(shadow,sizeof(double));
			}

// 	for(i=0;i<behind;i++)
// 	{
// 		Node[i]=0;
// 	}		
/*	Noderesult=(int *)calloc(behind,sizeof(int));*/
// 	for(i=0;i<behind;i++)
// 	{
// 		Noderesult[i]=0;
// 	}
	
}
/*******************************************************************************/
//weidu是训练样本的个数
//inputarry是训练样本的数组
/******************************************************************************/
double CBP::Train_everynet(int z)
{
	int i,j;
	double *shinput;          //隐含层输入值
	double *shoutput;         //隐含层输出值
	double *beinput;          //输出层输入值
	double *beoutput;          //输出层实际输出
	double *deltas;            //输出层误差
	double *shadowdeltas;      //隐含层误差
	double  m=0.0;
	shinput= (double*)calloc(shadow,sizeof(double));
	shoutput= (double*)calloc(shadow,sizeof(double));
	beinput= (double*)calloc(behind,sizeof(double));
	beoutput= (double*)calloc(behind,sizeof(double));
	deltas= (double*)calloc(behind,sizeof(double));
	shadowdeltas= (double*)calloc(shadow,sizeof(double));
	
	
//     shuru= (double*)calloc(front,sizeof(double));
// 	for(j=0;j<front;j++)
// 	{
// 		// (*(shuru+j))=(*(inputarry+j));    //输入层的值由外部输入数组赋予
// 		shuru[j]=inputarry[j];
// 	}
	//正向传输
	for(i=0;i<shadow;i++)
	{
		for(j=0;j<front;j++)
		{
			shinput[i]+=first[i][j]*shuru[z][j];         
		}
		shoutput[i]=func(shinput[i]+yuzhi1[i]);
	}
	for(i=0;i<behind;i++)
	{
		for(j=0;j<shadow;j++)
		{
			beinput[i]+=second[i][j]*shoutput[j];
			
		}
		beoutput[i]=func(beinput[i]+yuzhi2[i]);
	}
	//反向传输
	//先求输出层误差
	
	for(i=0;i<behind;i++)
	{
		deltas[i]=beoutput[i]*(1-beoutput[i])*(shuru[z][front+i]-beoutput[i]);
		
	}
	//再求隐含层误差
	for(i=0;i<shadow;i++)
	{
		double  zhongjian=0;
		for(j=0;j<behind;j++)
		{
			
			zhongjian+=deltas[j]*second[j][i];
			
		}
		shadowdeltas[i]=zhongjian*(1-shoutput[i])*shoutput[i];
	}
	//权值调整
	for(i=0;i<behind;i++)          //输出和隐含层之间权值的调整
		for(j=0;j<shadow;j++)
		{
			second[i][j]+=BP_LEARNING*deltas[i];
		}
	for(i=0;i<shadow;i++)
		for(j=0;j<front;j++)
		{
			first[i][j]+=BP_LEARNING*deltas[i]*shoutput[i];
		}
						
	for(j=0;j<behind;j++)
	{
		m+=(shuru[z][front+j]-beoutput[j])*(shuru[z][front+j]-beoutput[j]);
	}
//	double *shinput;          //隐含层输入值
//	double *shoutput;         //隐含层输出值
//	double *beinput;          //输出层输入值
//	double *beoutput;          //输出层实际输出
//	double *deltas;            //输出层误差
//	double *shadowdeltas;      //隐含层误差
//	shuru		;*inputarry


//	cout << *shinput << "  " << *shoutput << "  " << *beinput << "  " << *beoutput << "  " << *deltas << "  " << *shuru << "  " << endl;
//	system("pause");

	free(shinput);
	free(shoutput);
	free(beinput);
	free(beoutput);
	free(deltas);
 	free(shadowdeltas);
// 	free(shuru);

	return m;
}


double CBP::func(double num)
{
	return (double)(1/(1+exp(-num)));
}



void CBP::Trainnet(double **inputarry)
{
	int i,j;
	int member=0;
	int flag=100;
	double m=100.0;
	shuru=(double **)calloc(layernumber,sizeof(double*));
	for(i=0;i<layernumber;i++)
	{
		*(shuru+i)=(double *)calloc((front+behind),sizeof(double));
	}
	for(i=0;i<layernumber;i++)
		for(j=0;j<(front+behind);j++)
		{
			shuru[i][j]=inputarry[i][j];
		}
		while(m>0.4)
		{
		  for(i=0;i<layernumber;i++)
           m=Train_everynet(i);
		  member++;
	 
		}
// 		for(i=0;i<shadow;i++)
// 		for(j=0;j<front;j++)
// 		{
// 			firstweight[l][i][j]=first[i][j];
// 			cout<<firstweight[l][i][j]<<endl;
// 		}
// 		for(i=0;i<behind;i++)
// 			for(j=0;j<shadow;j++)
// 			{
// 				secondweight[l][i][j]=second[i][j];
// 				cout<<secondweight[l][i][j]<<endl;
// 			}
		cout<<"最终误差是"<<m<<endl;
		cout<<"迭代次数是"<<member<<endl;

		free(shuru);

	  
}

void  CBP::test_everynet(double *inputunarray)
{
  	int i,j;
	int flag=1000;
	double *shinput;          //隐含层输入值
	double *shoutput;         //隐含层输出值
	double *beinput;          //输出层输入值
	double *beoutput;          //输出层实际输出
// 	double *deltas;            //输出层误差
// 	double *shadowdeltas;      //隐含层误差
	double  m=0.0;
	Node=(int *)calloc(behind,sizeof(int));
	shinput= (double*)calloc(shadow,sizeof(double));
	shoutput= (double*)calloc(shadow,sizeof(double));
	beinput= (double*)calloc(behind,sizeof(double));
	beoutput= (double*)calloc(behind,sizeof(double));
// 	deltas= (double*)calloc(behind,sizeof(double));
// 	shadowdeltas= (double*)calloc(shadow,sizeof(double));
	
	
//     shuru1= (double**)calloc(,sizeof(double));
//  	for(j=0;j<front;j++)
//  	{
//  		// (*(shuru+j))=(*(inputarry+j));    //输入层的值由外部输入数组赋予
//  		shuru[j]=inputarry[j];
//  	}
//     while(l<z)
// 	{
	   for(i=0;i<shadow;i++)
	   {   
		for(j=0;j<front;j++)
		{
			shinput[i]+=first[i][j]*inputunarray[j];         
		}
		shoutput[i]=func(shinput[i]+yuzhi1[i]);
	   }
	for(i=0;i<behind;i++)
	{
		for(j=0;j<shadow;j++)
		{
			beinput[i]+=second[i][j]*shoutput[j];
			
		}
		beoutput[i]=func(beinput[i]+yuzhi2[i]);
// 		for(j=0;j<behind;j++)
// 	{
// 		m+=(beoutput[j])*(beoutput[j]);
// 	}
		if(beoutput[i]<0.3) 
		{
			Node[i]=0;
/*			flag=0;*/
		}
	    if(beoutput[i]>0.9)
		{
			Node[i]=1;
/*			flag=0;*/
		}
		cout<<"This pattern has output: "<<endl;
        for(i=0;i<behind;i++)
		{
			cout<<beoutput[i]<<' ';
		}
		cout<<endl;
		for(i=0;i<behind;i++)
		{
			cout<<Node[i]<<' ';
		}
		cout<<endl;
		    /*cout<<"is patter!"<<endl;*/	
	}
/*	}*/

	  
//	double *shinput;          //隐含层输入值
//	double *shoutput;         //隐含层输出值
//	double *beinput;          //输出层输入值
//	double *beoutput;          //输出层实际输出
//	double *deltas;            //输出层误差
//	double *shadowdeltas;      //隐含层误差
//	shuru		;*inputarry


//	cout << *shinput << "  " << *shoutput << "  " << *beinput << "  " << *beoutput << "  " << *deltas << "  " << *shuru << "  " << endl;
//	system("pause");

	free(shinput);
	free(shoutput);
	free(beinput);
	free(beoutput);
	free(Node);
// 	free(deltas);
//  	free(shadowdeltas);
// 	free(shuru);
}

⌨️ 快捷键说明

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