?? 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 + -