📄 elman.cpp
字号:
// Elman.cpp: implementation of the CElman class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Elman.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CElman::CElman()
{
NI=6;
NO=1;
NH=12;
NSample=3043;
NStruct=12;
LoopTimes=600;
n=0.9;
A=0.1;
}
CElman::~CElman()
{
}
void CElman::InitiateMatrix()
{
W0=new double* [NStruct];
DW0=new double* [NStruct];
DW00=new double* [NStruct];
a0=new double* [NStruct];
for(unsigned int i=0;i<NStruct;i++)
{
W0[i]=new double[NH];
DW0[i]=new double[NH];
DW00[i]=new double[NH];
a0[i]=new double[NH];
}
W1=new double* [NI];//输入层到隐含层的权值
DW1=new double* [NI];//每一轮输入层到隐含层的权值的变化量
DW11=new double* [NI];//上一轮对连接权值的修整量
a1=new double* [NI];
for(unsigned int i1=0;i1<NI;i1++)
{
W1[i1]=new double[NH];
DW1[i1]=new double[NH];
DW11[i1]=new double[NH];
a1[i1]=new double[NH];
}
W2=new double* [NH];// 隐含层到输出层的权值
DW2=new double* [NH];//每一轮 隐含层到输出层的权值的变化量
DW22=new double* [NH];//上一轮对连接权值的修整量
a2=new double* [NH];
for(unsigned int i2=0;i2<NH;i2++)
{
W2[i2]=new double[NO];
DW2[i2]=new double[NO];
DW22[i2]=new double[NO];
a2[i2]=new double[NO];
}
//三层神经元的输入
Pi=new double* [NSample];
Po=new double* [NSample];
Ph=new double* [NSample];
Xh=new double* [NSample];
Xo=new double* [NSample];
//神经网络的期望输出
T=new double* [NSample];
XStructure=new double* [NSample];
Qh=new double* [NSample];//隐层和输出层神经元的输出
Qo=new double* [NSample];//对应于各连接值的delta
PrePi=new double* [NSample];
PreT=new double* [NSample];//对应于各连接值的delta
for(unsigned int i3=0;i3<NSample;i3++)
{
Ph[i3]=new double[NH];
Pi[i3]=new double[NI];
Po[i3]=new double[NO];
T[i3]=new double[NO];
Xh[i3]=new double[NH];
Xo[i3]=new double[NO];
XStructure[i3]=new double[NStruct];
Qh[i3]=new double[NH];
Qo[i3]=new double[NO];
PrePi[i3]=new double[NI];
PreT[i3]=new double[NO];
}
XhOld=new double* [NSample+1];
for(unsigned int i4=0;i4<NSample+1;i4++)
{
XhOld[i4]=new double[NH];
}
XOldstructure=new double* [NSample+1];
for(unsigned int i5=0;i5<NSample+1;i5++)
{
XOldstructure[i5]=new double[NStruct];
}
YU_ON=new double [NO];
YU_HN=new double [NH];
Error=new double [LoopTimes];//误差
SumP=new double [NI];
SumT=new double [NO];
VARP=new double [NI];
meanp=new double [NI];
STDP=new double [NI];
meanT=new double [NO];
VART=new double [NO];
STDT=new double [NO];
minP=new double [NI];
maxP=new double [NI];
minT=new double [NO];
maxT=new double [NO];
}
void CElman::InitializeZero()
{
for(unsigned int i=0; i<NSample; i++)
{
for(unsigned int j=0; j < NI; j++)
{
PrePi[i][j]=0.0;
Pi[i][j]=0.0;
}
for(unsigned int j1=0; j1 < NH; j1++)
{
Ph[i][j1]=0.0;
Qh[i][j1]=0.0;
Xh[i][j1]=0.0;
}
for(unsigned int j2=0; j2 < NO; j2++)
{
Qo[i][j2]=0.0;
Xo[i][j2]=0.0;
Po[i][j2]=0.0;
T[i][j2]=0.0;
PreT[i][j2]=0.0;
}
for(unsigned int j3=0; j3 <NStruct; j3++)
{
XStructure[i][j3]=0.0;
}
}
for(unsigned int ih=0; ih<NSample+1; ih++)
{
for(unsigned int jh=0; jh < NH; jh++)
{
XhOld[ih][jh]=0.0;
}
for(unsigned int jstr=0; jstr <NStruct; jstr++)
{
XOldstructure[ih][jstr]=0.0;
}
}
for(unsigned int i3=0; i3 < NO; i3++)
{
SumT[i3]=0.0;
VART[i3]=0.0;
meanT[i3]=0.0;
minT[i3]=0.0;
maxT[i3]=0.0;
STDT[i3]=0.0;
YU_ON[i3]=0.0;
}
for(unsigned int i4=0; i4 < NI; i4++)
{
SumP[i4]=0.0;
VARP[i4]=0.0;
minP[i4]=0.0;
maxP[i4]=0.0;
meanp[i4]=0.0;
STDP[i4]=0.0;
}
for(unsigned int i2=0; i2 < NH; i2++)
{
YU_HN[i2]=0.0;
}
for(unsigned int i5=0; i5 <LoopTimes; i5++)
{
Error[i5]=0.0;
}
}
void CElman::initiatewb()
{
srand( (unsigned)time( NULL ) );//意思是每次产生的随机数都不相同.
for(unsigned int i=0; i<NH; i++)
{
for(unsigned int j=0; j < NI; j++)
{
W1[j][i]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;
DW1[j][i]=0;
DW11[j][i]=0;
a1[j][i]=0.5;
}
//结构层
for(unsigned int j0=0; j0<NStruct; j0++)
{
W0[j0][i]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;
DW0[j0][i]=0;
DW00[j0][i]=0;
a0[j0][i]=0.5;
}
// YU_HN[i] = ((float)(::rand()) / (float)(RAND_MAX)) * 0.2f - 0.1f; //第一隐层阈值初始化 ,-0.1 ~ 0.1 之间
}
for(unsigned int j1=0; j1 < NO; j1++)
for(unsigned int i1=0; i1 < NH; i1++)
{
{
W2[i1][j1]=((float)(rand() - (0.5*RAND_MAX)) / (0.5*RAND_MAX))*3;
DW2[i1][j1]=0;
DW22[i1][j1]=0;
a2[i1][j1]=0.5;
// V[i][j]= ((float)(::rand()) / (float)(RAND_MAX)) * 2.0f - 1.0f; //初始化隐层到输出层的权值,随机模拟0 和 1 -1
}
// YU_ON[j1] = ((float)(::rand()) / (float)(RAND_MAX)) * 0.2f - 0.1f; //输出层阈值初始化 ,-0.01 ~ 0.01 之间
}
}
void CElman::SetFreeFinal()
{
delete[] STDT;
delete[] VART;
delete[] meanT;
delete[] minT;
delete[] maxT;
delete[] minP;
delete[] maxP;
delete[] STDP;
delete[] meanp;
delete[] VARP;
delete[] SumT;
delete[] SumP;
delete[] Error;
delete[] YU_HN;
delete[] YU_ON;
for(unsigned int i4=0;i4<NSample+1;i4++)
{
delete[] XOldstructure[i4];
delete[] XhOld[i4];
}
delete[] XhOld;
delete[] XOldstructure;
for(unsigned int i3=0;i3<NSample;i3++)
{
delete[] Pi[i3];
delete[] Po[i3];
delete[] Ph[i3];
delete[] Xo[i3];
delete[] Xh[i3];
delete[] XStructure[i3];
delete[] Qh[i3];
delete[] Qo[i3];
delete[] PrePi[i3];
delete[] PreT[i3];
delete[] T[i3];
}
delete[] T;
delete[] PreT;
delete[] PrePi;
delete[] Qo;
delete[] Qh;
delete[] XStructure;
delete[] Xh;
delete[] Xo;
delete[] Ph;
delete[] Po;
delete[] Pi;
for(unsigned int i2=0;i2<NH;i2++)
{
delete[] W2[i2];
delete[] DW2[i2];
delete[] DW22[i2];
delete[] a2[i2];
}
delete[] a2;
delete[] DW22;
delete[] DW2;
delete[] W2;
for(unsigned int i1=0;i1<NI;i1++)
{
delete[] W1[i1];
delete[] DW1[i1];
delete[] DW11[i1];
delete[] a1[i1];
}
delete[] a1;
delete[] DW11;
delete[] DW1;
delete[] W1;
for(unsigned int i=0;i<NStruct;i++)
{
delete[] W0[i];
delete[] DW0[i];
delete[] DW00[i];
delete[] a0[i];
}
delete[] a0;
delete[] DW00;
delete[] DW0;
delete[] W0;
}
void CElman::DemoInput()
{
ifstream GetTrainingData ( "训练样本.txt", ios::in );
for(unsigned int m=0;m<NSample;m++)
{
for(unsigned int i=0;i<NI;i++)
{
GetTrainingData>>Pi[m][i]; //取得输入数据
}
for(unsigned int j=0;j<NO;j++)
{
GetTrainingData>>T[m][j]; //取得输出数据//
}
}
GetTrainingData.close();
}
void CElman::Prestd()
{
for (unsigned int i0=0;i0<NI;i0++)
{
SumP[i0]=0;
// SumP=new double[i0];
for(unsigned int m0=0;m0<NSample;m0++)
{
SumP[i0]+=Pi[m0][i0];
}
meanp[i0]=SumP[i0]/NSample;
}
for (unsigned int i1=0;i1<NO;i1++)
{
SumT[i1]=0;
for(unsigned int m1=0;m1<NSample;m1++)
{
SumT[i1]+=T[m1][i1];
}
meanT[i1]=SumT[i1]/NSample;
}
for (unsigned int i2=0;i2<NI;i2++)
{
VARP[i2]=0;
for (unsigned int m2=0;m2<NSample;m2++)
{
VARP[i2]+=(Pi[m2][i2]-meanp[i2])*(Pi[m2][i2]-meanp[i2]);
//RESID = X - MEAN(X) and N is LENGTH(X).
}
VARP[i2]=VARP[i2]/(NSample-1);
//VAR(X) = SUM(RESID.*CONJ(RESID)) / (N-1)
STDP[i2]=sqrt(VARP[i2]);
}
for (unsigned int i3=0;i3<NO;i3++)
{
VART[i3]=0;
for (unsigned int m3=0;m3<NSample;m3++)
{
VART[i3]+=(T[m3][i3]-meanT[i3])*(T[m3][i3]-meanT[i3]);
//RESID = X - MEAN(X) and N is LENGTH(X).
}
VART[i3]=VART[i3]/(NSample-1);
//VAR(X) = SUM(RESID.*CONJ(RESID)) / (N-1)
STDT[i3]=sqrt(VART[i3]);
}
for (unsigned int m4=0;m4<NSample;m4++)
{
for (unsigned int i4=0;i4<NI;i4++)
{
PrePi[m4][i4]=(Pi[m4][i4]-meanp[i4])/STDP[i4];
}
for (unsigned int i5=0;i5<NO;i5++)
{
PreT[m4][i5]=(T[m4][i5]-meanT[i5])/STDT[i5];
}
}
}
double CElman::cal(double d,int index)//s型激励函数
{
switch(index)
{
case 0://logsig
d=-d*u;
d=exp(d);
d=1/(1+d);
return d;
case 1://tansig
d=2/(1+exp(-2*d))-1;
return d;
default:
return d;
}
}
void CElman::forward()//计算神经元的delta,误差公式
{
for(unsigned int i=0;i<NSample;i++)
{
for(unsigned int j=0; j< NO; j++)
{
// Qo[i][j]=-(PreT[i][j]-Xo[i][j])*derivecal(Xo[i][j],2);//输出层的修正
Qo[i][j]=(PreT[i][j]-Xo[i][j])*derivecal(Po[i][j],1);//输出层的修正
//Qo[i][j]=-(PreT[i][j]-Xo[i][j]);
}
for(unsigned int j1=0; j1< NH; j1++)
{
Qh[i][j1]=0;
for(unsigned int k=0; k< NO; k++)
Qh[i][j1]+=Qo[i][k]*W2[j1][k];
// Qh[i][j1]=Qh[i][j1]*derivecal(Xh[i][j1],2);
Qh[i][j1]=Qh[i][j1]*derivecal(Ph[i][j1],1);
}
}
}
double CElman::derivecal(double d,int index)
//s型激励函数求导
{
switch(index)
{
case 0://logsig
return u*d*(1-d);
case 1:
return 1.0-d*d;
case 2:
return 1.0;
}
}
void CElman::amend()//权值修正,阈值修正
{
double D0,D,D1;
for(unsigned int i0=0; i0< NH; i0++)
{
for(unsigned int j0=0; j0< NI; j0++)
{
DW1[j0][i0]=0;
// YU_HN[i0]=0;
}
for(unsigned int k0=0; k0< NO; k0++)
{
DW2[i0][k0]=0;
// YU_ON[k0]=0;//输出层阈值
}
}
//结构层
for(unsigned int i2=0; i2< NStruct; i2++)
{
for(unsigned int j=0; j< NH; j++)
{
for(unsigned int k=0;k<NSample;k++)
{
DW0[i2][j]+=Qh[k][j]*XStructure[k][i2];
}
D0=DW0[i2][j]*DW00[i2][j];
a0[i2][j]=newa(a0[i2][j],D0);
W0[i2][j]+=a0[i2][j]*(n*DW0[i2][j]+(1-n)*DW00[i2][j]);
DW00[i2][j]=DW0[i2][j];
}
}
for(unsigned int i=0; i< NI; i++)
{
for(unsigned int j=0; j< NH; j++)
{
for(unsigned int k=0;k<NSample;k++)
{
DW1[i][j]+=Qh[k][j]*PrePi[k][i];
}
D=DW1[i][j]*DW11[i][j];
a1[i][j]=newa(a1[i][j],D);
W1[i][j]+=a1[i][j]*(n*DW1[i][j]+(1-n)*DW11[i][j]);
DW11[i][j]=DW1[i][j];
}
/*
for(unsigned int jb=0; jb< NH; jb++)
{
for(unsigned int kb=0;kb<NSample;kb++)
{
YU_HN[jb]+=a1[i][jb]*Qh[kb][jb];
}
}*/
}
for(unsigned int i1=0; i1< NH; i1++)
{
for(unsigned int j1=0; j1< NO; j1++)
{
for(unsigned int k1=0;k1<NSample;k1++)
{
DW2[i1][j1]+=Qo[k1][j1]*Xh[k1][i1];
}
D1=DW2[i1][j1]*DW22[i1][j1];
a2[i1][j1]=newa(a2[i1][j1],D1);
W2[i1][j1]+=a2[i1][j1]*(n*DW2[i1][j1]+(1-n)*DW22[i1][j1]);
DW22[i1][j1]=DW2[i1][j1];
}
/*
for(unsigned int j3=0; j3< NO; j3++)
{
for(unsigned int k3=0;k3<NSample;k3++)
{
YU_ON[j3]+=a2[i1][j3]*Qo[k3][j3];//错误
}
}*/
}
}
double CElman::newa(double a, double D)//学习速率自动调节
{
if(D>0)//当最近两次对权值调整方向相同,则为正
{
if(a<=0.04)
a=a*2;
else
a=0.08;
}
else
if(D<0)
{
if(a>=0.02)
a=a/2;
else
a=0.01;
}
return a;
}
void CElman::Simulate()
{
unsigned int j;
j=5;
}
void CElman::proceed(unsigned int Times)//各层输入输出
{
Error[Times]=0.0;
for(unsigned int i=0;i<NSample;i++)
{
//结构层输出
for(unsigned int j0=0; j0 < NStruct; j0++)
{
// XStructure[i][j]=0;
// for(unsigned int k=0; k< NH; k++)//结构层神经元个数
// {
XStructure[i][j0]=XhOld[i][j0]+gaincoffi*XOldstructure[i][j0];//结构层输出
// }
XOldstructure[i][j0]=XStructure[i][j0];
}
for(unsigned int j1=0; j1 < NH; j1++)
{
Ph[i][j1]=0;
for(unsigned int m1=0; m1< NStruct; m1++)
{
Ph[i][j1]+=XStructure[i][m1]*W0[m1][j1];//隐节点输入
}
for(unsigned int k1=0; k1< NI; k1++)
{
Ph[i][j1]+=PrePi[i][k1]*W1[k1][j1];
}
// Xh[i][j1]=cal(Ph[i][j1]-YU_HN[j1]);//隐节点输出
Xh[i][j1]=cal(Ph[i][j1],1);
XhOld[i][j1]=Xh[i][j1];
}
for(unsigned int j2=0; j2 < NO; j2++)
{
Po[i][j2]=0;
for(unsigned int k=0; k< NH; k++)
{
// Po[i][j2]+=Xh[i][k]*W2[k][j2];
Po[i][j2]+=Xh[i][k]*W2[k][j2];
}
// Xo[i][j2]=cal(Po[i][j2]-YU_ON[j2]);
Xo[i][j2]=cal(Po[i][j2],1);
//Xo[i][j2]= Po[i][j2] ;
Error[Times]+=(Xo[i][j2]-PreT[i][j2])*(Xo[i][j2]-PreT[i][j2])/2;
}
}
Error[Times]=Error[Times]/NSample;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -