⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpcolor.cpp

📁 用VC6.0写的一个BP网络程序
💻 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 + -