📄 bpnet.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 + -