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

📄 bpnet.cpp

📁 很好用的BP神经网络类
💻 CPP
字号:
 // BPNet.cpp: implementation of the CBPNet class.
//
//////////////////////////////////////////////////////////////////////

#include "BPNet.h"

#include <fstream.h>
#include <math.h>
#include <iomanip.h>
#include <time.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#include <WINDOWS.H>
CBPNet::CBPNet()
{
   Status=0;
   bCreated=false;
}

CBPNet::~CBPNet()
{
	
}

//void CBPNet::InitWeight()
//{
////    ifstream WeightFile("InitData.txt");
////	int i;
////	for(i=0;i<HidenLayerNum;i++)
////		WeightFile>>PowerIH[i];
////	for(i=0;i<HidenLayerNum;i++)
////		WeightFile>>PowerHO[i];
////	for(i=0;i<HidenLayerNum;i++)
////		WeightFile>>HidenLayerThreshold[i];
////	WeightFile>>OutLayerThreshold;
//}

//void CBPNet::GenerateStudyData()
//{
//	int k;
//    ofstream ofile("outfile.txt");
//	for(k=0;k<StudySampleNum;k++)
//	{
//		InputX[k]=k*(2*PI/(StudySampleNum-1));// 输入值
//		Teach[k]=(sin(InputX[k])+1)/PROPORTION; //计算教师的值
//		ofile<<InputX[k]<<"   "<<Teach[k]<<endl;
//		//Teach[k]=(sin(InputX[k])+1)/PROPORTION+(double)rand()/RAND_MAX/10; //计算教师的值
//	}
//	ofile.close();
//}

void CBPNet::CaculateOutput()
{
	int i,j,k;
	for(i=0;i<StudySampleNum;i++)
	{
		for(j=0;j<HidenLayerNum;j++)
			HidenLayerOut[i][j]=0;
		for(j=0;j<OutLayerNum;j++)
			OutputY[i][j]=0;
	}
	for(i=0;i<HidenLayerNum;i++)
	{
		for(j=0;j<StudySampleNum;j++)
		{
			for(k=0;k<InputLayerNum;k++)
				HidenLayerOut[j][i]+=PowerIH[k][i]*InputX[j][k]; //计算隐单元输出
			HidenLayerOut[j][i]=Sigmoid(HidenLayerOut[j][i]-HidenLayerThreshold[i]); //计算隐单元输出

		}
	}
	for(i=0;i<OutLayerNum;i++)
	{
		for(j=0;j<StudySampleNum;j++)
		{
			for(k=0;k<HidenLayerNum;k++)
				OutputY[j][i]+=PowerHO[k][i]*HidenLayerOut[j][k];
			OutputY[j][i]=Sigmoid(OutputY[j][i]-OutLayerThreshold[i]);
		}
	}
}

void CBPNet::CaculateError()
{
	int i,j,k;
	for(i=0;i<StudySampleNum;i++)
	{
		for(j=0;j<HidenLayerNum;j++)
			HidenLayerError[i][j]=0;
		for(j=0;j<OutLayerNum;j++)
			OutLayerError[i][j]=0;
	}
	
	for(i=0;i<OutLayerNum;i++)
	{
		for(j=0;j<StudySampleNum;j++)
			OutLayerError[j][i]=OutputY[j][i]*(1-OutputY[j][i])*(Teach[j][i]-OutputY[j][i]); //输出
	}

	for( i=0;i<HidenLayerNum;i++)
	{
		for(j=0;j<StudySampleNum;j++)
		{
			for(k=0;k<OutLayerNum;k++)
				HidenLayerError[j][i]+=OutLayerError[j][k]*PowerHO[i][k];//隐单元
			HidenLayerError[j][i]*=HidenLayerOut[j][i]*(1-HidenLayerOut[j][i]);
		}
	}
}

void CBPNet::AdjustWeight()
{
	int i,j,k;
	double deltw,deltt;
//	for(i=0;i<HidenLayerNum;i++)
//	{
//		for()
//		temp=PowerHO[i];
//		for(j=0;j<InputLayerNum;j++)
//		{
//			for(k=0;k<StudySampleNum;k++)
//			{
//				
//				PowerHO[i]+=m_Step*OutLayerError[k]*HidenLayerOut[i][k];
//				
//			}
//		}
//		PowerHO[i]+=m_coefficient_moment*(PowerHO[i]-last_w2[i]);
//		last_w2[i]=temp;
//
//	}
    ///////////////////调整输入到隐层////////////
	if(m_n==10018)
	{
		int m;
		m=1;
	}
    for(i=0;i<InputLayerNum;i++)
	{
		for(j=0;j<HidenLayerNum;j++)
		{
			deltw=PowerIH[i][j]-Last_PowerIH[i][j];
			Old_Last_PowerIH[i][j]=Last_PowerIH[i][j];
			Last_PowerIH[i][j]=PowerIH[i][j];
			for(k=0;k<StudySampleNum;k++)
				PowerIH[i][j]+=m_Step*InputX[k][i]*HidenLayerError[k][j];
			PowerIH[i][j]+=deltw*m_coefficient_moment;
		}
		
	}
    for(i=0;i<HidenLayerNum;i++)
	{
		deltt=HidenLayerThreshold[i]-Last_HidenLayerThreshold[i];
		Old_Last_HidenLayerThreshold[i]=Last_HidenLayerThreshold[i];
		Last_HidenLayerThreshold[i]=HidenLayerThreshold[i];
		for(k=0;k<StudySampleNum;k++)
			HidenLayerThreshold[i]+=m_Step*(-1)*HidenLayerError[k][i];
		HidenLayerThreshold[i]+=deltt*m_coefficient_moment;
	}
    ////////////////////////////////////////////////////
	//////////////////调整隐层到输出层/////////////////////////
    for(i=0;i<HidenLayerNum;i++)
	{
		for(j=0;j<OutLayerNum;j++)
		{
			deltw=PowerHO[i][j]-Last_PowerHO[i][j];
			Old_Last_PowerHO[i][j]=Last_PowerHO[i][j];
			Last_PowerHO[i][j]=PowerHO[i][j];
			for(k=0;k<StudySampleNum;k++)
				PowerHO[i][j]+=m_Step*HidenLayerOut[k][i]*OutLayerError[k][j];
			PowerHO[i][j]+=deltw*m_coefficient_moment;
		}
	}
	for(i=0;i<OutLayerNum;i++)
	{
		deltt=OutLayerThreshold[i]-Last_OutLayerThreshold[i];
		Old_Last_OutLayerThreshold[i]=Last_OutLayerThreshold[i];
		Last_OutLayerThreshold[i]=OutLayerThreshold[i];
		for(k=0;k<StudySampleNum;k++)
		   OutLayerThreshold[i]+=m_Step*(-1)*OutLayerError[k][i];
		OutLayerThreshold[i]+=deltt*m_coefficient_moment;
	}
	//////////////////////////////////////////////////////
//	temp1=OutLayerThreshold;
//	for(j=0;j<StudySampleNum;j++)
//		OutLayerThreshold+=m_Step*OutLayerError[j]*(-1);
//	OutLayerThreshold+=m_coefficient_moment*(OutLayerThreshold-last_p);
//	last_p=temp1;
//
//
//	for(i=0;i<HidenLayerNum;i++)
//	{
//		temp=PowerIH[i];
//		temp1=HidenLayerThreshold[i];
//		for(j=0;j<StudySampleNum;j++)
//		{
//			PowerIH[i]+=m_Step*HidenLayerError[i][j]*InputX[j];
//			HidenLayerThreshold[i]+=m_Step*HidenLayerError[i][j]*(-1);
//		}
//		PowerIH[i]+=m_coefficient_moment*(PowerIH[i]-last_w1[i]);
//		HidenLayerThreshold[i]+=m_coefficient_moment*(HidenLayerThreshold[i]-last_q[i]);
//		last_w1[i]=temp;
//		last_q[i]=temp1;
//	
//	}
}

double CBPNet::CaculateTotalError()
{
    double E=0;
	int i,j;
	for(i=0;i<OutLayerNum;i++)
	{
		for(j=0;j<StudySampleNum;j++)
			E+=0.5*(Teach[j][i]-OutputY[j][i])*(Teach[j][i]-OutputY[j][i]);
	}
	return E;
}

double CBPNet::Sigmoid(double u)
{
    return 1/(1+exp(-u));
}

void CBPNet::Study()
{
	////////////变量定义/////////////////
    int i,j,k;
	Status=1;
	Ez=1;
	EzLast=100;
	nSendNum=0;
	double EzLast300=0;
    m_n=0;
	nSendNum=0;
	int add=0;
	int subtract=0;
	int tag=0;
  	if(m_Method==VOGL)
	{
		ofstream VoglFile("VoglError.txt");
		m_Step=0.2;
		CaculateOutput();
		do{
			m_n++;
			CaculateError();
			AdjustWeight();
			EzLast=Ez;
			Ez=CaculateTotalError();
			//if(true)   //可变学习步长和动量项
			//{
				
				if(Ez-EzLast<=0)
				{
					add++;
					subtract=0;
				}
				else 
				{
					subtract++;
					add=0;
				}
				
				if(add>=5)
				{
					if(m_Step<0.9)
						m_Step+=0.001;
					add=0;
				//	subtract=0;
					m_coefficient_moment=0.9;
					
				}
				
				if(subtract>=5)
				{
					if(m_Step>0.01)
						m_Step*=0.5;
				//	add=0;
					subtract=0;
					m_coefficient_moment=0;
					
				}
				
				
			//}
			CaculateOutput();
			if(nSendNum==1)
			{
				VoglFile<<Ez<<" ";
				sInfo.ErrorNo=nSendNum;
				sInfo.StudyNum=m_n;
				sInfo.TotleError=Ez;
				::SendMessage(m_hFWnd,UM_CHANGEINFO,(WPARAM)&sInfo,NULL);
				nSendNum++;
			}
			if(m_n%200==0)
			{
				VoglFile<<Ez<<" ";
				sInfo.ErrorNo=nSendNum;
				sInfo.StudyNum=m_n;
				sInfo.TotleError=Ez;
				::SendMessage(m_hFWnd,UM_CHANGEINFO,(WPARAM)&sInfo,NULL);
				nSendNum++;
			}
			cout<<"学习次数:"<<m_n<<'\t'<<"当前误差:"<<Ez<<endl;

		}while(Ez>m_MinError);
		VoglFile.seekp(0,ios::beg);
		VoglFile<<nSendNum<<" ";
		VoglFile<<m_n<<" ";
	}
	if(m_Method==NORMAL)
	{
		
		ofstream NormalFile("NormalError.txt");
		CaculateOutput();
		do{
			m_n++;
			CaculateError();
			AdjustWeight();
			Ez=CaculateTotalError();
			CaculateOutput();
			if(nSendNum==1)
			{
				NormalFile<<Ez<<" ";
				sInfo.ErrorNo=nSendNum;
				sInfo.StudyNum=m_n;
				sInfo.TotleError=Ez;
				::SendMessage(m_hFWnd,UM_CHANGEINFO,(WPARAM)&sInfo,NULL);
				nSendNum++;
			}
			if(m_n%200==0)
			{
				NormalFile<<Ez<<" ";
				sInfo.ErrorNo=nSendNum;
				sInfo.StudyNum=m_n;
				sInfo.TotleError=Ez;
				::SendMessage(m_hFWnd,UM_CHANGEINFO,(WPARAM)&sInfo,NULL);
				nSendNum++;
			}
			cout<<m_n<<'\t'<<Ez<<endl;
		}while(Ez>m_MinError);
		NormalFile.seekp(0,ios::beg);
		NormalFile<<nSendNum<<" ";
		NormalFile<<m_n<<" ";
	}
	
}

void CBPNet::Test(double *Input,double *Output)
{
    int i,j;
	double *hh;
    for(i=0;i<InputLayerNum;i++)
		Input[i]=Input[i]/MaxInputX[i]*SCALE;
	hh=new double[HidenLayerNum];
	memset(hh,0,sizeof(double)*HidenLayerNum);
	memset(Output,0,sizeof(double)*OutLayerNum);
	for(i=0;i<HidenLayerNum;i++)
	{
		for(j=0;j<InputLayerNum;j++)
		{
			hh[i]+=Input[j]*PowerIH[j][i];
		}	
		hh[i]=Sigmoid(hh[i]-HidenLayerThreshold[i]);
	}
	for(i=0;i<OutLayerNum;i++)
	{
		for(j=0;j<HidenLayerNum;j++)
		{
			Output[i]+=hh[j]*PowerHO[j][i];
		}
		Output[i]=Sigmoid(Output[i]-OutLayerThreshold[i]);
		Output[i]=Output[i]*MaxOutputY[i]/SCALE;
	}
	delete []hh;
}

void CBPNet::CreateBPNet(HWND hWnd,int Inum,int Hnum,int Onum)
{
	////////////////////
	int i,j;
	m_hFWnd=hWnd;
	InputLayerNum=Inum;
	HidenLayerNum=Hnum;
	OutLayerNum=Onum;
	//////////////////////////////////////////////////
	MaxInputX=new double [Inum];
	MaxOutputY=new double [Onum];
	////////////////////////////////////////////////////////
	PowerIH=new double*[InputLayerNum];
	Last_PowerIH=new double*[InputLayerNum];
	Old_Last_PowerIH=new double*[InputLayerNum];
	for(i=0;i<InputLayerNum;i++)
	{
		PowerIH[i]=new double[HidenLayerNum];
		Last_PowerIH[i]=new double[HidenLayerNum];
		Old_Last_PowerIH[i]=new double[HidenLayerNum];
	}
	////////////////////////////////////////////////////////////
	PowerHO=new double* [HidenLayerNum];
	Last_PowerHO=new double*[HidenLayerNum];
	Old_Last_PowerHO=new double*[HidenLayerNum];
	for(i=0;i<HidenLayerNum;i++)
	{
		PowerHO[i]=new double[OutLayerNum];
		Last_PowerHO[i]=new double[OutLayerNum];
		Old_Last_PowerHO[i]=new double[OutLayerNum];
	}
	////////////////////////////////////////////////////////////////
	HidenLayerThreshold=new double [HidenLayerNum];
	Last_HidenLayerThreshold=new double [HidenLayerNum];
	Old_Last_HidenLayerThreshold=new double [HidenLayerNum];
	//////////////////////////////////////////////////////////
	OutLayerThreshold=new double [OutLayerNum];
	Last_OutLayerThreshold=new double[OutLayerNum];
	Old_Last_OutLayerThreshold=new double[OutLayerNum];
	////////////////////////////////////////////////////////////
	OutputY=new double* [HidenLayerNum];
	for(j=0;j<HidenLayerNum;j++)
	{
		OutputY[j]=new double[OutLayerNum];
	}
///////////////xxxxx	
	for(i=0;i<InputLayerNum;i++)
		for(j=0;j<HidenLayerNum;j++)
		{
			Last_PowerIH[i][j]=0;
			Old_Last_PowerIH[i][j]=0;
		}
	for(i=0;i<HidenLayerNum;i++)
		for(j=0;j<OutLayerNum;j++)
		{
			Last_PowerHO[i][j]=0;
			Old_Last_PowerHO[i][j]=0;
		}
	for(i=0;i<HidenLayerNum;i++)
	{
		Last_HidenLayerThreshold[i]=0;
		Old_Last_HidenLayerThreshold[i]=0;
	}
	for(i=0;i<OutLayerNum;i++)
	{
		Last_OutLayerThreshold[i]=0;
		Old_Last_OutLayerThreshold[i]=0;
	}
//	//*********************产生随机权值域值*************************************
	srand(time(NULL));
	ofstream ofile("初始权值域值.txt");
	ofile<<"输入层到隐层权值:"<<endl;
	for(i=0;i<InputLayerNum;i++)
		for(j=0;j<HidenLayerNum;j++)
		{
			PowerIH[i][j]=(double)rand()/RAND_MAX;
			ofile<<PowerIH[i][j]<<" ";
		}
	ofile<<endl<<"隐层到输出层权值:"<<endl;
	for(i=0;i<HidenLayerNum;i++)
		for(j=0;j<OutLayerNum;j++)
		{
			PowerHO[i][j]=(double)rand()/RAND_MAX;
			ofile<<PowerHO[i][j]<<" ";
		}
	ofile<<endl<<"隐层域值:"<<endl;
    for(i=0;i<HidenLayerNum;i++)
	{
	    HidenLayerThreshold[i]=(double)rand()/RAND_MAX;
		ofile<<HidenLayerThreshold[i]<<" ";
	}
	ofile<<endl<<"输出层域值:"<<endl;
	for(i=0;i<OutLayerNum;i++)
	{
		OutLayerThreshold[i]=(double)rand()/RAND_MAX;
		ofile<<OutLayerThreshold[i]<<" ";
	}
	//*****************************************************************
//	char str[100];
//	ifstream Infile("initWeight.txt");
//	Infile>>str;
//	for(i=0;i<InputLayerNum;i++)
//		for(j=0;j<HidenLayerNum;j++)
//			Infile>>PowerIH[i][j];
//		
//	Infile>>str;
//	for(i=0;i<HidenLayerNum;i++)
//		for(j=0;j<OutLayerNum;j++)
//			Infile>>PowerHO[i][j];
//	Infile>>str;
//    for(i=0;i<HidenLayerNum;i++)
//	    Infile>>HidenLayerThreshold[i];
//	Infile>>str;
//	for(i=0;i<OutLayerNum;i++)
//		Infile>>OutLayerThreshold[i];
	bCreated=true;
}
void CBPNet::SetBPParameter(double MinError,double InitStep,double InitMoment,int Method)
{
	m_MinError=MinError;
	m_Step=InitStep;
	m_coefficient_moment=InitMoment;
	m_Method=Method;
}
void CBPNet::SetStudySample(double **x,double **t,int number)
{

	int i,j;
	InputX=x;
	Teach=t;
	StudySampleNum=number;
	HidenLayerOut=new double* [StudySampleNum];
	HidenLayerError=new double* [StudySampleNum];
	for(i=0;i<StudySampleNum;i++)
	{
		HidenLayerOut[i]=new double[HidenLayerNum];
		HidenLayerError[i]=new double[HidenLayerNum];
	}
	OutputY=new double* [StudySampleNum];
	OutLayerError=new double*[StudySampleNum];
	for(i=0;i<StudySampleNum;i++)
	{
		OutputY[i]=new double [OutLayerNum];
		OutLayerError[i]=new double[OutLayerNum];
	}

	////////////////////////////////////////////////////////////
	for(i=0;i<InputLayerNum;i++)
	{
		MaxInputX[i]=0;
	}
	for(i=0;i<OutLayerNum;i++)
	{
		MaxOutputY[i]=0;
	}
    for(i=0;i<StudySampleNum;i++)
	{
		for(j=0;j<InputLayerNum;j++)
		{
			if(x[i][j]>MaxInputX[j])
				MaxInputX[j]=x[i][j];
		}
		for(j=0;j<OutLayerNum;j++)
		{
			if(t[i][j]>MaxOutputY[j])
				MaxOutputY[j]=t[i][j];
		}
	}
	for(i=0;i<StudySampleNum;i++)
	{
		for(j=0;j<InputLayerNum;j++)
		{
			x[i][j]=x[i][j]/MaxInputX[j]*SCALE;
		}
		for(j=0;j<OutLayerNum;j++)
		{
			t[i][j]=t[i][j]/MaxOutputY[j]*SCALE;
		}
	 }

 

}
void CBPNet::DeleteBDNet()
{
	delete []InputX;
	delete []OutputY;
	delete []Teach;
	delete []OutLayerError;
	delete []HidenLayerOut;
	delete []HidenLayerError;
	delete []PowerIH;
	delete []PowerHO;
	delete []HidenLayerThreshold;
//	delete []last_w1;
//	delete []last_w2;
//	delete []last_q;
//	delete []last_dw1;
//	delete []last_dw2;
//	delete []last_dq;
	delete []Last_PowerIH;
	delete []Last_PowerHO;
	delete []Last_HidenLayerThreshold;
	delete []Last_OutLayerThreshold;

}



void CBPNet::ReturnToLast()
{ 
	int i,j;
	for(i=0;i<InputLayerNum;i++)
	{
		for(j=0;j<HidenLayerNum;j++)
		{
			PowerIH[i][j]=Last_PowerIH[i][j];
			Last_PowerIH[i][j]=Old_Last_PowerIH[i][j];
		}
	}
	for(i=0;i<HidenLayerNum;i++)
	{
		for(j=0;j<OutLayerNum;j++)
		{
			PowerHO[i][j]=Last_PowerHO[i][j];
			Last_PowerHO[i][j]=Old_Last_PowerHO[i][j];
		}
	}
	for(i=0;i<HidenLayerNum;i++)
	{
		HidenLayerThreshold[i]=Last_HidenLayerThreshold[i];
		Last_HidenLayerThreshold[i]=Old_Last_HidenLayerThreshold[i];
	}
	for(i=0;i<OutLayerNum;i++)
	{
		OutLayerThreshold[i]=Last_OutLayerThreshold[i];
		Last_OutLayerThreshold[i]=Old_Last_OutLayerThreshold[i];
	}
	
}


⌨️ 快捷键说明

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