📄 bp.cpp
字号:
// BP.cpp: implementation of the CBP class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "stdlib.h"
#include "time.h"
#include "BP.h"
#include <math.h>
#include<iostream>
using namespace std;
#define BP_LEARNING (float)(0.6) // 学习系数
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBP::CBP()
{
}
CBP::~CBP()
{
}
CBP::CBP(int f,int sh,int be,int layer)
{
front=f;
shadow=sh;
behind=be;
layernumber=layer;
}
void CBP::initial()
{
int i,j;
first=(double**)calloc(shadow,sizeof(double*)); //输入层权值数组分配内存
for(i=0;i<shadow;i++)
{
first[i]=(double*)calloc(front,sizeof(double));
}
srand((unsigned)time(NULL));
for(i=0;i<shadow;i++) //给权值分配随机数
for(j=0;j<front;j++)
{
first[i][j]=rand()/32767.0;
/* first[i][j]=0.09;*/
/* cout<<first[i][j]<<endl;*/
}
second=(double**)calloc(behind,sizeof(double*)); //隐含层到输出层权值开辟动态空间
for(i=0;i<behind;i++)
{
second[i]=(double*)calloc(shadow,sizeof(double));
}
for(i=0;i<behind;i++) //隐含层到输出层权值赋随机值
for(j=0;j<shadow;j++)
{
second[i][j]=rand()/32767.0;
/*second[i][j]=0.08;*/
}
yuzhi1=(double*)calloc(shadow,sizeof(double));
yuzhi2=(double*)calloc(behind,sizeof(double));
for(i=0;i<shadow;i++)
{
yuzhi1[i]=rand()/32767.0;
/*yuzhi1[i]=0.05;*/ //域值统一赋为0.05
}
for(i=0;i<behind;i++)
{
yuzhi2[i]=rand()/32767.0;
/*yuzhi2[i]=0.05;*/ //域值统一赋为0.05
}
behindlayer=pow(2,behind);
firstweight=(double ***)calloc(behindlayer,sizeof(double **));
for(i=0;i<behindlayer;i++)
{
*(firstweight+i)=(double **)calloc(shadow,sizeof(double *));
}
for(i=0;i<behindlayer;i++)
for(j=0;j<shadow;j++)
{
*(*(firstweight+i)+j)=(double *)calloc(front,sizeof(double));
}
secondweight=(double ***)calloc(behindlayer,sizeof(double **));
for(i=0;i<behindlayer;i++)
{
*(secondweight+i)=(double **)calloc(behind,sizeof(double *));
}
for(i=0;i<behindlayer;i++)
for(j=0;j<behind;j++)
{
*(*(secondweight+i)+j)=(double *)calloc(shadow,sizeof(double));
}
// for(i=0;i<behind;i++)
// {
// Node[i]=0;
// }
/* Noderesult=(int *)calloc(behind,sizeof(int));*/
// for(i=0;i<behind;i++)
// {
// Noderesult[i]=0;
// }
}
/*******************************************************************************/
//weidu是训练样本的个数
//inputarry是训练样本的数组
/******************************************************************************/
double CBP::Train_everynet(int z)
{
int i,j;
double *shinput; //隐含层输入值
double *shoutput; //隐含层输出值
double *beinput; //输出层输入值
double *beoutput; //输出层实际输出
double *deltas; //输出层误差
double *shadowdeltas; //隐含层误差
double m=0.0;
shinput= (double*)calloc(shadow,sizeof(double));
shoutput= (double*)calloc(shadow,sizeof(double));
beinput= (double*)calloc(behind,sizeof(double));
beoutput= (double*)calloc(behind,sizeof(double));
deltas= (double*)calloc(behind,sizeof(double));
shadowdeltas= (double*)calloc(shadow,sizeof(double));
// shuru= (double*)calloc(front,sizeof(double));
// for(j=0;j<front;j++)
// {
// // (*(shuru+j))=(*(inputarry+j)); //输入层的值由外部输入数组赋予
// shuru[j]=inputarry[j];
// }
//正向传输
for(i=0;i<shadow;i++)
{
for(j=0;j<front;j++)
{
shinput[i]+=first[i][j]*shuru[z][j];
}
shoutput[i]=func(shinput[i]+yuzhi1[i]);
}
for(i=0;i<behind;i++)
{
for(j=0;j<shadow;j++)
{
beinput[i]+=second[i][j]*shoutput[j];
}
beoutput[i]=func(beinput[i]+yuzhi2[i]);
}
//反向传输
//先求输出层误差
for(i=0;i<behind;i++)
{
deltas[i]=beoutput[i]*(1-beoutput[i])*(shuru[z][front+i]-beoutput[i]);
}
//再求隐含层误差
for(i=0;i<shadow;i++)
{
double zhongjian=0;
for(j=0;j<behind;j++)
{
zhongjian+=deltas[j]*second[j][i];
}
shadowdeltas[i]=zhongjian*(1-shoutput[i])*shoutput[i];
}
//权值调整
for(i=0;i<behind;i++) //输出和隐含层之间权值的调整
for(j=0;j<shadow;j++)
{
second[i][j]+=BP_LEARNING*deltas[i];
}
for(i=0;i<shadow;i++)
for(j=0;j<front;j++)
{
first[i][j]+=BP_LEARNING*deltas[i]*shoutput[i];
}
for(j=0;j<behind;j++)
{
m+=(shuru[z][front+j]-beoutput[j])*(shuru[z][front+j]-beoutput[j]);
}
// double *shinput; //隐含层输入值
// double *shoutput; //隐含层输出值
// double *beinput; //输出层输入值
// double *beoutput; //输出层实际输出
// double *deltas; //输出层误差
// double *shadowdeltas; //隐含层误差
// shuru ;*inputarry
// cout << *shinput << " " << *shoutput << " " << *beinput << " " << *beoutput << " " << *deltas << " " << *shuru << " " << endl;
// system("pause");
free(shinput);
free(shoutput);
free(beinput);
free(beoutput);
free(deltas);
free(shadowdeltas);
// free(shuru);
return m;
}
double CBP::func(double num)
{
return (double)(1/(1+exp(-num)));
}
void CBP::Trainnet(double **inputarry)
{
int i,j;
int member=0;
int flag=100;
double m=100.0;
shuru=(double **)calloc(layernumber,sizeof(double*));
for(i=0;i<layernumber;i++)
{
*(shuru+i)=(double *)calloc((front+behind),sizeof(double));
}
for(i=0;i<layernumber;i++)
for(j=0;j<(front+behind);j++)
{
shuru[i][j]=inputarry[i][j];
}
while(m>0.4)
{
for(i=0;i<layernumber;i++)
m=Train_everynet(i);
member++;
}
// for(i=0;i<shadow;i++)
// for(j=0;j<front;j++)
// {
// firstweight[l][i][j]=first[i][j];
// cout<<firstweight[l][i][j]<<endl;
// }
// for(i=0;i<behind;i++)
// for(j=0;j<shadow;j++)
// {
// secondweight[l][i][j]=second[i][j];
// cout<<secondweight[l][i][j]<<endl;
// }
cout<<"最终误差是"<<m<<endl;
cout<<"迭代次数是"<<member<<endl;
free(shuru);
}
void CBP::test_everynet(double *inputunarray)
{
int i,j;
int flag=1000;
double *shinput; //隐含层输入值
double *shoutput; //隐含层输出值
double *beinput; //输出层输入值
double *beoutput; //输出层实际输出
// double *deltas; //输出层误差
// double *shadowdeltas; //隐含层误差
double m=0.0;
Node=(int *)calloc(behind,sizeof(int));
shinput= (double*)calloc(shadow,sizeof(double));
shoutput= (double*)calloc(shadow,sizeof(double));
beinput= (double*)calloc(behind,sizeof(double));
beoutput= (double*)calloc(behind,sizeof(double));
// deltas= (double*)calloc(behind,sizeof(double));
// shadowdeltas= (double*)calloc(shadow,sizeof(double));
// shuru1= (double**)calloc(,sizeof(double));
// for(j=0;j<front;j++)
// {
// // (*(shuru+j))=(*(inputarry+j)); //输入层的值由外部输入数组赋予
// shuru[j]=inputarry[j];
// }
// while(l<z)
// {
for(i=0;i<shadow;i++)
{
for(j=0;j<front;j++)
{
shinput[i]+=first[i][j]*inputunarray[j];
}
shoutput[i]=func(shinput[i]+yuzhi1[i]);
}
for(i=0;i<behind;i++)
{
for(j=0;j<shadow;j++)
{
beinput[i]+=second[i][j]*shoutput[j];
}
beoutput[i]=func(beinput[i]+yuzhi2[i]);
// for(j=0;j<behind;j++)
// {
// m+=(beoutput[j])*(beoutput[j]);
// }
if(beoutput[i]<0.3)
{
Node[i]=0;
/* flag=0;*/
}
if(beoutput[i]>0.9)
{
Node[i]=1;
/* flag=0;*/
}
cout<<"This pattern has output: "<<endl;
for(i=0;i<behind;i++)
{
cout<<beoutput[i]<<' ';
}
cout<<endl;
for(i=0;i<behind;i++)
{
cout<<Node[i]<<' ';
}
cout<<endl;
/*cout<<"is patter!"<<endl;*/
}
/* }*/
// double *shinput; //隐含层输入值
// double *shoutput; //隐含层输出值
// double *beinput; //输出层输入值
// double *beoutput; //输出层实际输出
// double *deltas; //输出层误差
// double *shadowdeltas; //隐含层误差
// shuru ;*inputarry
// cout << *shinput << " " << *shoutput << " " << *beinput << " " << *beoutput << " " << *deltas << " " << *shuru << " " << endl;
// system("pause");
free(shinput);
free(shoutput);
free(beinput);
free(beoutput);
free(Node);
// free(deltas);
// free(shadowdeltas);
// free(shuru);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -