📄 bpcolor.cpp
字号:
#include "stdio.h"
#include "iostream.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
const int T=10; //学习的次数
#define arf 0.8
#define beta 0.8
#define BIGRND 0x7fff
double wimnew[3][3],wmonew[3],thmnew[3],thonew;
int ttime=0;
double E[T];
double Sfun(double a)
{
double b,f;
b=exp(-a);
f=1.0/(1+b);
return f;
}
double randnum()
{
double x;
x=(double) rand() / (double) BIGRND;
return x;
}
int samplenum(char *filename)
{
FILE *fp;
int N=0;
if((fp=fopen(filename,"r"))==NULL)
{
printf("Can not open this file!\n");
exit(0);
}
char temp[14];
while(!feof(fp))
{
fgets(temp,15,fp);
N++;
}
fclose(fp);
return N-1;
}
void fileopen(double *sample,double *teinfo,int N,char *filename)
{
FILE *fp;
char temp[20];
if((fp=fopen(filename,"r"))==NULL)
{
printf("Can not open this file!\n");
exit(0);
}
int m=0,tempnum[4],douwei[3],j;
char temp1[10];
for(int num=0;num<N;num++)
{
fgets(temp, 15, fp);
for(int i=0;i<15;i++)
{
if(temp[i]==',')
{
douwei[m]=i;
if(m==0)
{
for(j=0;j<douwei[m];j++)
temp1[j]=temp[j];
tempnum[m]=(int)atoi(temp1);
m++;
}
else
{
for(j=0;j<(douwei[m]-douwei[m-1]);j++)
temp1[j]=temp[douwei[m-1]+j+1];
tempnum[m]=(int)atoi(temp1);
m++;
}
if(m==3)
{
for(j=0;j<(15-douwei[m-1]);j++)
temp1[j]=temp[douwei[m-1]+j+1];
tempnum[m]=(int)atoi(temp1);
}
}
}
*(sample+num*3+0)=(double)tempnum[0]/50.0;
*(sample+num*3+1)=(double)tempnum[1]/50.0;
*(sample+num*3+2)=(double)tempnum[2]/50.0;
*(teinfo+num)=(double)tempnum[3]/10.0;
m=0;
}
fclose(fp);
}
void randyz(double *wim, double *wmo, double *thm,double *tho)
{
int i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
*(wim+i*3*T+j*T+ttime)=randnum();//随机产生 输入层与中间层的网络权值
for(j=0;j<3;j++)
*(wmo+j*T+ttime)=randnum(); //随机产生中间层与输出层的网络权值
for(j=0;j<3;j++)
*(thm+j*T+ttime)=randnum(); //随机产生中间层的阈值
*(tho+ttime)=randnum(); //随机产生输出层的阈值
}
void bp_study(double *sample,double *teinfo,int N,double *wim, double *wmo, double *thm,double *tho,double *Y3)
{
int i,j;
double temp=0.;
double *Y2=new double[N*3];
for(int num=0;num<N;num++)
{
// 计算隐层各节点的输出值
for(j=0;j<3;j++)
{
temp=0.;
for(i=0;i<3;i++)
{
temp=temp+(*(sample+num*3+i))*(*(wim+i*3*T+j*T+ttime));
}
temp=temp-(*(thm+j*T+ttime));
*(Y2+num*3+j)=Sfun(temp);
}//end
//计算输出层节点的输出
temp=0.;
for(j=0;j<3;j++)
{
temp=temp+(*(Y2+num*3+j))*(*(wmo+j*T+ttime));
}
temp=temp-(*(tho+ttime));
*(Y3+num)=Sfun(temp);
//end
//计算输出层节点和隐层节点之间连接权值修正量
double dto;
dto=(*(teinfo+num)-(*(Y3+num)))*(*(Y3+num))*(1-(*(Y3+num)));
//end
//计算隐层节点和输入层节点间连接权值修正量
double dtm[3];
for(j=0;j<3;j++)
{
temp=dto*(*(wmo+j*T+ttime));
dtm[j]=*(Y2+num*3+j)*(1-(*(Y2+num*3+j)))*temp;
}//end
//修正输出层和隐层间连接权值和阈值
for(j=0;j<3;j++)
(*(wmo+j*T+ttime+1))=*(wmo+j*T+ttime)+arf*dto*(*(Y2+num*3+j));
*(tho+ttime+1)=*(tho+ttime)+beta*dto;
//end
//修正隐层和输入层间连接权值和阈值
for(i=0;i<3;i++)
for(j=0;j<3;j++)
*(wim+i*3*T+j*T+ttime+1)=*(wim+i*3*T+j*T+ttime)+arf*dtm[j]*(*sample+num*3+i);
for(j=0;j<3;j++)
*(thm+j*T+ttime+1)=*(thm+j*T+ttime)+arf*dtm[j];
//end
}//学习完所有的样本
//计算误差
temp=0;
for(num=0;num<N;num++)
temp=temp+(*(teinfo+num) - (*(Y3+num))) * (*(teinfo+num)-(*(Y3+num)));
E[ttime]=temp/(2*N);
E[ttime]=sqrt(E[ttime]);
//计算ttime+1次的误差
double *Y2t=new double[N*3];
double *Y3t=new double[N];
for(num=0;num<N;num++)
{
// 计算隐层各节点的输出值
for(j=0;j<3;j++)
{
temp=0;
for(i=0;i<3;i++)
{
temp=temp+(*(sample+num*3+i))**(wim+i*3*T+j*T+ttime+1);
}
temp=temp-*(thm+j*T+ttime+1);
*(Y2t+num*3+j)=Sfun(temp);
}//end
//计算输出层节点的输出
temp=0;
for(j=0;j<3;j++)
{
temp=temp+(*(Y2t+num*3+j))*(*(wmo+j*T+ttime+1));
}
temp=temp-*(tho+ttime+1);
*(Y3t+num)=Sfun(temp);
//end
}
temp=0;
for(num=0;num<N;num++)
temp=temp+(*(teinfo+num) - (*(Y3t+num))) * (*(teinfo+num)-(*(Y3t+num)));
E[ttime+1]=temp/(2*N);
E[ttime+1]=sqrt(E[ttime+1]);
delete Y2t;
delete Y3t;
delete Y2;
}
void bp_error(double *sample,double *teinfo,int N,double *wim, double *wmo, double *thm,double *tho,double *Y3)
{
//计算误差函数的值
int i,j;
if(E[ttime+1] > E[ttime])
{
for(i=0;i<3;i++)
for(j=0;j<3;j++)
*(wim+i*3*T+j*T+ttime+1)=*(wim+i*3*T+j*T+ttime);
for(j=0;j<3;j++)
{
*(wmo+j*T+ttime+1)=*(wmo+j*T+ttime);
*(thm+j*T+ttime+1)=*(thm+j*T+ttime);
}
*(tho+ttime+1)=*(tho+ttime);
}
printf("\n训练样本集的第%d次学习的函数误差为:%f\n",ttime,E[ttime]);
//end
//判断误差
if(E[ttime]<0.0001 || ttime==T-1)
{
for(i=0;i<3;i++)
for(j=0;j<3;j++)
wimnew[i][j]=*(wim+i*3*T+j*T+ttime+1);
for(j=0;j<3;j++)
{
wmonew[j]=*(wmo+j*T+ttime+1);
thmnew[j]=*(thm+j*T+ttime+1);
}
thonew=*(tho+ttime+1);
}
else
{
ttime++;
bp_study(sample,teinfo,N,wim,wmo,thm,tho,Y3);
bp_error(sample,teinfo,N,wim,wmo,thm,tho,Y3);
}
}
void bp_test(char *filename,int N,double *sample, double *teinfo)
{
//计算测试样本数据,检验程序的可行性
double temp;
double *Y2t=new double[N*3];
double *Y3t=new double[N];
int num,i,j;
for(num=0;num<N;num++)
{
// 计算隐层各节点的输出值
for(j=0;j<3;j++)
{
temp=0;
for(i=0;i<3;i++)
{
temp=temp+(*(sample+num*3+i))*wimnew[j][i];
}
temp=temp-thmnew[j];
*(Y2t+num*3+j)=Sfun(temp);
}//end
//计算输出层节点的输出
temp=0;
for(j=0;j<3;j++)
{
temp=temp+(*(Y2t+num*3+j))*wmonew[j];
}
temp=temp-thonew;
*(Y3t+num)=Sfun(temp);
//end
}
//计算误差函数的值
double Et;
temp=0;
for(num=0;num<N;num++)
temp=temp+(*(teinfo+num)-(*(Y3t+num)))*(*(teinfo+num)-(*(Y3t+num)));
Et=temp/(2*N);
Et=sqrt(Et);
printf("\n测试样本集的函数误差为:%f\n",Et);
printf("\n颜色的识别率为:%f%%\n",(1-Et)*100);
delete Y2t;
delete Y3t;
}
void main()
{
int N;
double *wim = new double[3*3*T];
double *wmo = new double[3*T]; //定义的两层的网络权值
double *thm = new double[3*T];
double *tho = new double[T]; //定义的2层的阈值
srand(time(NULL));
printf("现在进行颜色文件中的颜色的学习:");
getchar();
N=samplenum("颜色.txt");
double *sample = new double[N*3];
double *teinfo = new double[N]; //定义的输入信号和教师信号
double *Y3 = new double[N]; //定义个层节点的输出
randyz(wim,wmo,thm,tho); // 产生随机数
//读文件里面的信息
fileopen(sample,teinfo,N,"颜色.txt");
//进行学习
bp_study(sample,teinfo,N,wim,wmo,thm,tho,Y3);
//判断误差
bp_error(sample,teinfo,N,wim,wmo,thm,tho,Y3);
//进行测试
bp_test("颜色.txt",N,sample,teinfo);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -