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

📄 bp网络识别.c

📁 本程序的功能是做BP网络识别
💻 C
字号:

//
//bp网络识别
//
//训练集4,输入单元46(有阈值-1),输出单元4,隐层1,隐单元10
//学习率0.05,允许误差上限0.005,最大迭代次数5000
//
//"训练.txt"存放图2.1训练集合
//"识别1.txt"存放图2.2识别集合
//"识别2.txt"存放图2.3识别集合
//"识别3.txt"存放图2.4识别集合
//"result.txt"存放输出结果。
#include "stdio.h"
#include "math.h"


#define TRAINNUM 4          //训练集总数
#define INPUTNUM 46          //输入层单元个数
#define OUTPUTNUM 4         //输出层单元个数
#define MASKNUM 10           //隐层单元个数
#define BETA 1              //Segmiod函数中的参数Beta
#define ETA  0.05            //学习率
#define VAREPSILON 0.005   //误差控制
#define TIMES 50000          //迭代次数控制

double E;                                          //误差
int    Cycletimes;                                 //迭代次数
int    Input[TRAINNUM+1][INPUTNUM+1];              //输入向量
int    Expectation[TRAINNUM+1][OUTPUTNUM+1];       //期望输出向量
double Output[TRAINNUM+1][OUTPUTNUM+1];            //实际输出向量
double reOutput[TRAINNUM+1][OUTPUTNUM+1];          //实际输出向量
double innerProduct[TRAINNUM+1][TRAINNUM+1];       //内积
double w_in[MASKNUM+1][INPUTNUM+1];                //输入层和隐层之间的权值
double w_out[OUTPUTNUM+1][MASKNUM+1];              //输出层和隐层之间的权值
FILE   *out,*in;

/********************读取训练集********************/
void ReadData()
{
	int j,n,m;

	for(j=1;j<=TRAINNUM;j++)
	{
		for(n=1;n<=INPUTNUM;n++)
			fscanf(in,"%d",&Input[j][n]);//输入向量
		for(m=1;m<=OUTPUTNUM;m++)
			fscanf(in,"%d",&Expectation[j][m]);//期望输出向量
	}
}
/********************输出结果********************/
void WriteData()
{
	int j,m;
	for(j=1;j<=TRAINNUM;j++)
	{
		for(m=1;m<=OUTPUTNUM;m++)
		{
			fprintf(out,"%f\t",reOutput[j][m]);
		}
		fprintf(out," +||+ ");
		for(m=1;m<=TRAINNUM;m++)//与已知第i组
		{
			fprintf(out,"%f\t",innerProduct[j][m]);
		}
		fprintf(out,"\n");
	}
	fprintf(out,"/////////////////////////////////////\n");
}
/********************随机赋初始权值********************/
void PrimalWeight()
{
	int i,j;
	double RandomSgn;

	srand((unsigned)time(NULL));
	//输出层和隐层之间的权值
	for(i=1;i<=OUTPUTNUM;i++)
	{
		for(j=1;j<=MASKNUM;j++)
		{
			RandomSgn=fmod((double)rand(),2.0);
			if(RandomSgn<0.001)
				w_out[i][j]=(-1)*((rand()%9000)+1000)/100000.0*5;
			else
				w_out[i][j]=((rand()%9000)+1000)/100000.0*5;	
		}
	}
	//输入层和隐层之间的权值
	for(i=1;i<=MASKNUM;i++)
	{
		for(j=1;j<=INPUTNUM;j++)
		{
			RandomSgn=fmod((double)rand(),2.0);
			if(RandomSgn<0.001)
				w_in[i][j]=(-1)*((rand()%9000)+1000)/100000.0*5;
			else
				w_in[i][j]=((rand()%9000)+1000)/100000.0*5;	
		}
	}
}
/********************Segmoid型函数********************/
double Segmoid(double x)
{
	double y;

	x=x*BETA;
	y=(exp(x)-exp(-x))/(exp(x)+exp(-x));
	return(y);

}
/********************Segmoid型函数的导函数********************/
double DerivativeSeg(double x)
{
	double y;

	y=BETA*(1-Segmoid(x)*Segmoid(x));
	return(y);
}
/********************训练并修改权值********************/
void Training()
{
	int p,n,m,j;
	double sum;       //辅助量(E)
	double ssum[TRAINNUM+1];
	double tao[TRAINNUM+1][MASKNUM+1];          //隐层输出
	double H[TRAINNUM+1][OUTPUTNUM+1];//辅助量(w_out[][]*tao[]相加)
	double h[TRAINNUM+1][MASKNUM+1];//辅助量(w_in[][]*Input[]相加)
	
	E=0.0;//误差赋初值
	//////////计算实际输出向量//////////
	for(j=1;j<=TRAINNUM;j++)//训练集//
	{
		sum=0.0;
		for(m=1;m<=OUTPUTNUM;m++)//输出层单元//
		{
			H[j][m]=0.0;
			for(p=1;p<=MASKNUM;p++)//隐层单元//
			{
				h[j][p]=0.0;
				for(n=1;n<=INPUTNUM;n++)//输入层单元//
				{
					h[j][p]=h[j][p]+w_in[p][n]*Input[j][n];
				}
				tao[j][p]=Segmoid(h[j][p]);//活化函数作用,计算出隐层输出
				H[j][m]=H[j][m]+w_out[m][p]*tao[j][p];
			}
			Output[j][m]=Segmoid(H[j][m]);//活化函数作用,计算出实际输出
			sum=sum+(Output[j][m]-Expectation[j][m])*(Output[j][m]-Expectation[j][m]);
		}

		//////////计算误差//////////
		E=E+sum;
	}
	E=E/2.0;
	//////////误差后向传播//////////
	//////////修改输出层和隐层之间的权值//////////
	for(m=1;m<=OUTPUTNUM;m++)//输出层单元//
	{
		for(p=1;p<=MASKNUM;p++)//隐层单元//
		{
			sum=0.0;
			for(j=1;j<=TRAINNUM;j++)//训练集//
			{
				sum=sum+(Expectation[j][m]-Output[j][m])*DerivativeSeg(H[j][m])*tao[j][p];
			}
			w_out[m][p]=w_out[m][p]+ETA*sum;
		}
	}
	//////////修改输入层和隐层之间的权值//////////
	for(p=1;p<=MASKNUM;p++)//隐层单元//
	{
		for(n=1;n<=INPUTNUM;n++)//输入层单元//
		{
			sum=0.0;
			for(j=1;j<=TRAINNUM;j++)//训练集//
			{
				ssum[j]=0.0;
				for(m=1;m<=OUTPUTNUM;m++)//输出层单元//
				{
					ssum[j]=ssum[j]+(Expectation[j][m]-Output[j][m])*DerivativeSeg(H[j][m])*w_out[m][p];
				}
				sum=sum+DerivativeSeg(h[j][p])*ssum[j]*Input[j][n];
			}
			w_in[p][n]=w_in[p][n]+ETA*sum;
		}
	}
}
/********************识别函数********************/
void Recognise()
{
	int p,n,m,j,i,k;
	double sum;       //辅助量(E)
	double tao[TRAINNUM+1][MASKNUM+1];          //隐层输出
	double H[TRAINNUM+1][OUTPUTNUM+1];//辅助量(w_out[][]*tao[]相加)
	double h[TRAINNUM+1][MASKNUM+1];//辅助量(w_in[][]*Input[]相加)
	
	E=0.0;//误差赋初值
	//////////计算实际输出向量//////////
	for(j=1;j<=TRAINNUM;j++)//训练集//
	{
		sum=0.0;
		for(m=1;m<=OUTPUTNUM;m++)//输出层单元//
		{
			H[j][m]=0.0;
			for(p=1;p<=MASKNUM;p++)//隐层单元//
			{
				h[j][p]=0.0;
				for(n=1;n<=INPUTNUM;n++)//输入层单元//
				{
					h[j][p]=h[j][p]+w_in[p][n]*Input[j][n];
				}
				tao[j][p]=Segmoid(h[j][p]);//活化函数作用,计算出隐层输出
				H[j][m]=H[j][m]+w_out[m][p]*tao[j][p];
			}
			reOutput[j][m]=Segmoid(H[j][m]);//活化函数作用,计算出实际输出
			sum=sum+(reOutput[j][m]-Output[j][m])*(reOutput[j][m]-Output[j][m]);
		}

		//////////计算误差//////////
		E=E+sum;
	}
	E=E/2.0;
	//////////计算内积//////////
	for(k=1;k<=TRAINNUM;k++)//第k组
	{
		for(i=1;i<=TRAINNUM;i++)//与已知第i组
		{
			innerProduct[k][i]=0.0;
			for(j=1;j<=OUTPUTNUM;j++)//第j个分量
			{
				innerProduct[k][i]+=(reOutput[k][j]-Output[i][j])*(reOutput[k][j]-Output[i][j]);
			}
		}
	}
}
/********************主函数********************/
main()
{
	int j,m;
	int tag;

	tag=1;//训练中止标识
	Cycletimes=0;
	in=fopen("训练.txt","r");
	ReadData();      //从训练.txt中读取训练集
	fclose(in);
	PrimalWeight();  //随机赋初始权值 
	while(tag)
	{
		Cycletimes++;//迭代次数加1
		Training();      //一次训练(修改权值和计算误差)
		printf("%d            ",Cycletimes);
		printf("%f\n",E);//跟踪每次迭代误差E
		if((Cycletimes>TIMES)||(E<VAREPSILON))//结束条件
			tag=0;
	}
	out=fopen("result.txt","a+");
	if((Cycletimes==(TIMES+1))&&(E>VAREPSILON))
	{
		fprintf(out,"失败!!!!!!!!\n");
		fprintf(out,"Don't give up,come on!~ :)\n");
	}
	else{
	fprintf(out,"Success!!!!!!!!\n");
	fprintf(out,"You did a good job!~ :)\n");
	fprintf(out,"迭代次数:%d\n",Cycletimes);
	fprintf(out,"误    差:%f\n",E);
	fprintf(out,"训练期望输出:\n");
	for(j=1;j<=TRAINNUM;j++)
	{
		for(m=1;m<=OUTPUTNUM;m++)
		{
			fprintf(out,"%d\t",Expectation[j][m]);
		}
		fprintf(out,"\n");
	}
	fprintf(out,"训练实际输出:\n");
	for(j=1;j<=TRAINNUM;j++)
	{
		for(m=1;m<=OUTPUTNUM;m++)
		{
			fprintf(out,"%f\t",Output[j][m]);
		}
		fprintf(out,"\n");
	}
	}
	fprintf(out,"/////////////////////////////////////\n");
	{
		in=fopen("识别1(污染2个点).txt","r");
		ReadData();      //从识别1.txt中读取识别集
		fclose(in);
		Recognise();
		fprintf(out,"识别1与训练实际输出之间的误差为:%f\n",E);
		fprintf(out,"识别1实际输出:\n");
		WriteData();//输出结果到result.txt
	}
	{
		in=fopen("识别2(污染5个点).txt","r");
		ReadData();      //从识别1.txt中读取识别集
		fclose(in);
		Recognise();
		fprintf(out,"识别2与训练实际输出之间的误差为:%f\n",E);
		fprintf(out,"识别2实际输出:\n");
		WriteData();//输出结果到result.txt
	}
	{
		in=fopen("识别3(污染9个点).txt","r");
		ReadData();      //从识别1.txt中读取识别集
		fclose(in);
		Recognise();
		fprintf(out,"识别3与训练实际输出之间的误差为:%f\n",E);
		fprintf(out,"识别3实际输出:\n");
		WriteData();//输出结果到result.txt
	}
	fprintf(out,"////////////////////////////////////////////////////////////\n");
	fclose(out);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -