📄 bp.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 + -