📄 bpnetdlg.cpp
字号:
fplot10=1; //
nunit[nhlayer+1]=noutattr;
nunit[0]=ninattr;
}
void CBPNetDlg::init()
{
int len1,len2,i;
float *p1,*p2,*p3,*p4;
len1=len2=0;
nunit[nhlayer+2]=0;
for(i=0;i<(nhlayer+2);i++)
{
len1+=(nunit[i]+1)*nunit[i+1];
len2+=nunit[i]+1;
}
p1=(float *)calloc(len1+1,sizeof(float));//权指针
p2=(float *)calloc(len2+1,sizeof(float));//输出指针
p3=(float *)calloc(len2+1,sizeof(float));//误差指针
p4=(float *)calloc(len1+1,sizeof(float));//delw指针
wtptr[0]=p1;//设置初始的指针
outptr[0]=p2;
errptr[0]=p3;
delw[0]=p4;
for(i=1;i<(nhlayer+1);i++)//设置其余的指针值
{
wtptr[i]=wtptr[i-1]+nunit[i]*(nunit[i-1]+1);
delw[i]=delw[i-1]+nunit[i]*(nunit[i-1]+1);
}
for(i=1;i<(nhlayer+2);i++)
{
outptr[i]=outptr[i-1]+nunit[i-1]+1;
errptr[i]=errptr[i-1]+nunit[i-1]+1;
}
for(i=0;i<nhlayer+1;i++)//set up threshold outputs
{
*(outptr[i]+nunit[i])=1.0;
}
}
void CBPNetDlg::initwt()//initialize weights with random
{//numbers between -0.5 and +0.5
int i,j;
for(j=0;j<nhlayer+1;j++)
for(i=0;i<(nunit[j]+1)*nunit[j+1];i++)
{
*(wtptr[j]+i)=(float)random()/(float)pow(2.0,15.0)-(float)0.5;
*(delw[j]+i)=0.0;
}
}
long randseed=568731L;
int CBPNetDlg::random()
{
randseed=15625L*randseed+22221L;
return((randseed>>16)&0x7FFF);
}
int CBPNetDlg::rumelhart(int from_snum,int to_snum)//向后反馈,输出-〉输入
{
int i,j,k,m,n,p ,offset,index,flag;
float out;
char *err_file="criter.dat";
CString cstemp,s1;
cnt=0;
nsold=0;
flag=0;
result=CONTNE;
if (fplot10==1)
if((fp3=fopen(err_file,"w"))==NULL)
{
perror("cannot open error file");
return -1;
}
do {
err_curr=0.0;//系统当前误差
for(i=from_snum;i<to_snum;i++)//开始层到结束层
{
forward(i);//向前计算
for(m=0; m<nunit[nhlayer+1];m++)
{
out=*(outptr[nhlayer+1]+m);//实际输出
*(errptr[nhlayer+1]+m)=(target[i][m]-out)*(1-out)*out;//输出层的误差
}
//隐藏层误差计算
for(m=nhlayer+1;m>=1;m--)
{
for(n=0;n<nunit[m-1]+1;n++)
{
*(errptr[m-1]+n)=0.0;
for(p=0;p<nunit[m];p++)
{
offset=(nunit[m-1]+1)*p+n;
*(delw[m-1]+offset)=eta*(*(errptr[m]+p))*(*(outptr[m-1]+n))
+alpha*(*(delw[m-1]+offset));
*(errptr[m-1]+n)+=*(errptr[m]+p)*(*(wtptr[m-1]+offset));
}
*(errptr[m-1]+n)=*(errptr[m-1]+n)*(1-*(outptr[m-1]+n))*(*(outptr[m-1]+n));
}
}
//调整权
for(m=1; m<nhlayer+2;m++)
{
for(n=0; n<nunit[m];n++)
{
for(p=0;p<nunit[m-1]+1;p++)
{
offset=(nunit[m-1]+1)*n+p;
*(wtptr[m-1]+offset)+=*(delw[m-1]+offset);
}
}
}
ep[i]=0.0;//样本集误差
for(m=0;m<nunit[nhlayer+1];m++)
{
ep[i]+=(float)fabs((target[i][m]-*(outptr[nhlayer+1]+m)));
}
err_curr+=ep[i]*ep[i];
}
err_curr=(float)0.5*err_curr/ninput;//改进
if(fplot10==1)
fprintf(fp3,"%d,%e\n",cnt,err_curr);
cnt++;
result=introspective(from_snum,to_snum);//自检过程,看是否可完成迭代
}while(result==CONTNE);
for(i=from_snum;i<to_snum;i++) forward(i);
//结果显示
for(i=0; i<nhlayer+1;i++){
index=0;
for(j=0;j<nunit[i+1];j++)
{
fprintf(fl,"Weights between unit %d of layer %d ",j,i+1);
fprintf(fl," and units of layer %d \n",i);
for(k=0;k<nunit[i];k++)
fprintf(fl,"%f ",*(wtptr[i]+index++));
fprintf(fl,"\nThreshold of unit %d of layer %d is %f\n\n",j,i+1,*(wtptr[i]+index++));
}
}
fprintf(fl,"\n");
char t1[64],t2[64],t3[64];
for(i=0; i<ninput;i++)
{
for(j=0; j<noutattr;j++)
{
s1.Format(" %7.6f %7.6f",output[i][j],target[i][j]);//输出和目标
}
cstemp.Format(" %d ",i);//样本
cstemp=cstemp+s1;
sscanf(cstemp,"%s%s%s",t1,t2,t3);
int index = m_ListCtrl1.InsertItem(i,t1);//在第一列中的显示
m_ListCtrl1.SetItemText(index,1,t2);//第二列的显示
m_ListCtrl1.SetItemText(index,2,t3);//j的位置为所要插入的位置
}
return(result);
}
void CBPNetDlg::forward(int i)//向前传播,即由输入到输出
{
int m,n,p,offset;
float net;
for(m=0;m<ninattr;m++)
*(outptr[0]+m)=input[i][m];
for(m=1; m<nhlayer+2;m++)
{
for(n=0;n<nunit[m];n++)
{
net=0.0;
for(p=0; p<nunit[m-1]+1;p++)
{
offset=(nunit[m-1]+1)*n+p;
net+=*(wtptr[m-1]+offset)*(*(outptr[m-1]+p));
}
*(outptr[m]+n)=(float)1/(float)(1+exp(-net));//激活函数公式
}
}
for (n=0;n<nunit[nhlayer+1];n++)
output[i][n]=*(outptr[nhlayer+1]+n);
}
int CBPNetDlg::introspective(int nfrom,int nto)//看迭代是否结束
{
int i, flag;
if(cnt>=cnt_num)//超过循环次数
return(FEXIT);
nsnew=0;
flag=1;
for(i=nfrom;(i<nto)&&(flag==1);i++)
{
if(ep[i]<=maxep) nsnew++;//最大干扰值
else
flag=0;
}
if((flag==1))
return(SEXIT);
if((err_curr<=maxe) ) return(SEXIT);//学习精度
return(CONTNE);
}
void CBPNetDlg::dwrite( CString taskname )//学习结果写入
{
int i,j,c;
CString var_file_name;
var_file_name=taskname;
var_file_name=var_file_name+"_v.dat";
if ((fp1=fopen(var_file_name,"w+"))==NULL)
{
AfxMessageBox("cannot open data file");
return;
}
fprintf(fp1,"%u %u %u %f %f %f %f %u %u\n",
ninput,noutattr,
ninattr,eta,alpha,maxe,maxep,
nhlayer,cnt_num);
for(i=0; i<nhlayer+2;i++){
fprintf(fp1,"%d ",nunit[i]);
}
fprintf(fp1,"\n%d %f ",cnt,err_curr);
fprintf(fp1,"\n");
for(i=0;i<ninput;i++)
{
for(j=0;j<noutattr;j++)
fprintf(fp1,"%f ",output[i][j]);
fprintf(fp1,"\n");
}
if ((c=fclose(fp1))!=0)
AfxMessageBox("\nfile cannot be closed ");
}
void CBPNetDlg::wtwrite(CString taskname)//权写入
{
int i,j,c,k;
CString wt_file_name;
wt_file_name=taskname;
wt_file_name=wt_file_name+"_w.dat";
if ((fp2=fopen(wt_file_name,"w+"))==NULL)
{
AfxMessageBox("Cannot open data file");
return;
}
k=0;
for(i=0;i<nhlayer+1;i++)
for(j=0;j<(nunit[i]+1)*nunit[i+1];j++){
if(k==8){
k=0;
fprintf(fp2,"\n");
}
fprintf(fp2,"%f",*(wtptr[i]+j));
k++;
}
if ((c=fclose(fp2))!=0)
AfxMessageBox("\nfile cannot be closed ");
}
void CBPNetDlg::output_generation()
{
int i,m,nsample;
CString dfile,fnam;
CString cstemp1,cstemp2,s1;
CString cstemp;
TV_ITEM tvItem;//控件风格
tvItem.mask=TVIF_TEXT|TVIF_PARAM;//pszText和cchTextMax成员有效
tvItem.pszText = "关于输出的相关信息";
tvItem.cchTextMax=2;//字符大小
TV_INSERTSTRUCT tvInsert;//表示项目在树中的位置
tvInsert.hParent=TVI_ROOT;//项目插入到视图的根部
tvInsert.hInsertAfter=TVI_LAST;//在列表末插入项目
tvInsert.item=tvItem;//定义将加入到树视图控件的项目的TV_ITEM结构
HTREEITEM hRoot=m_TreeCtrl2.InsertItem(&tvInsert);//得到目录位置
char ctemp[50];
nsample=7;//处理数据的个数
dfile="data.dat";
cstemp.Format("学习模式为%s",task_name);
sscanf(cstemp,"%s",ctemp);
tvItem.pszText=ctemp;
tvItem.cchTextMax=6;//字符大小
tvInsert.hParent=hRoot;//设置父母录为hRoot
tvInsert.item=tvItem;
m_TreeCtrl2.InsertItem(&tvInsert);
cstemp.Format("处理数据的个数%d",nsample);
sscanf(cstemp,"%s",ctemp);
tvItem.pszText=ctemp;
tvItem.cchTextMax=6;//字符大小
tvInsert.hParent=hRoot;//设置父母录为hRoot
tvInsert.item=tvItem;
m_TreeCtrl2.InsertItem(&tvInsert);
cstemp.Format("处理数据文件为%s",dfile);
sscanf(cstemp,"%s",ctemp);
tvItem.pszText=ctemp;
tvItem.cchTextMax=6;//字符大小
tvInsert.hParent=hRoot;//设置父母录为hRoot
tvInsert.item=tvItem;
m_TreeCtrl2.InsertItem(&tvInsert);
if((fp1=fopen(dfile,"r"))==NULL)
{
printf("cannot open this file\n");
return;
}
for(i=0;i<nsample;i++)
for(m=0;m<ninattr;m++)
fscanf(fp1,"%f",&input[i][m]);
//结果输出
char t1[64],t2[64];
for(i=0; i<nsample;i++)
{
s1=" ";
forward(i);
for(m=0; m<noutattr;m++)
{
cstemp1.Format(" %7.6f",*(outptr[nhlayer+1]+m));//输出
s1=s1+cstemp1;
}
cstemp2.Format(" %d ",i);//数据
cstemp2=cstemp2+s1;
sscanf(cstemp2,"%s%s",t1,t2);
int index = m_ListCtrl2.InsertItem(i,t1);//在第一列中的显示
m_ListCtrl2.SetItemText(index,1,t2);//第二列的显示
}
if((i=fclose(fp1))!=0)
AfxMessageBox("cannot close this file\n");
}
void CBPNetDlg::dread(CString taskname)
{
int i,c;
CString var_file_name;
var_file_name=taskname;
var_file_name=var_file_name+"_v.dat";
if ((fp1=fopen(var_file_name,"r"))==NULL)
{
AfxMessageBox("\n can not open data file ");
return;
}
fscanf(fp1,"%d%d%d%f%f%f%f%d%d",&ninput ,&noutattr,&ninattr,
&eta,&alpha,&maxe,&maxep,&nhlayer,&cnt_num);
for(i=0;i<nhlayer+2;i++)
fscanf(fp1,"%d",&nunit[i]);
if ((c=fclose(fp1))!=0)
AfxMessageBox("\nFile cannot be closed ");
}
void CBPNetDlg::wtread(CString taskname)//读权
{
int i,j,c;
CString wt_file_name;
wt_file_name=taskname;
wt_file_name=wt_file_name+"_w.dat";
if ((fp2=fopen(wt_file_name,"r"))==NULL)
{
AfxMessageBox("\n cannot open data file");
return;
}
for (i=0; i<nhlayer+1;i++)
{
for (j=0;j<(nunit[i]+1)*nunit[i+1];j++)
fscanf(fp2,"%f",(wtptr[i]+j));
}
if ((c=fclose(fp2))!=0)
AfxMessageBox("\n File can not be closed ");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -