bp_net.cpp
来自「故障诊断工作涉及的领域相当广泛」· C++ 代码 · 共 1,535 行 · 第 1/3 页
CPP
1,535 行
}
}
}while(1);
}
}
}
ggg:
if(theerror<tterror[i])
{
theerror=tterror[i];
it=i;
}
//}
// if(theerror<0.002&&stage==0)
// {
// alpha/=2;
// stage++;
// }
if(theerror<0.002&&stage==0)
{
alpha*=0.618;
beta*=0.618;
stage++;
}
if(theerror<0.0012&&stage==1)
{
alpha*=0.618;
beta*=0.618;
stage++;
}
if(theerror<0.0011&&stage==2)
{
alpha*=0.618;
beta*=0.618;
stage++;
}
if(alpha>a0)
alpha=0.00001;
if(beta>b0)
beta=0.00001/2;
}
}
if(cnt>=50)
{
if(cnt2/10*10==cnt2)
if(theerror<100)
{ mx=horzcat(mx,mwArray(cnt));
merror[0]=horzcat(merror[0],mwArray(theerror));
}
}
/* if(cnt>=50)
{
if(cnt2/100*100==cnt2)
if(theerror<100)
{ mx=horzcat(mx,mwArray(cnt));
for(unsigned int j=0;j<nsamp;j++)
{
merror[j]=horzcat(merror[j],mwArray(tterror[j]));
}
}
}*/
if(cnt>1000)
int ccc=0;
if(cnt>loopcnt)
goto endp;
}while(!bsucceed);
}
else if(type==opt)
{
btrained=optimize();
}
endp:
//double bag[5000];
//memset(bag,0,2000);
mwArray me;
for(unsigned int u=0;u<1/*nsamp*/;u++)
{//merror[u].ExtractData(bag);
// memset(bag,0,2000);
// me=vertcat(me,merror[u]);
}
// int l=mx.Size(1);
// int c=mx.Size(2);
// l=me.Size(1);
// c=me.Size(2);
VARIANT vx,ve;
// mx.ExtractData(bag);
mwArray2VARIANT(&vx,mx);
mwArray2VARIANT(&ve,merror[0]);;
iplot->easyplot(vx,ve);
btrained=bsucceed;
}
btrained=1;
return btrained;
}
#define rand rand_func
#undef rand //rand_func
int bp_net::offset(double step,double theerror[],unsigned int num_samp,double *databag, double *arrow, unsigned int weishu)
{ double delta=step/5;
reset(databag);
foward(num_samp);
theerror[1]=error(num_samp);//中心误差
for(unsigned k=0;k<weishu;k++)
databag[k]+=delta*arrow[k];
reset(databag);
foward(num_samp);
theerror[2]=error(num_samp);//上误差
for(k=0;k<weishu;k++)
databag[k]+=-2*delta*arrow[k];
reset(databag);
foward(num_samp);
theerror[0]=error(num_samp);//下误差
for(k=0;k<weishu;k++)
databag[k]+=delta*arrow[k];
reset(databag);
if(theerror[0]>theerror[1]&&theerror[1]>theerror[2])
return -1;
else if(theerror[0]<theerror[1]&&theerror[1]<theerror[2])
return 1;
else
return 0;
}
double bp_net::search2min(int num_sam,double databag[],double arrow[],unsigned weishu)
{ double step=512;
double theerror[3];
//double* temp=new double[weishu];
//double* databag0=new double[weishu];
//double* mid=new double[weishu];
double temp[200];
double databag0[200];
double mid[200];
double *left,*right;
unsigned int num_arrow=0;
for(unsigned int i=0;i<nsamp;i++)//单个样本迭待次数
{ //do{
for(unsigned int j=0;j<weishu;j++)//按向量个数峰别搜索
{ for(unsigned int k=0;k<weishu;k++)//保存向量初始值
databag0[k]=databag[k];
for(k=0;k<weishu;k++)//向量初始值容器
temp[k]=databag[k];
int where=1;
unsigned int cnt=-1;
int v=offset(step,theerror,num_sam,databag,arrow+j*weishu,weishu);
//寻找位于最小点两侧的两个点
if(v==-1)//初始点在最小点左面
{ where=0;
cnt=0;
do{if(cnt>0)
for(unsigned k=0;k<weishu;k++)//当前点右移
databag[k]=temp[k];
for(unsigned k=0;k<weishu;k++)
temp[k]=databag[k]+step*arrow[j*weishu+k];
//reset(temp);
cnt++;
v=offset(step,theerror,num_sam,temp,arrow+j*weishu,weishu);
if(v==0)
{for(unsigned k=0;k<weishu;k++)
databag[k]=temp[k];
goto goon;
}
}while(v==-1);
left=databag;
right=temp;
}
else if(v==1)//初始点在最小点右面面
{cnt=0;
where=2;
do{if(cnt>0)
for(unsigned k=0;k<weishu;k++)//当前点左移
databag[k]=temp[k];
cnt++; //step/=2;
for(unsigned k=0;k<weishu;k++)
temp[k]=databag[k]-step*arrow[j*weishu+k];
v=offset(step,theerror,num_sam,temp,arrow+j*weishu,weishu);
if(v==0)
{for(unsigned k=0;k<weishu;k++)
databag[k]=temp[k];
goto goon;
}
}while(v==1);
left=temp;
right=databag;
}
else //初始点是最小点!
break;
if(where=0)//在最小点左面
{
do{for(unsigned k=0;k<weishu;k++)
mid[k]=(left[k]+right[k])/2;
step/=2;
v=offset(step,theerror,num_sam,mid,arrow+j*weishu,weishu);
if(v==-1)
left=mid;
else if(v==2)
right=mid;
else
break;
}while(1);
}
else if(where=2)//在最小点右面面
{
do{for(unsigned k=0;k<weishu;k++)
mid[k]=(left[k]+right[k])/2;
step/=2;
int v=offset(step,theerror,num_sam,mid,arrow+j*weishu,weishu);
if(v==1)
right=mid;
else if(v==2)
left=mid;
else
break;
}while(1);
}
for(k=0;k<weishu;k++)//最优向量存放
databag[k]=mid[k];
goon: for(k=0;k<weishu;k++)
arrow[k+j*weishu]=databag[k]-databag0[k];//该方向的前进向量
}
unsigned int jmp=0;
if(num_arrow==weishu-1)
jmp=num_arrow+1;
// step=0;
for(unsigned k=0;k<weishu;k++)
arrow[num_arrow*weishu+k]+=arrow[(num_arrow+1-jmp)*weishu+k];
// for(k=0;k<weishu;k++)
// step+=arrow[num_arrow*weishu+k]*arrow[num_arrow*weishu+k]+\
arrow[(num_arrow+1-jmp)*weishu+k]*arrow[(num_arrow+1-jmp)*weishu+k];
num_arrow++;
if(num_arrow==weishu)
num_arrow=0;
// }while(theerror[1]>stderror);//单个样本优化搜索
}
// delete temp;
// delete databag0;
return theerror[0];
}
BOOL bp_net::optimize()
{
unsigned int where=0,cnt=0;
unsigned int weishu=0;
BOOL bsucceed=FALSE;;
for(unsigned int i=0;i<nlayer;i++)
weishu+=player[i].weight.Size(1)*player[i].weight.Size(2)+player[i].weight.Size(1);
weishu+=weightout.Size(1)*weightout.Size(2)+weightout.Size(1);
double* databag=new double[weishu];//权值和阈值
double* arrow=new double[weishu*weishu];//方向向量
memset(arrow,0,sizeof(double)*weishu*weishu);
for(i=0;i<weishu;i++)
arrow[(weishu-i-1)*weishu]=1;//初始化方向向量
for(i=0;i<weishu;i++)
databag[i]=(double)(::rand())/32768;//初始化权值和阈值
do{
for(i=0;i<nsamp;i++)
{ reset(databag);
tterror[i]=search2min(i,databag,arrow,weishu);
if(tterror[i]>stderror)
bsucceed=FALSE;
}
cnt++;
if(cnt==500)
int vv=0;
}while(!bsucceed&&cnt<=2000);
return bsucceed;
}
#define rand rand_func
void bp_net::run()
{
}
void bp_net::operator =(bp_net &in)
{
alpha=in.alpha;
bempty=in.bempty;
beta=in.beta;
btrained=in.btrained;
bvalid=in.bvalid;
cnt=in.cnt;
dedlastin=in.dedlastin;
dipan=in.dipan;
// failuretype=in.failuretype;
frenew=in.frenew;
// ibag=in.ibag;
// is=in.is;
lastbar=in.lastbar;
lastin=in.lastin;
layin=in.layin;
layout=in.layout;
mdata=in.mdata;
mdout=in.mdout;
//merror=in.merror;
mwin=in.mwin;
mwout=in.mwout;
mwstdout=in.mwstdout;
mx=in.mx;
ndata=in.ndata;
ndcnt=in.ndcnt;
nin=in.nin;
nlayer=in.nlayer;
nout=in.nout;
nsamp=in.nsamp;
nscnt=in.nscnt;
nsdocnt=in.nsdocnt;
// os=in.os;
// pdata=in.pdata;
// pdataout=in.pdataout;
player=new bp_layer[nlayer];
for(unsigned int i=0;i<nlayer;i++)
player[i]=in.player[i];
prelastbar=in.prelastbar;
preweightout=in.preweightout;
// pvin=in.pvin;
// pvout=in.pvout;
// pvstdout=in.pvstdout;
stderror=in.stderror;
theerror=in.theerror;
type=in.type;
weightout=in.weightout;
}
BOOL bp_layer::is_snap(const CPoint &point)
{
if(dipan.PtInRect(point))
{ frenew=TRUE;
return TRUE;
}
return FALSE;
}
void bp_layer::draw_area(CDC *pdc,BOOL visible)
{ CPen* pNewPen=new CPen;
pNewPen->CreatePen(0,5,RGB(50,50,255));
CPen* oldpen=pdc->SelectObject(pNewPen);
if(visible)
{
pdc->MoveTo(dipan.left,dipan.top);
pdc->LineTo(dipan.left,dipan.bottom);
pdc->LineTo(dipan.right,dipan.bottom);
pdc->LineTo(dipan.right,dipan.top);
pdc->LineTo(dipan.left,dipan.top);
}
else
{ unsigned long bkcolor= pdc->GetBkColor();
CPen* pNewPen=new CPen;
pNewPen->CreatePen(0,5,bkcolor);
pdc->SelectObject(pNewPen);
//覆盖先前的地盘
pdc->MoveTo(dipan.left,dipan.top);
pdc->LineTo(dipan.left,dipan.bottom);
pdc->LineTo(dipan.right,dipan.bottom);
pdc->LineTo(dipan.right,dipan.top);
pdc->LineTo(dipan.left,dipan.top);
frenew=FALSE;
}
pdc->SelectObject(oldpen);
}
void bp_net::renew_layer(CDC *pdc,CPoint& point)
{
if(layin.is_snap(point))
layin.draw_area(pdc,TRUE);
else if(!layin.is_snap(point)&&layin.frenew)
layin.draw_area(pdc,FALSE);
for(unsigned int i=0;i<nlayer;i++)
{if(player[i].is_snap(point))
{
player[i].draw_area(pdc,TRUE);
bp_layer_dialog lydlg(player+i);
lydlg.DoModal();
this->func_type=(bp_net_function)layout.type;
// bpinfodlg dlg;
// dlg.DoModal();
}
else if(!player[i].is_snap(point)&&player[i].frenew)
player[i].draw_area(pdc,FALSE);
}
if(layout.is_snap(point))
{
layout.draw_area(pdc,TRUE);layout.draw_area(pdc,TRUE);
bp_layer_dialog lydlg(&layout);
lydlg.DoModal();
}
else if(!layout.is_snap(point)&&layout.frenew)
layout.draw_area(pdc,FALSE);
}
BOOL bp_net::read_data(double **ibag,char** errorinfo)
{
unsigned int count=0,incount=0,i=0;
CString filename,line,fileext;
filename.Empty();
CFileDialog dlg(TRUE);
if(IDOK==dlg.DoModal())
{
filename=dlg.GetFileName();
fileext=dlg.GetFileExt();
if(!filename.IsEmpty())
{CFile* filebin=new CFile(filename,CFile::modeRead);
if(filebin!=NULL)
{
CArchive ar(filebin,CArchive::load);
CFile* fp=ar.GetFile();
unsigned int lth=fp->GetLength();
char bag0[64];
*ibag=new double[lth/2];
char* bag=bag0,c=-1;
CString info;
info.Empty();
do{
ar>>c;
count++;//字符计数
}while(c!='{'&&count<lth);
info+='\0';
do{
do{
ar>>c;
if((c>='0'&&c<='9')||c=='.')
*(bag++)=c;
count++;//字符计数
}while(c!=','&&c!='}'&&c!=' '&&c!=';'\
&&c!='{'&&c!='\n'&&c!=EOF);
if(bag!=bag0)
{ incount++;
*(*ibag+i++)=atof(bag0);
bag=bag0;
memset(bag,0,sizeof(char)*64);
if(c=='}')
goto tail;
}
}while(count<lth);
tail:
ar.Close();
filebin->Close();
;
}
}
}
else
return FALSE;
unsigned ndata=incount/nin;
realloc(*ibag,incount*sizeof(double));
ndcnt=incount;
if(ndata>0)
{
pdata=*ibag;
mdata=mwArray(nin,ndata,pdata);
if(pdataout)
delete[] pdataout;
pdataout=new double[nout*ndata];
}
return TRUE;
}
BOOL bp_net::read_samp(double **ibag,char** errorinfo)
{unsigned int count=0,incount=0,outcount=0,i=0;
unsigned int index=0;
CString filename,line,fileext;
BOOL bincnt=TRUE,bfailure=FALSE;
filename.Empty();
CFileDialog dlg(TRUE);
if(IDOK==dlg.DoModal())
{
filename=dlg.GetFileName();
fileext=dlg.GetFileExt();
if(!filename.IsEmpty())
{CFile* filebin=new CFile(filename,CFile::modeRead);
if(filebin!=NULL)
{
CArchive ar(filebin,CArchive::load);
CFile* fp=ar.GetFile();
unsigned int lth=fp->GetLength();
char* bag0=new char[64];
*ibag=new double[lth/2];
char* bag=bag0,c=-1;
CString info;
info.Empty();
do{
ar>>c;
count++;//字符计数
}while(c!='{'&&count<lth);
info+='\0';
do{
do{
ar>>c;
if((c>='0'&&c<='9')||c=='.')
*(bag++)=c;
count++;//字符计数
}while(c!=','&&c!='}'&&c!=' '&&c!=';'\
&&c!='{'&&c!='\n'&&c!=EOF);
if(c=='{')
bincnt=FALSE;
if(bag!=bag0)
{
if(bincnt)
incount++;
else
outcount++;
*(*ibag+i++)=atof(bag0);
if(c=='}'&&!bincnt)
{bfailure=TRUE;
bag=bag0;
memset(bag,0,sizeof(char)*64);
goto failureinfo;
}
bag=bag0;
memset(bag,0,sizeof(char)*64);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?