www.pudn.com > RBPNN.rar > CRBPNN.CPP, change:2006-06-19,size:12551b
#include#include #include"CRBPNN.H" #include #include #include CRBPNN::CRBPNN() { this->m_pN=0; this->m_pD=0; this->m_pC=0; this->m_in=0; this->m_out=0; this->m_mid1=0; this->m_mid2=0; this->m_kernel=NULL; this->m_learningalgorithm=NULL; this->v_pNC=NULL; this->v_pSort=NULL; this->v_pClass=NULL; this->v_pX=NULL; this->v_expectD=NULL; this->v_realY=NULL; this->v_conS=NULL; this->v_midZ1=NULL; this->v_midZ2=NULL; this->v_weight=NULL; } CRBPNN::~CRBPNN() { int i; for(i=0;i m_mid1;i++) delete[] this->v_conS[i]; for(i=0;i m_out;i++) delete[] this->v_weight[i]; delete[] this->v_conS,this->v_weight,this->v_pNC; if(this->v_realY!=NULL) { for(i=0;i m_pN;i++) delete[] this->v_realY[i]; delete[] this->v_realY; } } void CRBPNN::Training(int pn, int pd, int pc, char* kernel, char* learning, char* sampledata) { if(pn>0&&pd>0&&pc>0&&kernel!=NULL&&learning!=NULL&&sampledata!=NULL) { ////////////////////////////////////////// //初始化网络,分配空间 ////////////////////////////////////////// int i,j; this->m_pN=pn; this->m_pD=pd; this->m_pC=pc; this->m_in=pd; this->m_kernel=kernel; this->m_learningalgorithm=learning; this->m_mid1=pn; this->m_mid2=pc; this->m_out=pc; this->v_pNC=new int[this->m_pC]; this->v_pSort=new int[this->m_pN]; this->v_pClass=new int[this->m_pN]; this->v_pX=new double*[this->m_pN]; this->v_expectD=new double*[this->m_pN]; this->v_conS=new double*[this->m_mid1]; this->v_midZ1=new double*[this->m_pN]; this->v_midZ2=new double*[this->m_pN]; this->v_weight=new double*[this->m_out]; for(j=0;j m_pN;j++) { this->v_pX[j]=new double[this->m_in]; this->v_expectD[j]=new double[this->m_out]; this->v_midZ1[j]=new double[this->m_mid1]; this->v_midZ2[j]=new double[this->m_mid1]; } for(j=0;j m_mid1;j++) this->v_conS[j]=new double[this->m_in]; for(j=0;j m_out;j++) this->v_weight[j]=new double[this->m_mid2]; ifstream fin(sampledata,ios::nocreate); if(fin.fail()) { cerr<<"Error opening the file:"< m_pN;i++) { int c; fin>>c; this->v_pClass[i]=c; //类别标志 for(j=0;j m_out;j++) { if(j==(c-1)) this->v_expectD[i][j]=1; else this->v_expectD[i][j]=0; } for(j=0;j m_in;j++) fin>>this->v_pX[i][j]; } fin.close(); for(i=0;i m_out;i++) for(j=0;j m_mid2;j++) this->v_weight[i][j]=1; ////////////////////////////////////////// //训练网络,更新并记录权值 ////////////////////////////////////////// this->CalcNumberperC(); this->ChooseandSortconS(); //选取径向基函数中心矢量 this->CalcMidZ1(); //选择变换函数,计算隐层输出 this->CalcMidZ2(); if(strcmp(this->m_learningalgorithm,"RLSA")==0) RLSA(); //其他学习算法 //else if //else if //... ////////////////////////////////////////// //释放空间,仅保留权值、中心控制矢量和各个变量 ////////////////////////////////////////// for(j=0;j m_pN;j++) delete[] this->v_pX[j],this->v_expectD[j],this->v_midZ1[j],this->v_midZ2[j]; delete[] this->v_pX,this->v_expectD,this->v_midZ1,this->v_midZ2; delete[] this->v_pClass,this->v_pSort; } } /*计算每个类别对应的模式个数*/ void CRBPNN::CalcNumberperC() { int c,i,j; j=0; for(c=1;c<=this->m_pC;c++) { this->v_pNC[c-1]=0; for(i=0;i m_pN;i++) { if(this->v_pClass[i]==c) { this->v_pSort[j]=i; j++; this->v_pNC[c-1]++; } } } } /*设置中心控制矢量,并将其按类别排好*/ void CRBPNN::ChooseandSortconS() { int i,j; for(i=0;i m_mid1;i++) for(j=0;j m_in;j++) this->v_conS[i][j]=this->v_pX[this->v_pSort[i]][j]; } /*计算第一隐层输出*/ void CRBPNN::CalcMidZ1() { if(strcmp(this->m_kernel,"Gaussian")==0) { double* v_alpha; //高斯形状控制参数 v_alpha=new double[this->m_mid1]; for(int m=0;m m_mid1;m++) v_alpha[m]=0.3; //将v_alpha[i]设为固定值0.5 /* //将v_alpha[i]设为0、1之间的随机值 int m; srand((unsigned)time(NULL)); for(m=0;m m_pN;t++) { for(i=0;i m_mid1;i++) { sum=0; for(j=0;j m_in;j++) sum+=pow(this->v_pX[t][j]-this->v_conS[i][j],2); sum=sum*1.0/(2.0*(pow(v_alpha[i],2))); this->v_midZ1[t][i]=exp((-1)*sum); } } delete[] v_alpha; } //采用其他核计算第一层隐层输出 //if //if //if } /*计算第二隐层输出*/ void CRBPNN::CalcMidZ2() { int i,j,k,t; double sum; for(i=0;i >m_lamda; m_lamda=0.99; //cout<<"请输入终止误差:"< >m_enderror; m_enderror=0.01; //cout<<"请输入终止次数:"< >m_endcyc; m_endcyc=1000; double *v_gain; //卡尔曼增益 v_gain=new double[m_mid2]; double **v_icorrP; //逆相关矩阵 v_icorrP=new double*[m_mid2]; for(i=0;i m_mid2;i++) { v_icorrP[i]=new double[m_mid2]; for(j=0;j m_mid2;j++) if(j==i) v_icorrP[i][j]=1; else v_icorrP[i][j]=0; } //迭代算法,计算权值和累计误差能量 do { pk=int(k%this->m_pN); //选择输入模式 this->CalcGain(pk,m_lamda,v_gain,v_icorrP); //计算卡尔曼增益 this->CalcIcorrP(pk,m_lamda,v_gain,v_icorrP); //计算逆相关矩阵 m_energyJ=this->CalcEnergyJ(pk,m_lamda,m_energyJ); //计算累计误差能量 this->CalcWeight(pk,v_gain); //更新连接权值 k++; fout< m_enderror&&k m_out;j++) { sum=0; for(k=0;k m_mid2;k++) sum+=this->v_midZ2[t][k]*this->v_weight[j][k]; sum=this->v_expectD[t][j]-sum; for(i=0;i v_weight[j][i]=this->v_weight[j][i]+gain[i]*sum; } } /*计算卡尔曼增益 t:迭代的次序 lamda:加权遗忘因子 gain:卡尔曼增益(输出) icorrP:逆相关矩阵*/ void CRBPNN::CalcGain(int t,double lamda,double* gain,double **icorrP) { int i,j; double g=0.0; for(i=0;i m_mid2;i++) { gain[i]=0.0; for(j=0;j m_mid2;j++) gain[i]+=icorrP[i][j]*this->v_midZ2[t][j]; } for(j=0;j m_mid2;j++) g+=this->v_midZ2[t][j]*gain[j]; g+=lamda; for(i=0;i m_mid2;i++) gain[i]/=g; } /*迭代计算逆相关矩阵 t:迭代的次序 lamda:加权遗忘因子 gain:卡尔曼增益 icorrP:逆相关矩阵(输出)*/ void CRBPNN::CalcIcorrP(int t,double lamda,double *gain,double **icorrP) { int i,j,k; double** temp1; double** temp2; temp1=new double*[this->m_mid2]; temp2=new double*[this->m_mid2]; for(i=0;i m_mid2;i++) { temp1[i]=new double[this->m_mid2]; for(j=0;j m_mid2;j++) temp1[i][j]=gain[i]*this->v_midZ2[t][j]; } for(i=0;i m_mid2;i++) { temp2[i]=new double[this->m_mid2]; for(j=0;j m_mid2;j++) { temp2[i][j]=0; for(k=0;k m_mid2;k++) temp2[i][j]+=temp1[i][k]*icorrP[k][j]; } } for(i=0;i m_mid2;i++) { for(j=0;j m_mid2;j++) icorrP[i][j]=(icorrP[i][j]-temp2[i][j])/lamda; } for(i=0;i m_mid2;i++) delete[] temp1[i],temp2[i]; delete[] temp1,temp2; } /*迭代计算累积误差能量函数 t:迭代的次序 lamda:加权遗忘因子 energyJ:累积误差能量*/ double CRBPNN::CalcEnergyJ(int t,double lamda,double energyJ) { int k,j; double sum1,sum2; sum1=0; for(j=0;j m_out;j++) { sum2=0; for(k=0;k m_mid2;k++) sum2+=this->v_midZ2[t][k]*this->v_weight[j][k]; sum2=this->v_expectD[t][j]-sum2; sum1+=pow(sum2,2); } return lamda*energyJ+sum1/2.0; } /*模式分类 n:需要分类的模式个数 testdata:分类数据*/ void CRBPNN::Classifying(int n,char* testdata) { if(n>0&&testdata!=NULL&&this->v_weight!=NULL) { int i,j; this->m_pN=n; this->v_pX=new double*[this->m_pN]; this->v_midZ1=new double*[this->m_pN]; this->v_midZ2=new double*[this->m_pN]; for(j=0;j m_pN;j++) { this->v_pX[j]=new double[this->m_in]; this->v_midZ1[j]=new double[this->m_mid1]; this->v_midZ2[j]=new double[this->m_mid1]; } ifstream fin(testdata,ios::nocreate); if(fin.fail()) { cerr<<"Error opening the file:"< m_in;j++) fin>>this->v_pX[i][j]; i++; }while(!fin.eof()); fin.close(); this->CalcMidZ1(); this->CalcMidZ2(); this->CalcOutput(); for(j=0;j m_pN;j++) delete[] this->v_pX[j],this->v_midZ1[j],this->v_midZ2[j]; delete[] this->v_pX,this->v_midZ1,this->v_midZ2; } } /*计算网络输出*/ void CRBPNN::CalcOutput() { int i,j,t; this->v_realY=new double*[this->m_pN]; for(i=0;i m_pN;i++) this->v_realY[i]=new double[this->m_out]; for(t=0;t m_pN;t++) { for(j=0;j m_out;j++) { v_realY[t][j]=0.0; for(i=0;i v_realY[t][j]+=this->v_midZ2[t][i]*this->v_weight[j][i]; } } } /*网络输出 pFileName:用于保存输出结果的文件名称*/ void CRBPNN::GetOutput(char *pFileName) { ofstream fout(pFileName); if(fout.fail()) { cerr<<"Error opening file:"< m_pN;i++) { int t=0; double y=this->v_realY[i][0]; for(j=0;j m_out;j++) { if(y v_realY[i][j]) {y=this->v_realY[i][j];t=j;} fout< m_pN-1) fout< v_weight!=NULL) { ofstream fout(pFileName); if(fout.fail()) { cerr<<"Error opening file:"< m_out;i++) { for(j=0;j m_mid2;j++) { fout< v_weight[i][j]; } fout< v_weight==NULL) { ofstream fout(pFileName); if(fout.fail()) { cerr<<"Error opening file:"< m_out;i++) { for(j=0;j m_mid2;j++) { fout.precision(5); fout< v_weight[i][j]; } fout< v_realY!=NULL) { ifstream fin(ptestclass); if(fin.fail()) { cerr<<"Error opening file:"< m_pN;i++) { fin>>d; y=this->v_realY[i][0]; t=0; for(j=1;j m_out;j++) { if(y v_realY[i][j]) {y=this->v_realY[i][j];t=j;} } if(d==t+1) count++; } return count*100.0/m_pN; } return -1; }