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

📄 bpnet.cpp

📁 BP算法的运算矩阵
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}

void CBpNet::stop()
{
 m_IsStop=true;
}

double CBpNet::randab(double a, double b)
{ //注意,如果应用矩阵库,头文件matlib.h对rand()函数重新定义,只产生(0,1)
  //之间的随机数
  return((b-a)*rand()+a);
}

//将数据转化到(0,1)区间
void CBpNet::normalize()
{
 
 int i,j;
  //输入数据范围
  mInputNormFactor=scope(mSampleInput);
  //目标数据范围
  mTargetNormFactor=scope(mSampleTarget);

 for(i=1;i<=mSampleInput.rows();i++)
	 for(j=1;j<=mSampleInput.cols();j++)
		 mSampleInput.r(i,j)=(mSampleInput.r(i,j)-mInputNormFactor.r(j,1))/(mInputNormFactor.r(j,2)-mInputNormFactor.r(j,1));
 
 for(i=1;i<=mSampleTarget.rows();i++)
	 for(j=1;j<=mSampleTarget.cols();j++)
		 mSampleTarget.r(i,j)=(mSampleTarget.r(i,j)-mTargetNormFactor.r(j,1))/(mTargetNormFactor.r(j,2)-mTargetNormFactor.r(j,1));
 
}

//前向计算 
void CBpNet::forward(int iSample)
{//根据第iSample个样本,前向计算
	if(iSample<1||iSample>mSampleInput.rows()){
		MessageBox(NULL,"无此样本数据:索引出界!","无此样本数据:索引出界!",MB_OK);
		return;
	}
	int i,j;
	double sum=0.0;
	
	//输入层数据
	for(i=1;i<=iInput;i++)
		mInput.r(i)=mSampleInput.r(iSample,i);
	
	//隐层数据
    
	for(j=1;j<=iHidden;j++){
		sum=0.0;
		for(i=1;i<=iInput;i++)			
			sum+=mInput.r(i)*mWeighti.r(i,j);
		
		sum-=mThresholdi.r(j); 
		mHidden.r(j)=1.0/(1.0+exp(-sum));
	}
    	
	//输出数据
	for(j=1;j<=iOutput;j++){
		sum=0.0;
		for(i=1;i<=iHidden;i++)
			sum+=mHidden.r(i)*mWeighto.r(i,j);
		sum-=mThresholdo.r(j); 
		mOutput.r(j)=1.0/(1.0+exp(-sum));
	}
   	
}

//后向反馈
void CBpNet::backward(int iSample)
{
	if(iSample<1||iSample>mSampleInput.rows()){
		MessageBox(NULL,"无此样本数据:索引出界!","无此样本数据:索引出界!",MB_OK);
		return;
	}
    int i,j;
	
    //输出误差
	for(i=1;i<=iOutput;i++)
		mOutputDeltas.r(i)=mOutput.r(i)*(1-mOutput.r(i))*(mSampleTarget.r(iSample,i)-mOutput.r(i));
	
	//隐层误差
	double sum=0.0;
	for(j=1;j<=iHidden;j++){
		sum=0.0;
		for(i=1;i<=iOutput;i++)
			sum+=mOutputDeltas.r(i)*mWeighto.r(j,i);
		mHiddenDeltas.r(j)=mHidden.r(j)*(1-mHidden.r(j))*sum;
	}
	//更新隐层-输出权重
	
	double dblChange;
	for(j=1;j<=iHidden;j++)
		for(i=1;i<=iOutput;i++){
			dblChange=mOutputDeltas.r(i)*mHidden.r(j);
			mWeighto.r(j,i)=mWeighto.r(j,i)+dblLearnRate2*dblChange+dblMomentumFactor*mChangeo.r(j,i);
			mChangeo.r(j,i)=dblChange;
		}
    
	//更新输入-隐层权重
    for(i=1;i<=iInput;i++)
		for(j=1;j<=iHidden;j++){
			dblChange=mHiddenDeltas.r(j)*mInput.r(i);
            mWeighti.r(i,j)=mWeighti.r(i,j)+dblLearnRate1*dblChange+dblMomentumFactor*mChangei.r(i,j); 
			mChangei.r(i,j)=dblChange;
		}
	//修改阙值
	for(j=1;j<=iOutput;j++)
	    mThresholdo.r(j)-=dblLearnRate2*mOutputDeltas.r(j);  
	for(i=1;i<=iHidden;i++) 
	    mThresholdi.r(i)-=dblLearnRate1*mHiddenDeltas.r(i); 
   	//计算误差
	dblErr=0.0;
	for(i=1;i<=iOutput;i++)
		dblErr+=0.5*(mSampleTarget.r(iSample,i)-mOutput.r(i))*(mSampleTarget.r(iSample,i)-mOutput.r(i));
	
   
}

//求数据列的范围
Mm CBpNet::scope(Mm mData)
{Mm mScope;
 mScope=zeros(mData.cols(),2);
 double  min,max;
 for(int i=1;i<=mData.cols();i++){
	 min=max=mData.r(1,i); 
	 for(int j=1;j<=mData.rows();j++){
		 if(mData.r(j,i)>=max)
			 max=mData.r(j,i);
		 if(mData.r(j,i)<=min)
			 min=mData.r(j,i);
	 }
	 if(min==max)
		 min=0.0;
	 mScope.r(i,1)=min;
	 mScope.r(i,2)=max;
 }
 return(mScope);

}

//显示矩阵数据,方便调试
void CBpNet::display(Mm data)
{CString strData,strTemp;
 int i=1,j=1;
 for(i=1;i<=data.rows();i++){
	 for(j=1;j<=data.cols();j++){
	 strTemp.Format("%.3f ",data.r(i,j));
	 strData+=strTemp;
	 }
	 strData=strData+"\r\n";
 }
 ::MessageBox(NULL,strData,"",MB_OK);

}

void CBpNet::Serialize(CArchive &ar)
{CObject::Serialize(ar);
 ///////////////////////////////////// 
if(ar.IsStoring()){
     int i,j;
	 double dblData;
	 CString strTemp="Bp";
	 ar<<strTemp;//写入标志
	//纪录神经元个数
	 ar<<iInput<<iHidden<<iOutput;
    //纪录权值
	 for(i=1;i<=iInput;i++)
		 for(j=1;j<=iHidden;j++){
			 dblData=mWeighti.r(i,j);
		     ar<<dblData;
		 }
     for(i=1;i<=iHidden;i++)
		 for(j=1;j<=iOutput;j++){
			 dblData=mWeighto.r(i,j);
			 ar<<dblData;
		 }
	
      //记录权值变化
	 for(j=1;j<=iHidden;j++)
		for(i=1;i<=iOutput;i++)
			ar<<mChangeo.r(j,i);
	
    //输入-隐层权重变化
     for(i=1;i<=iInput;i++)
		for(j=1;j<=iHidden;j++)
			ar<<mChangei.r(i,j);
		
      //纪录阙值
	 for(i=1;i<=iHidden;i++){
              dblData=mThresholdi.r(i);
			  ar<<dblData;
			  }
     for(i=1;i<=iOutput;i++){
		      dblData=mThresholdo.r(i);
			  ar<<dblData;
			  }
     //纪录输入输出的极值
	 for(i=1;i<=iInput;i++){
		  dblData=mInputNormFactor.r(i,1);
		  ar<<dblData; //极小值
		  dblData=mInputNormFactor.r(i,2);
		  ar<<dblData; //极大值
         }
	 for(i=1;i<=iOutput;i++)
		 {dblData=mTargetNormFactor.r(i,1);
		  ar<<dblData; //输出数据极小值
		  dblData=mTargetNormFactor.r(i,2);
		  ar<<dblData; 
		 }
	 //误差范围
	 ar<<dblMse; 
	 //学习速率
	 ar<<dblLearnRate1<<dblLearnRate2;
	 
}
         
 else{
	 int i,j;
	 CString strTemp="";
	 double dblTemp;
	 ar>>strTemp;//读入标志
	//读入神经元个数
	 ar>>iInput>>iHidden>>iOutput;
	 mChangei=zeros(iInput,iHidden);
     mChangeo=zeros(iHidden,iOutput);
	 mWeighti=zeros(iInput,iHidden);
	 mWeighto=zeros(iHidden,iOutput);
    //读入权值
	 for(i=1;i<=iInput;i++)
		  for(j=1;j<=iHidden;j++)
		  { ar>>dblTemp;
		    mWeighti.r(i,j)=dblTemp;
		  }
	 	  
     for(i=1;i<=iHidden;i++)
		 for(j=1;j<=iOutput;j++)
		 { ar>>dblTemp;
		   mWeighto.r(i,j)=dblTemp;
		 }
	
	 //读入权值变化
	 for(j=1;j<=iHidden;j++)
		for(i=1;i<=iOutput;i++)
			ar>>mChangeo.r(j,i);
	
     //输入-隐层权重
     for(i=1;i<=iInput;i++)
		for(j=1;j<=iHidden;j++)
			ar>>mChangei.r(i,j);
	
     //读入阙值
     mThresholdi=zeros(1,iHidden);
	 for(i=1;i<=iHidden;i++)
	 {ar>>dblTemp;
	  mThresholdi.r(i)=dblTemp;
	 }
	 mThresholdo=zeros(1,iOutput);
     for(i=1;i<=iOutput;i++)
	 {ar>>dblTemp;
	  mThresholdo.r(i)=dblTemp;
	 }
     //读入输入输出的极值
     mInputNormFactor=zeros(iInput,2);
	 for(i=1;i<=iInput;i++){
		  ar>>dblTemp;
		  mInputNormFactor.r(i,1)=dblTemp; //极小值
		  ar>>dblTemp;
		  mInputNormFactor.r(i,2)=dblTemp; //极大值
         }
	 mTargetNormFactor=zeros(iOutput,2);
	 for(i=1;i<=iOutput;i++)
		 {ar>>dblTemp;
	      mTargetNormFactor.r(i,1)=dblTemp; //输出数据极小值
		  ar>>dblTemp;
		  mTargetNormFactor.r(i,2)=dblTemp; 
		 }
	 //读入误差范围
	 ar>>dblMse; 
	 //读入学习速率
	 ar>>dblLearnRate1>>dblLearnRate2;
	 

	 //创建计算用的单个样本矩阵
     mInput=zeros(1,iInput);
     mHidden=zeros(1,iHidden);
     mOutput=zeros(1,iOutput);
	 //误差矩阵
	 mOutputDeltas=zeros(iOutput);
	 mHiddenDeltas=zeros(iHidden);
     
 }

}

//如果不是新网络,比如从文件恢复的网络,调用此函数构建学习样本
void CBpNet::LoadPattern(Mm mIn, Mm mOut)
{ if(mIn.cols()!=iInput||mOut.cols()!=iOutput){
	::MessageBox( NULL,"学习样本格式错误!","错误",MB_OK);
	return;
}
  mSampleInput=zeros(mIn.rows(),mIn.cols());
  mSampleTarget=zeros(mOut.rows(),mOut.cols());  
  mSampleInput=mIn;
  mSampleTarget=mOut;
    
  m_isOK=false;
  m_IsStop=false;
  lEpochs=0;
  dblMomentumFactor=0.95;
  dblError=1.0;
}

⌨️ 快捷键说明

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