📄 dynbp.cpp
字号:
#include "stdafx.h"
#include "ANNdemo.h"
#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#include <fstream.h>
#include <assert.h>
#include <math.h>
#include "dynbp.h"
int G_FilePos; //文件位置
float G_rand_max; //随机函数最大值参数
float G_rand_min; //随机函数最小值参数
////////////////////////////////////////////////////////////////////////////////
float random(float max,float min)
{
return (float)rand()/RAND_MAX*(max-min)+min;
}
//------------------------------------------------------------------------------
//模型函数y=1/(1+e(-x))
float sigmoid(float val)
{
return 1/(1+exp(-val));
}
//------------------------------------------------------------------------------
float sqr(float val)
{
return val*val;
}
//------------------------------------------------------------------------------
float normal(float val,float max,float min)
{
return (val-min)/(max-min);
}
//------------------------------------------------------------------------------
float anti_normal(float val,float max,float min)
{
return val*(max-min)+min;
}
////////////////////////////////////////////////////////////////////////////////
CNote::CNote()
{
fThreshold=random(G_rand_max, G_rand_min);
fActivation=0;
fErr=0;
}
//------------------------------------------------------------------------------
CNote::~CNote()
{
}
////////////////////////////////////////////////////////////////////////////////
CLayer::CLayer()
{
///////////////////////NEED IMPROVE/////////////////////////////
/////////////Different layer different nodenum///////////
ifstream rdfile("setting.txt");
assert(rdfile);
rdfile.seekg(G_FilePos,ios::beg);//文件指针置于上次访问文件结束处
char str[20];
rdfile>>str;
// cout<<str;
rdfile>>nNote_num;//取当前层节点数
// cout<<nNote_num<<endl;
streampos fp=rdfile.tellg();//取当前文件指针
G_FilePos=fp;//存储当前文件指针
rdfile.close();
pNote=new CNote[nNote_num];
}
//------------------------------------------------------------------------------
CLayer::~CLayer()
{
delete []pNote;
}
////////////////////////////////////////////////////////////////////////////////
CNet::CNet()
{
create_net();
create_weight();
}
//------------------------------------------------------------------------------
CNet::~CNet()//网络和权矩阵删除顺序和初始化顺序相反!!!
{
remove_weight();
remove_net();
}
//------------------------------------------------------------------------------
//神经网络的建立函数,建立的层和每层的节点数
void CNet::create_net()
{
///////////////////////NEED IMPROVE/////////////////////////////
/*
G_rand_max=0.5;//取随机函数最大值
G_rand_min=-0.5;//取随机函数最小值
fNorMax=1;//取归一化最大值
fNorMin=0;//取归一化最小值
nLay_num=3;//取层数
fRate=.5;//取学习率
pLayer=new CLayer[nLay_num];
*/
ifstream setfile("setting.txt");
assert(setfile);
char str[20];
setfile>>str;
// cout<<str;
setfile>>G_rand_max;//取随机函数最大值
// cout<<G_rand_max<<endl;
setfile>>str;
// cout<<str;
setfile>>G_rand_min;//取随机函数最小值
// cout<<G_rand_min<<endl;
setfile>>str;
// cout<<str;
setfile>>fNorMax;//取归一化最大值
// cout<<fNorMax<<endl;
setfile>>str;
// cout<<str;
setfile>>fNorMin;//取归一化最小值
// cout<<fNorMin<<endl;
// cout<<endl;
setfile>>str;
// cout<<str;
setfile>>nLay_num;//取层数
// cout<<nLay_num<<endl;
setfile>>str;
// cout<<str;
setfile>>fRate;//取学习率
// cout<<fRate<<endl;
streampos fp=setfile.tellg();//取当前文件指针
G_FilePos=fp;//存储当前文件指针
setfile.close();
pLayer=new CLayer[nLay_num];
/////////////////NEED IMPROVE/////////////////////
int nIn=pLayer[0].nNote_num;//输入层节点数
int nOut=pLayer[nLay_num-1].nNote_num;//输出层节点数
/////////////////NEED IMPROVE///////////////////////////////////
ifstream trfile("example.txt");
assert(trfile);
trfile>>str;
trfile>>nGroup_num;//获取样本数据组数
//----------------------------------------
pGroup_in=new float*[nGroup_num]; //申请输入样本矩阵
pGroup_out=new float*[nGroup_num];//申请输出样本矩阵
pNor_in=new float*[nGroup_num]; //申请归一化输入矩阵
pNor_out=new float*[nGroup_num]; //申请归一化输出矩阵
for(int i=0;i<nGroup_num;++i)
{
pGroup_in[i]=new float[nIn];
pGroup_out[i]=new float[nOut];
pNor_in[i]=new float[nIn];
pNor_out[i]=new float[nOut];
}
//----------------------------------------
for(i=0;i<nGroup_num;++i) //读入样本数据
{
trfile>>str;
for(int j=0;j<nIn;++j)
{
trfile>>pGroup_in[i][j];//输入
pNor_in[i][j]=normal( pGroup_in[i][j], fNorMax, fNorMin);
}
for(int k=nIn;k<nIn+nOut;++k)
{
trfile>>pGroup_out[i][k-nIn];//输出
pNor_out[i][k-nIn]=normal( pGroup_out[i][k-nIn], fNorMax, fNorMin);
}
}
trfile.close();
}
//------------------------------------------------------------------------------
//用于结束时的释放空间
void CNet::remove_net()
{
for(int i=0;i<nGroup_num;++i)//释放样本数据数组
{
delete []pGroup_in[i];
delete []pGroup_out[i];
delete []pNor_in[i];
delete []pNor_out[i];
}
delete []pGroup_in;
delete []pGroup_out;
delete []pNor_in;
delete []pNor_out;
delete []pLayer;
}
//------------------------------------------------------------------------------
//产生随机的权值
void CNet::create_weight()
{
pWeight=new float**[nLay_num-1];
for(int i=0;i<nLay_num-1;++i)//权矩阵数比层数少1
{
pWeight[i]=new float*[pLayer[i].nNote_num];
for(int j=0;j<pLayer[i].nNote_num;++j)
pWeight[i][j]=new float[pLayer[i+1].nNote_num];
}
for(i=0;i<nLay_num-1;++i)
for(int j=0;j<pLayer[i].nNote_num;++j)
for(int k=0;k<pLayer[i+1].nNote_num;++k)
{
pWeight[i][j][k]=random(G_rand_max, G_rand_min);
}
}
//------------------------------------------------------------------------------
//相应的释放空间
void CNet::remove_weight()
{
for(int i=0;i<nLay_num-1;++i)
{
for(int j=0;j<pLayer[i].nNote_num;++j)
delete []pWeight[i][j];
delete []pWeight[i];
}
delete []pWeight;
}
//------------------------------------------------------------------------------
//正向传输的计算函数
void CNet::propagation(float *pInput)
{
float sum;
for(int i=0; i<pLayer[0].nNote_num; ++i)//获取输入层数据
pLayer[0].pNote[i].fActivation=pInput[i];
for(i=1; i<nLay_num; ++i)//正向计算隐层及输出层的激活值
for(int j=0; j<pLayer[i].nNote_num; ++j)
{
sum=0;
for(int k=0; k<pLayer[i-1].nNote_num; ++k)
sum+=pLayer[i-1].pNote[k].fActivation*pWeight[i-1][k][j];
sum+=pLayer[i].pNote[j].fThreshold;
pLayer[i].pNote[j].fActivation=sigmoid(sum);
}
}
//------------------------------------------------------------------------------
// 反向误差传输的计算函数
void CNet::back_propagation(float *pTeach)
{
int nOut=nLay_num-1;
float fAct,fNext_err;
for(int i=nLay_num-1;i>0;--i)
for(int j=0;j<pLayer[i].nNote_num;++j)
{
fAct=pLayer[i].pNote[j].fActivation;
if(i==nOut)//输出层节点
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -