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

📄 bp.cpp

📁 BP算法的C++类
💻 CPP
字号:

////////////////////////////////////////////////////////////////////////////
//	File:		BP.cpp
//	Version:	1.0.0.0
//	Created:	16-April-2004
//
//	Author:		Liming liu
//	E-mail:		liulimi0893@sina.com
//
//	Backpropagation algorithm of three layers 
//
//	You are free to use or modify this code to the following restrictions:
//	- Acknowledge me somewhere in your about box, simple "Parts of code by.."
//	will be enough. If you can't (or don't want to), contact me personally.
//	- LEAVE THIS HEADER INTACT
////////////////////////////////////////////////////////////////////////////



// BP.cpp 
//
//版权所有 刘黎明 2004
//晓月儿 2004-40-16
//电子邮箱:  liulimi0893@sina.com
//个人主页:  http://202.204.59.204/2003/bbs0an?path=/groups/GROUP_0/PersonalCorpus/L/liuliming
//您可以无偿使用,传播并修改这份源码,但请保留上述声明
//
/*
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
	文件:tooltipex.cpp

	版权所有(C) 2004 刘黎明

		这一程序是自由软件,你可以遵照自由软件基金会出版的GNU 
	通用公共许可证条款来修改和重新发布这一程序。或者用许可证的
	第二版,或者(根据你的选择)用任何更新的版本。

		发布这一程序的目的是希望它有用,但没有任何担保。甚至没
	有适合特定目地的隐含的担保。更详细的情况请参阅GNU 通用公共
	许可证。

		你应该已经和程序一起收到一份GNU 通用公共许可证的副本。
	如果还没有,写信给:
		The Free Software Foundation, Inc., 
		675  Mass Ave,  Cambridge,	MA02139,  USA

		如果你在使用本软件时有什么问题或建议,用以下地址可以与
	我们取得联系:
		liulimi0893@sina.com
		


	编写:	 刘黎明	(liulimi0893@sina.com)

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
/*
                           
作者概况
姓  名:刘黎明
性  别:男
学    历:在读研究生
学    位:学士
毕业院校:北京科技大学
专  业:计算机科学与技术
出生年月:1980年 10月24日
健康状况:良好
身    高:1.77米
体    重:63公斤
毕业地点:北京
出生地点:湖北随州
电子邮件:liulimi0893@sina.com
联系电话:13691330960
通信地址:北京科技大学638#
邮    编:100083
特    长: 算法设计,组织,管理,交际,书法,写作,善于接受理解新概念新事物,容易适应新环境
     性格描述: 谦虚谨慎,踏实稳重,待人真诚,喜欢挑战
教育背景
1987.7-1993.7 随州市南郊区吴家桥小学 
1993.9 -1996.7 随州市岁丰学校
1996.9-1999.7 就读于湖北省随州市第二高级中学
1999.9-2003.7就读于北京科技大学信息工程学院计算机科学与技术专业
2003.9—今    北京科技大学计算机系系统结构专业硕士研究生
英语水平:具备比较熟练的听说读写能力,已通过英语四级和六级考试(可提供证书)
    技术背景
精通:Visual C++(MFC), .NET C++,
熟悉:.NET C# ,.NET ASP
初级:Delphi,Jbuider,Oracle
          
工作经验
熟悉vc下的MFC编程,曾参加C02IDE(c02语言集成开发环境)的开发,负责用户界面和编辑器的设计,对编译器和调试器有一定的了解。
    获奖情况
1995年,获学科综合竞赛市一等奖(可提供证书)
1998年,获数学联赛市三等奖(可提供证书),
物理奥林匹克省三等奖(可提供证书),
全国英语能力竞赛优胜奖(可提供证书)
1999年,获新生入学一等奖
2000年,获人民奖学金  
2001年,获团委社团工作先进个人称号(可提供证书)
       获人民奖学金
2002年,获‘校三好学生‘称号(可提供证书)
      获人民奖学金    

   社会活动
1999年 参加新生文艺汇演‘七月火把节‘舞蹈,一等奖
2000年 加入ibeike 团队技术部
2001年 第一届院健身运动会上任班级供稿员 
      参加计算机技能大赛
      参加参加校庆书法大赛
      作为候选人参加院学生会副主席竞选
任同心社宣传部部长,多次组织宣传活动
    2003年 班长,新生辅导员
    2004年 历任校研究生会宣传部长,办公室主任,副主席
  
*/

#include "math.h"
#include "stdlib.h" 
#include "stdio.h" 
#include "fstream.h"
//#define RNAD_MAX 1
#define a_sigmoid 1  //sigmoid函数参数
#define b_sigmoid 1  //sigmoid函数参数
#define c_sigmoid 0  //sigmoid函数参数
#define alfa 0.3  //惯性率
#define fi 2.99   //学习率
#define maxpass 100000  //训练次数停止条件
#define numNode 8   //训练样本量
#define testNum 8 //测试数据量
#define inNode 3  //输入层节点数
#define midNode 5  //隐层节点数
#define outNode 1  //输出层节点数
#define pre_error 0.1  //错误率停止条件
double sum_err=0.0;
//int sum_err=0;  //当前训练结果错误率
double W[inNode][midNode]; //输入层至隐层权值
double V[midNode][outNode]; //隐层至输出层权值            
double WInc[inNode][midNode]; //输入层至隐层权值改变量
double VInc[midNode][outNode]; //隐层至输出层权值改变量       
double X[midNode]; //隐层的输入                  
double Y[outNode]; //输出层的输入            
double M[midNode]; //隐层的输出
                  
double O[outNode]; //输出层的输出
                  
double sita[midNode]; //隐层的阈值
                 
double gama[outNode]; //输出层的阈值
                  
//double err_m[N]; //第m个样本的总误差
struct {
		double part[inNode+outNode+1];  //inNode个输入节点,outNode个输出节点,计算结果,分类结果(计算结果>=0.5-->1类,计算结果<0.5-->0类)
	}in[numNode],test[numNode];
 /*struct  InSample
{
	//Sample data;
	InSample * next;

};

int testcount=0;
*/
int i_pass=0;  //训练遍数

ofstream ftrainout,ftestout;  //

//读入样本数据 
int GetSample() 
{
  ifstream fin;
  fin.open("train.txt");
  //fin.getline(buf);
  //linelength=strlen(buf);
  int incount=0;
  while(!fin.eof())
  {
	  for (int i=0;i<inNode+outNode;i++)
	  {
		 fin>>in[incount].part[i];
	     
	  }
	  if(in[incount].part[inNode+outNode-1]>=0.5)
			 in[incount].part[inNode+outNode]=1;
		 else
			 in[incount].part[inNode+outNode]=0;
	  incount++;

  }
  fin.close();
  return incount;
}

//读入测试数据 
int GetTest()
{
  ifstream fintest;
  int incount=0;
  fintest.open("test.txt");
  incount=0;
  //fin.getline(buf);
  //linelength=strlen(buf);
  
  while(!fintest.eof())
  {
	  for (int i=0;i<inNode;i++)
	  {
		 fintest>>test[incount].part[i];
		 
	  }
	  test[incount].part[inNode]=0;   
	  test[incount].part[inNode+1]=0;
	  incount++;


  }
  fintest.close();
  return incount;
}

//参数初始化
void Initial()
{
   double sgn;
   int i,j;				
   for(j=0;j<midNode;j++)			
	   for(i=0;i<inNode;i++)//隐层权、阈值初始化//          
	   {
                    sgn=(double)(rand()/(double)RAND_MAX)-0.5; 
                    W[i][j]= sgn;//隐层输出层权值初始化。
					WInc[i][j]=0;//
                    }
					//randomize();
					for(j=0;j<midNode;j++)
                    {
					sgn=(double)(rand()/(double)RAND_MAX); 
                    sita[j]=sgn; //rnd/1000;//中间层阈值初始化
                    //cout<<"sita"<<sita[j]<<endl;
                    }
					for ( i=0;i<midNode;i++)
						 for (j=0;j<outNode;j++) 
						{
						sgn=(double)(rand()/(double)RAND_MAX)-0.5; 
						 V[i][j]=sgn;//隐层输入层权值初始化。
						 VInc[i][j]=0;//
						}
					 for (j=0;j<outNode;j++) 
                    {                  
					sgn=(double)(rand()/(double)RAND_MAX); 
                    gama[j]=sgn;//输出层阈值初始化
                    //cout<<"gama[k]"<<endl;
                    }
                    return ;
}

//第m个学习样本隐层各单元输入、输出值 
void Pass_In_Mid(int m)
{
	double sigma;			
	int i,j;			
	for (j=0;j<midNode;j++)
	{		
		sigma=0.0;	
		for (i=0;i<inNode;i++)		
			sigma+=W[i][j]*in[m].part[i];//求隐层内积						
		X[j]=sigma - sita[j];//求隐层净输入
		M[j]=a_sigmoid/(1.0+exp(-b_sigmoid*X[j]))-c_sigmoid;//求隐层输出
			
	}
	return;
}

//第m个学习样本输出层各单元输入、输出值 
void Pass_Mid_Out(int m)
{
	double sigma;			
	int i,j;			
	for (j=0;j<outNode;j++)
	{		
		sigma=0.0;	
		for (i=0;i<midNode;i++)	
		{
			sigma+=V[i][j]*M[i];//求隐层内积						
		    
		}
		//ftrainout<<" "<<in[m].part[inNode+j]<<" ";

		Y[j]=sigma - gama[j];//求隐层净输入
		//if(Y[j]==0)
		//	O[j]=5;
		//else
		//	if(fabs(Y[j])<1e-10)
		//		O[j]=1e+10;
		//	else
		O[j]=a_sigmoid/(1.0+exp(-b_sigmoid*Y[j]))-c_sigmoid;//求隐层输出
		in[m].part[inNode+outNode]=O[j];
		//if(i_pass%100==0)
		//  ftrainout<<O[j]<<" ";
	}
	
	return;
}
double Out_Gra[outNode];
double Mid_Gra[midNode];
double m_error[numNode];

//调整输出层、隐层权值			
void Adjust(int m)
{
	int i,j;
	m_error[m]=0;
	for(j=0;j<outNode;j++)
	{
	Out_Gra[j]=(in[m].part[inNode]-O[j])*O[j]*(1-O[j]);
    m_error[m]+=(in[m].part[inNode]-O[0])*(in[m].part[inNode]-O[0])/2;
	}

	double d_add=0.0;
	for(j=0;j<midNode;j++)
	{
		for(int i=0;i<outNode;i++)
			d_add+=V[j][i]*Out_Gra[i];
		Mid_Gra[j]=M[j]*(1-M[j])*d_add;
	}
    
	for ( i=0;i<outNode;i++)
	{
		for (j=0;j<midNode;j++) 
		{					
			VInc[j][i]=alfa*VInc[j][i]+fi*M[j]*Out_Gra[i];//
			
			V[i][j]+=VInc[i][j];
			
		//	ftrainout<<V[i][j]<<" ";
		}
		//gama[i]+=fi*Out_Gra[i];
	}


	for(j=0;j<midNode;j++)	
	{
		for(i=0;i<inNode;i++)
		{
			WInc[i][j]=alfa*WInc[i][j]+fi*in[m].part[i]*Mid_Gra[j];//
		
			W[i][j]+=WInc[i][j];
			
		//	ftrainout<<W[i][j]<<" ";
        }
		//sita[j]+=fi*Mid_Gra[j];
	}
	//ftrainout<<Out_Gra[0]<<" "<<endl;
 return;

}

//全部样本全局误差计算 
double Err_Sum()
{
	double err=0.0;
	for (int i=0;i<numNode;i++)
		err+=m_error[i];
	//fout<<sum_err<<" "<<endl;
	return err;
}

//对第m个测试数据分类
int Classify(int m)
{
	double sigma;			
	int i,j;	
	
	for (j=0;j<midNode;j++)
	{		
		sigma=0.0;	
		for (i=0;i<inNode;i++)		
			sigma+=W[i][j]*test[m].part[i];//求隐层内积						
		X[j]=sigma - sita[j];//求隐层净输入
		//if(X[j]==0)
		//	M[j]=5;
		//else
		M[j]=1.0/(1.0+exp(-X[j]));//求隐层输出
			
	}
		
	for (j=0;j<outNode;j++)
	{		
		sigma=0.0;	
		for (i=0;i<midNode;i++)		
			sigma+=V[i][j]*M[i];//求隐层内积						
		Y[j]=sigma - sita[j];//求层净输入
		//if(Y[j]==0)
		//	O[j]=5;
		//else	
		 O[j]=1.0/(1.0+exp(-Y[j]));//求层输出
		
	}
	test[m].part[inNode]=O[0];
	if(O[0]>=0.5)
		test[m].part[inNode+1]=1.0;
	else
		test[m].part[inNode+1]=0.0;
   // ftestout<<test[m].part[inNode]<<" "<<test[m].part[inNode+1]<<endl;
   
   return 1;
}

void OutputResult()
{

	ofstream fout;
	fout.open("Output.txt");
	int i,j;
	for(j=0;j<inNode;j++)	
	{
		for(i=0;i<midNode;i++)
		{		
			fout<<"weighth of input node No."<<j<<" to hide lay node No."<<i<< ":"<<V[i][j]<<endl;
        }
		//sita[j]+=fi*Mid_Gra[j];
	}
	fout<<endl;
	for ( j=0;j<midNode;j++)
	{
		for (i=0;i<outNode;i++) 
		{
			fout<<"weighth of hide lay node No."<<j<<" to output node No."<<i<<":"<<V[i][j]<<endl;

		}
		//gama[i]+=fi*Out_Gra[i];
	}
	fout<<endl;
	for(j=0;j<numNode;j++)	
	{
		fout<<"computal result of training sample No."<<j<<":"<<in[j].part[inNode+outNode]<<endl;
	}

	fout<<endl;
	for(j=0;j<testNum;j++)	
	{
		fout<<"computal result of test sample No."<<j<<":"<<test[j].part[inNode+outNode-1]<<endl;
	}

    fout.close();

	ftrainout<<sum_err<<endl;
	for(j=0;j<numNode;j++)	
	{
		ftrainout<<in[j].part[inNode+outNode-1]<<" "<<in[j].part[inNode+outNode];
		if((in[j].part[inNode+outNode-1])>=0.5)
			ftrainout<<" 1"<<endl;
		else
			ftrainout<<" 0"<<endl;
	}
		for(j=0;j<testNum;j++)	
	{
		ftestout<<test[j].part[inNode+outNode-1]<<" "<<test[j].part[inNode+outNode]<<endl;
	}


}

void main()
{
 
	
  
  
	
	ftrainout.open("trainoutput.txt");
	ftestout.open("testoutput.txt");
	 

	int i=GetSample();//读入样本数据 
	Initial(); //隐层、输出层权、阈值初始化	
	do	
	{		 						
		for (int m=0;m<numNode;m++) 						
		 {														
					
			 Pass_In_Mid(m); //第m个学习样本隐层各单元输入、输出值 
					
			 Pass_Mid_Out(m); //第m个学习样本输出层各单元输入、输出值 
			 Adjust(m);      //调整输出层、隐层权值										
		 } 				
		 sum_err=Err_Sum(); //全部样本全局误差计算 
		 
		 //ftrainout<<i_pass<<"end"<<endl;
		 i_pass++;
		 if(i_pass>maxpass)
			 break;


	 }           
	 while (fabs(sum_err) > pre_error);

	 GetTest();  //获取测试数据
	 for (int m=0;m<testNum;m++) 
	   Classify(m);  //对第m个测试数据分类
	 
	
	
	 OutputResult();
	 ftrainout.close();
	 ftestout.close();
	 return;
}

⌨️ 快捷键说明

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