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

📄 bpnet.cpp

📁 阿拉伯数字手写体的识别源码 vc++能够编译运行
💻 CPP
字号:
// BpNet.cpp: implementation of the BpNet class.
// 2005.1.13-16:02 By Superman 
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "BpNet.h"
#include "math.h"

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

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

BpNet::BpNet()
{ 
	inNum=5;
	hideNum=10;
	outNum=4;

	tjpt[0]=0;
	tjpt[1]=0;
	tjpt[2]=0;
	tjpt[3]=0;
 //////////////////////////////////////////////////////

	w[0][0]=1.0087;
	w[0][1]=-0.8205;
	w[0][2]=0.05389;
	w[0][3]=-0.0496;
	w[0][4]=0.9122;
	w[0][5]=0.9529;
	w[0][6]=-0.1164;
	w[0][7]=-1.159;
	w[0][8]=0.1164;
	w[0][9]=0.459;

	w[1][0]=0.7202;
	w[1][1]=-0.1687;
	w[1][2]=0.5822;
	w[1][3]=1.0328;
	w[1][4]=0.9833;
	w[1][5]=0.8660;
	w[1][6]=-0.8655;
	w[1][7]=-0.2271;
	w[1][8]=0.3685;
	w[1][9]=-0.4271;

	w[2][0]=1.0656;
	w[2][1]=1.3893;
	w[2][2]=-0.4942;
	w[2][3]=1.5207;
	w[2][4]=-1.1254;
	w[2][5]=-0.5841;
	w[2][6]=0.9143;
	w[2][7]=-1.2891;
	w[2][8]=0.0143;
	w[2][9]=0.2891;

	w[3][0]=-0.8710;
	w[3][1]=-0.9764;
	w[3][2]=-1.6356;
	w[3][3]=0.3952;
	w[3][4]=-0.5716;
	w[3][5]=-1.1786;
	w[3][6]=-1.3949;
	w[3][7]=0.6398;
	w[3][8]=0.3949;
	w[3][9]=0.0998;

	w[4][0]=1.0087;
	w[4][1]=-0.8205;
	w[4][2]=0.05389;
	w[4][3]=-0.0496;
	w[4][4]=0.9122;
	w[4][5]=0.9529;
	w[4][6]=-0.1164;
	w[4][7]=-1.159;
	w[4][8]=0.4864;
	w[4][9]=0.759;

////////////////////////////////////////
	w1[0][0]=0.6762;
	w1[0][1]=-0.9607;
	w1[0][2]=-0.8025;
	w1[0][3]=0.0909;

	w1[1][0]=0.3626;
	w1[1][1]=-0.2410;
	w1[1][2]=-0.5382;
	w1[1][3]=-0.7611;

	w1[2][0]=0.6636;
	w1[2][1]=0.0056;
	w1[2][2]=-0.2765;
	w1[2][3]=-0.3734;

	w1[3][0]=0.4189;
	w1[3][1]=-0.1422;
	w1[3][2]=0.0956;
	w1[3][3]=0.3097;	

	w1[4][0]=-0.3908;
	w1[4][1]=-0.6207;
	w1[4][2]=0.4534;
	w1[4][3]=0.4855;

	w1[5][0]=-0.6131;
	w1[5][1]=0.3644;
	w1[5][2]=0.2213;
	w1[5][3]=0.4040;

	w1[6][0]=-0.1964;
	w1[6][1]=0.0792;
	w1[6][2]=-0.3945;
	w1[6][3]=0.0833;

	w1[7][0]=-0.6983;
	w1[7][1]=0.3958;
	w1[7][2]=-0.8677;
	w1[7][3]=0.4007;

	w1[8][0]=0.6762;
	w1[8][1]=-0.9607;
	w1[8][2]=-0.8025;
	w1[8][3]=0.0909;

	w1[9][0]=0.3626;
	w1[9][1]=-0.2410;
	w1[9][2]=-0.5382;
	w1[9][3]=-0.7611;
///////////////////////////////////////////
	b1[0]=-0.1293;
	b1[1]=1.06167;
	b1[2]=-0.0801;
	b1[3]=-0.1915;
	b1[4]=0.8152;
	b1[5]=0.0592;
	b1[6]=-0.7001;
	b1[7]=0.4053;
	b1[8]=0.7274;
	b1[9]=-0.1563;

	b2[0]=0.4712;
	b2[1]=0.2923;
	b2[2]=0.6773;
	b2[3]=0.4197;

/////////////////////////////////////////////////////////////
	for(int i=0;i<200;i++)
	{
		x[i]=0;
		x1[i]=0;
		x2[i]=0;
		o1[i]=0;
		o2[i]=0;
		pp[i]=0;
		qq[i]=0;
		yd[i]=0.0;
	}
	error=0.001;
	e=0.0;

	rate_w=0.05;  //权值学习率(输入层--隐含层)
	rate_w1=0.047; //权值学习率 (隐含层--输出层)
	rate_b1=0.05; //隐含层阀值学习率
	rate_b2=0.047; //输出层阀值学习率
}

BpNet::~BpNet()
{

}

void BpNet::train(double p[][5],double t[][4],int samplenum)
{
	for(int isamp=0;isamp<samplenum;isamp++)//循环训练一次样品
	{ 
		for(int i=0;i<inNum;i++)
			x[i]=p[isamp][i];
		for(i=0;i<outNum;i++)
			yd[i]=t[isamp][i];

		//构造每个样品的输入和输出标准
		for(int j=0;j<hideNum;j++)
		{
			o1[j]=0.0;

			for(i=0;i<inNum;i++)
				o1[j]=o1[j]+w[i][j]*x[i];//隐含层各单元输入激活值
			x1[j]=1.0/(1+exp(-o1[j]-b1[j]));//隐含层各单元的输出
		}

		for(int k=0;k<outNum;k++)
		{
			o2[k]=0.0;

			for(j=0;j<hideNum;j++)
				o2[k]=o2[k]+w1[j][k]*x1[j];//输出层各单元输入激活值
			x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出
		}

		for(k=0;k<outNum;k++)
		{
			e=0.0;
			qq[k]=(yd[k]-x2[k])*x2[k]*(1.-x2[k]);//希望输出与实际输出的偏差
			e+=fabs(yd[k]-x2[k])*fabs(yd[k]-x2[k]);//计算均方差

			for(j=0;j<hideNum;j++)
				w1[j][k]=w1[j][k]+rate_w1*qq[k]*x1[j];//下一次的隐含层和输出层之间的新连接权
			e=sqrt(e);
			if(e<error)
				tjpt[k]=1;
		}

		for(j=0;j<hideNum;j++)
		{
			pp[j]=0.0;
			for(k=0;k<outNum;k++)
				pp[j]=pp[j]+qq[k]*w1[j][k];
			pp[j]=pp[j]*x1[j]*(1-x1[j]);//隐含层的校正误差

			for(i=0;i<inNum;i++)
				w[i][j]=w[i][j]+rate_w*pp[j]*x[i];//下一次的输入层和隐含层之间的新连接权
		}

		for(k=0;k<outNum;k++)
			b2[k]=b2[k]+rate_b2*qq[k];//下一次的隐含层和输出层之间的新阈值
		for(j=0;j<hideNum;j++)
			b1[j]=b1[j]+rate_b1*pp[j];//下一次的输入层和隐含层之间的新阈值

	}//end isamp样品循环

}
///////////////////////////end train/////////////////////////////

/////////////////////////////////////////////////////////////////

double * BpNet::sim(double *psim)
{ 
	for(int i=0;i<inNum;i++)
		x[i]=psim[i];
	for(int j=0;j<hideNum;j++)
	{
		o1[j]=0.0;

		for(int i=0;i<inNum;i++)
			o1[j]=o1[j]+w[i][j]*x[i];//隐含层各单元激活值
		x1[j]=1.0/(1.0+exp(-o1[j]-b1[j]));//隐含层各单元输出
	}

	for(int k=0;k<outNum;k++)
	{
		o2[k]=0.0;
		for(int j=0;j<hideNum;j++)
			o2[k]=o2[k]+w1[j][k]*x1[j];//输出层各单元激活值
		x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//输出层各单元输出
	} 

	for(k=0;k<outNum;k++)
	{
		shuchu[k]=x2[k];
	} 
	return x2;
}////////////////////////////end sim///////////////////////////

⌨️ 快捷键说明

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