📄 bplayer.cpp
字号:
// BPLayer.cpp: implementation of the CBPLayer class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "trainbp.h"
#include "BPLayer.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBPLayer::CBPLayer()
{
}
CBPLayer::~CBPLayer()
{
}
CMatrix CBPLayer::DeltaF()
{
CMatrix temp;
switch( FunctionType )
{
case CBPLayer::purelin:
temp.Ones(V.RowNo(),V.ColNo());
return temp;
case CBPLayer::logsig:
temp=V.Mul(1-V);
return temp;
case CBPLayer::tansig:
temp=1.0-V.Mul(V);
return temp;
default:
VERIFY(FALSE);
}
return temp;
}
void CBPLayer::initiate(unsigned int NumIn, unsigned int NumOut, unsigned int Mode, double l)
{
unsigned int i,j;
lr=l;//学习速率
FunctionType=(FunctionMode)Mode;
srand( (unsigned)time( NULL ) );
W.SetSize(NumOut,NumIn);
for( i=0; i<W.RowNo(); i++)
for( j=0; j<W.ColNo(); j++)
W(i,j)=rand();
W=W-double(RAND_MAX/2);
W/=double(RAND_MAX/2);
B.SetSize(NumOut,1);
for( i=0; i<B.RowNo(); i++)
for( j=0; j<B.ColNo(); j++)
B(i,j)=rand();
B=B-double(RAND_MAX/2);
B/=double(RAND_MAX/2);
}
void CBPLayer::ForWard(CMatrix &P1)
{
CMatrix t1(1,P1.ColNo());
t1.Ones();//置1
P=&P1;
V=W*P1+B*t1;
F(); //Y=F(V)
return ;
}
CMatrix CBPLayer::BackWard(CMatrix &E)
{
CMatrix t1(E.ColNo(), 1);
t1.Ones();
D=DeltaF().Mul(E);
CMatrix dw=D*(~(*P))*lr;
CMatrix db=D*t1*lr;
D=~W*D;
W+=dw;//更新权系数
B+=db;
return D;
}
void CBPLayer::F()
{
switch( FunctionType )
{
case CBPLayer::purelin:
Y=V;
return;
case CBPLayer::logsig:
Y=(1+Exp(-V)).Div();//1./(1+exp(-v))
return;
case CBPLayer::tansig:
Y=(1+Exp(-2*V)).Div()*2.0 -1.0;//2.0./(1+exp(-2v))
return;
default:
VERIFY(FALSE);
}
}
//////////////////////////////////////////////////////////////////////
// CBPNet Class
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBPNet::CBPNet()
{
}
CBPNet::~CBPNet()
{
}
void CBPNet::init(CEdit * edit_message,double m_lr,int m_num)
{
CString message;
m_message=edit_message;
//m_message->SetLimitText( 40000 );
m_message->SetSel( 0, -1);
m_message->Clear();
m_message->ReplaceSel("三层结构\r\n第一层:1输入,5输出,logsis\r\n");
//m_message->LineScroll(1);
//m_message->ReplaceSel("");
m_message->ReplaceSel("第二层:5输入,1输出,purelin\r\n");
P.SetSize(1,20);//21个输入数据
T.SetSize(1,20);//21个输出数据
m_message->ReplaceSel("公式为e(-d/10)sin(d)\r\n");
m_message->ReplaceSel("21个输入数据 21个输出数据\r\n");
lr=m_lr;
l1.initiate(1, 25, CBPLayer::tansig,lr/5);//1输入,5输出,logsis
l2.initiate(25, 1, CBPLayer::purelin,lr);//5输入,1输出,purelin
err_goal=0.01;
max_epoch=m_num;//运行100次
message.Format("学习速率:%f 运行%d次\r\n\r\n",lr,m_num);
m_message->ReplaceSel(message);
//初始化输入、输出数据
unsigned int i;
double d;
for(i=0,d=0.0; i<20; i++,d+=4*3.14159265/20)
{
P(0,i)=d;
T(0,i)=exp(-d/10.0)*sin(d);//公式为e(-d/10)sin(d)
}
}
void CBPNet::ForWard()
{
l1.ForWard(P);
l2.ForWard(l1.Y);
E=T-l2.Y;
sse=E.Norm();
}
void CBPNet::BackWard()
{
l1.BackWard(l2.BackWard(E));
}
void CBPNet::Train()
{
int i;
CString message;
for(i=0; i<max_epoch; i++)
{
ForWard();
if(sse<err_goal)break;
BackWard();
message.Format( "运行次数 = %d, 误差 = %f\r\n", i, sse );
m_message->ReplaceSel(message);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -