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 + -
显示快捷键?