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

📄 bpnetwork.cpp

📁 神经网络中bp网络的实现 供大家参考
💻 CPP
字号:
// BpNetwork.cpp: implementation of the CBpNetwork class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BP.h"
#include "BpNetwork.h"
#include "matlib.h"
#include "iostream.h"
#include "fstream.h"
#include "time.h"
#include "stdlib.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CBpNetwork::CBpNetwork()
{
   initM(MATCOM_VERSION);//启用矩阵运算库
}

CBpNetwork::~CBpNetwork()
{
   exitM();
   delete this;
}
void CBpNetwork::create(Mm mInputData, Mm mTarget, int input, int hidden, int output)
{   
	int i,j;
	srand((unsigned)time(NULL));
	//初始化网络基本参数
	mSampleInput=zeros(mInputData.rows(),mInputData.cols());
	mSampleTarget=zeros(mTarget.rows(),mTarget.cols());
	mSampleInput=mInputData;
    mSampleTarget=mTarget;
	this->input=input; 
	this->hidden=hidden;
	this->output=output;
	//初始化单个样本矩阵
	this->mInput=zeros(input,1);
	//初始化隐层数据
	this->mHidden=zeros(hidden,1);
    //初始化输出层数据
	this->mOutput=zeros(output,1);
	//创建权值矩阵
	this->mWeighti=zeros(this->hidden,this->input);
	this->mWeighto=zeros(this->output,this->hidden);
	for(i=1;i<=hidden;i++)
		for(j=1;j<=input;j++)
			this->mWeighti.r(i,j)=randData(-1.0,1.0);
	for(i=1;i<=output;i++)
		for(j=1;j<=hidden;j++)
			this->mWeighto.r(i,j)=randData(-1.0,1.0);
	//创建阙值矩阵
	this->mThresholdi=zeros(this->hidden,1);
	for(i=1;i<=hidden;i++)
		this->mThresholdi.r(i,1)=randData(-1.0,1.0);
	this->mThresholdo=zeros(this->output,1);
	for(i=1;i<=output;i++)
		this->mThresholdo.r(i,1)=randData(-1.0,1.0);
	//误差矩阵
    mOutputDeltas=zeros(output,1);
    mHiddenDeltas=zeros(hidden,1);	
	//学习速率赋值
    learnRate1=0.5;
    learnRate2=0.5;
	
	m_isOk=false;
    m_isStop=false;
    dblMse=1.0e-6;
    dblError=1.0;
    
}
void CBpNetwork::forward(int iSample)//前馈
{   
	if(iSample<0||iSample>mSampleInput.cols())
	{
		AfxMessageBox("输入错误");
		return;
	}
	int i,j;
	double temp=0.0;
	//输入层数据
	for(i=1;i<=input;i++)
		mInput.r(i,1)=mSampleInput.r(i,iSample);
	//隐层数据
	for(i=1;i<=hidden;i++)
	{
		temp=0.0;
		for(j=1;j<=input;j++)
		{
			temp+=mWeighti.r(i,j)*mInput.r(j,1);
		}
		temp+=mThresholdi.r(i,1);
		mHidden.r(i,1)=f(temp);
	}
	//输出
	for(i=1;i<=output;i++)
	{
		temp=0.0;
		for(j=1;j<=hidden;j++)
		{
			temp+=mWeighto.r(i,j)*mHidden.r(j,1);
		}
		temp+=mThresholdo.r(i,1);
		mOutput.r(i,1)=f(temp);
	}		
}
void CBpNetwork::backward(int iSample)
{
	if(iSample<0||iSample>mSampleInput.cols())
	{
		AfxMessageBox("输入错误");
		return;
	}
	int i,j;
	double sum;
    //输出层敏感性
	for(i=1;i<=output;i++)
		mOutputDeltas.r(i,1)=(-2)*f_1(mOutput.r(i,1))*(mSampleTarget.r(i,iSample)-mOutput.r(i,1));
	//隐层敏感性
    for(i=1;i<=hidden;i++)
	{
		sum=0.0;
		for(j=1;j<=output;j++)
		{
			sum+=changeMm(mWeighto).r(i,j)*mOutputDeltas.r(j,1);
		}
		mHiddenDeltas.r(i,1)=f_1(mHidden.r(i,1))*sum;
	}

	for(i=1;i<=hidden;i++)
	{
		for(j=1;j<=output;j++)
		{
			mWeighto.r(j,i)-=learnRate2*mOutputDeltas.r(j,1)*changeMm(mHidden).r(1,i);
		}
	}

	for(i=1;i<=input;i++)
	{
		for(j=1;j<=hidden;j++)
		{
			mWeighti.r(j,i)-=learnRate1*mHiddenDeltas.r(j,1)*changeMm(mInput).r(1,i);
		}
	}
	for(j=1;j<=output;j++)
	    mThresholdo.r(j,1)-=learnRate2*mOutputDeltas.r(j,1);  
	for(i=1;i<=hidden;i++) 
	    mThresholdi.r(i,1)-=learnRate1*mHiddenDeltas.r(i,1);
	dblError=0.0;
    for(i=1;i<=output;i++)
        dblError+=0.5*(mSampleTarget.r(i,iSample)-mOutput.r(i,1))*(mSampleTarget.r(i,iSample)-mOutput.r(i,1));
}
//学习
void CBpNetwork::learn()
{ 
  int iSample=1;
  double dblTotal;
  if(m_isStop)
	  m_isStop=false;

  while(dblError>dblMse && !m_isStop){
     dblTotal=0.0;
     for(iSample=1;iSample<=mSampleInput.cols();iSample++){
	    forward(iSample);
        backward(iSample);
	    dblTotal+=dblError;//总误差
	 }
     if(dblTotal/dblError>1.04){//动态改变学习速率
	   learnRate1*=0.7;
       learnRate2*=0.7;
	 }
     else{
       learnRate1*=1.05;
       learnRate2*=1.05;
	 }
     dblError=dblTotal;
 }
 if(dblError<=dblMse)
 {
	 m_isOk=true;
	 save();
	 AfxMessageBox("训练结束");
 }
 else
     m_isOk=false;
}
//停止训练
void CBpNetwork::stop()
{
   m_isStop=true;
}
//矩阵转置
Mm CBpNetwork::changeMm(Mm temp)
{
	Mm change;
	int i,j,row,col;
	row=temp.rows();
	col=temp.cols();
	change=zeros(col,row);
	for(i=1;i<=row;i++)
	   for(j=1;j<=col;j++)
		  change.r(j,i)=temp.r(i,j);
	return change;
}
void CBpNetwork::save()
{
	int i,j;
	ofstream wfile("c:\\权值.txt",ios::out);
	ofstream bfile("c:\\偏置值.txt",ios::out);
	wfile<<"输入层与隐含层之间的权\n";
	for(i=1;i<=hidden;i++)
	{
       for(j=1;j<=input;j++)
	   {
			wfile<<mWeighti.r(i,j)<<"  ";
	   }
	   wfile<<"\n";
	}		
    wfile<<"隐含层与输出层之间的权\n";
	for(i=1;i<=output;i++)
	{
       for(j=1;j<=hidden;j++)
	   {
			wfile<<mWeighto.r(i,j)<<"  ";
	   }
	   wfile<<"\n";
	}
	bfile<<"隐层的偏置值为:\n";
	for(i=1;i<=hidden;i++)
	{
		bfile<<mThresholdi.r(i,1)<<"    ";  //隐层偏置值写入文本
	}
	bfile<<"\n输出层的偏置值为:\n";
	for(i=1;i<=output;i++)
	{
		bfile<<mThresholdo.r(i,1)<<"    ";  //输出层偏置值写入文本
	}
}
//激活函数导数
double CBpNetwork::f_1(double temp)
{
	return (1-temp)*temp;
}
//激活函数
double CBpNetwork::f(double n)
{
	return 1.0/(1.0+exp(-n));
}
//随机产生a和b之间的随机数
double CBpNetwork::randData(double a, double b)
{ 
  return((b-a)*rand()+a);
}

⌨️ 快捷键说明

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