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

📄 wnn_bp.cpp

📁 用DSP实现的小波神经网络进行图象识别编程,希望对大家有用!
💻 CPP
📖 第 1 页 / 共 2 页
字号:

double DFunc(double x)
{
	double result;
	result=x*(1-x);
	return result;
}
/**********************************
* 选择高斯的一阶导数作为小波母函数
* 即 y=x*exp(-0.5*x^2)
**********************************/
double GaussFunc(double x)
{
	double result;
	result=x*exp(-0.5*x*x);
	return result;
}

/*********************************
* 返回高斯二阶导数的值
* 即 y=(1-x^2)*exp(-0.5*x^2)
*********************************/
double DGaussFunc(double x)
{
	double result;
	result=(1-x*x)*exp(-0.5*x*x);
	return result;
}

/***********************************************
* 将样本中的所有数据、以及目标向量读入输入数据中
************************************************/
void ReadSample(void)
{
	int i;
	int samp;
	ifstream infile("sample.txt");
	samp=0;
	while(samp<sampnum)
	{
	    for(i=0;i<IN;i++)
		{
			infile>>P[i*sampnum+samp];
		}
		for(i=0;i<ON;i++)
		{
			infile>>T[i*sampnum+samp];
		}
		samp++;
	}

}
/***********************************************
* 用参考文献提供的方法初始化输入层至隐层的权值
* 以及初始化平移和缩放尺度
* 将隐层和输出层之间的权值随机初始化为 [-1 1]的值
*************************************************/
void Init_WNN(void)
{
	/************************************************
	* 先把输入层和隐层之间的权值随机初始化在[-1,1]之间
	*************************************************/
    int i;
	int j;
	double square;

	double C=2.0*pow(HN,(double)1/IN); //根据文献设置的参考值

	for(i=0;i<HN;i++)
	{
        square=0;
		for(j=0;j<IN+1;j++)
		{
			W[i*(IN+1)+j]=RandomNum(-1,1);
			square+=W[i*(IN+1)+j]*W[i*(IN+1)+j];
		}
		//按行进行归一
		square=C/sqrt(square);
		for(j=0;j<IN+1;j++)
		{
			W[i*(IN+1)+j]*=square;
		}
	}
	
	//测试权值第一次初始化的值
	/*
	ofstream offile("weight.txt");
	for(i=0;i<HN;i++)
	{
		for(j=0;j<IN+1;j++)
		{
			offile<<W[i*(IN+1)+j]<<'\n';
		}
	}
	offile.close();
    */
	//和样本中的最大和最小值发生关系
	double min;
	double max;
	double temp;
	double d;
	int k;
	for(i=0;i<IN;i++)
	{
		max=0;
		min=10000;
		//返回第i个神经元输入样本中的最大和最小值
		for(j=0;j<sampnum;j++)
		{
			temp=P[i*sampnum+j];
			if(temp>max)
				max=temp;
			if(temp<min)
				min=temp;
		}
        d=2/(max-min+ep_min);
        for(k=0;k<HN;k++)
		{
			W[k*(IN+1)+i]*=d;
		}
	}

	ofstream offile("weight.txt");
	for(i=0;i<HN;i++)
	{
		for(j=0;j<IN+1;j++)
		{
			offile<<W[i*(IN+1)+j]<<'\n';
		}
	}
	offile.close();

    //开始a,b的初始化

	//memset(a,0,HN*sizeof(double));
	//memset(b,0,HN*sizeof(double));
    // float center=0;       //高斯小波的时域中心     
    //float radius=1.2247;  //高斯小波的半径
	double coeff=1/(2*1.2247);


    for(j=0;j<IN;j++)
	{
		max=0;
		min=1000;
		for(k=0;k<sampnum;k++)
		{
			//寻找第i个输入节点样本中的最大和最小值
			if(P[j*sampnum+k]>max)
				max=P[j*sampnum+k];
			if(P[j*sampnum+k]<min)
				min=P[j*sampnum+k];
		}
		for(i=0;i<HN;i++)
		{
			a[i]+=W[i*(IN+1)+j]*(max-min)*coeff;
			b[i]+=W[i*(IN+1)+j]*(max+min)*0.5;
		}
	}
	//平移和缩放尺度初始化完毕
	//初始化隐层至输出层的权值
	//加入了偏置的
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN+1;j++)
		{
			V[i*(HN+1)+j]=RandomNum(-1,1);
		}
	}
}

/***************************
* 第samp样本的网络前向传递过程
****************************/
void FeedForward(int samp)
{
	int i;
	int j;
	double t;
	double sum;
	//the layer input-hidden layer
	for(i=0;i<HN;i++)
	{
		sum=W[i*(IN+1)+IN]; //the weight of bias
		for(j=0;j<IN;j++)
		{
			sum+=P[j*sampnum+samp]*W[i*(IN+1)+j];
		}
		X[i]=sum; //隐层的输入
		t=(sum-a[i])/b[i]; 
		H[i]=GaussFunc(t); //隐层的输出
	}
	//the layer hidden-output layer
	for(i=0;i<ON;i++)
	{
		sum=V[i*(HN+1)+HN];
		for(j=0;j<HN;j++)
		{
			sum+=H[j]*V[i*(HN+1)+j];
		}
		//输出层采用了sigmoid函数
		//O[i]=Func(sum); //采用sigmoid函数
		//输出层采用线性叠加
		O[i]=sum;
	}
}

/*****************************************        
*输出层至隐层的一般化误差子程序
*第samp个样本输入时,存储输出端的总标准误差
******************************************/
void Err_O_H(int samp)
{
	double ep;
	double e;
	int i;
	ep=0.0;
	e=0.0; 
	//求输出端的总误差
	for(i=0;i<ON;i++)
	{
		ep=T[i*sampnum+samp]-O[i];
        //输出层采用了sigmoid函数
		//d_err[i]=DFunc(O[i])*ep; //有函数的导数部分
		//输出层采用了线性叠加
		d_err[i]=ep;
		ep=0.5*ep*ep;
		e+=ep;
	}
	err_m[samp]=e;
}

/****************************************
*隐层至输入层的一般化误差子程序
*****************************************/
void Err_H_I(void)
{
	int i;
	int j;
	double sum;
	double t;
	for(i=0;i<HN;i++)
	{
		sum=0.0;
		//输出层向隐层误差反传求和
		for(j=0;j<ON;j++)
		{
			sum+=d_err[j]*V[j*(HN+1)+i];
		}
		t=(X[i]-a[i])/b[i];
		e_err[i]=sum*DGaussFunc(t)/b[i];
	}
}

/*************************************************
* 输出层至隐层的权值调整、输出层阈值调整计算子程序
*************************************************/
void Update_O_H(void)
{
	int i;
	int j;
	double dw;
	for(i=0;i<ON;i++)
	{
		dw=alpha*d_err[i]+beta*tempV[i*(HN+1)+HN];
		V[i*(HN+1)+HN]+=dw;
        tempV[i*(HN+1)+HN]=dw;
		for(j=0;j<HN;j++)
		{
			dw=alpha*d_err[i]*H[j]+beta*tempV[i*(HN+1)+j];
			V[i*(HN+1)+j]+=dw;
			tempV[i*(HN+1)+j]=dw;
		}
	}
}

void Update_H_I(int samp)
{
	int i;
	int j;
	double dw;
	for(i=0;i<HN;i++)
	{
		dw=alpha*e_err[i]+beta*tempW[i*(IN+1)+IN];
		W[i*(IN+1)+IN]+=dw;
		tempW[i*(IN+1)+IN]=dw;
		for (j=0;j<IN;j++)
		{
			dw=alpha*e_err[i]*P[j*sampnum+samp]+beta*tempW[i*(IN+1)+j];
			W[i*(IN+1)+j]+=dw;
			tempW[i*(IN+1)+j]=dw;
		}
	}
}

double Err_sum(void)
{
	//N个样本的全局误差计算子程序
	int i;
	double sum;
	sum=0.0;
	for(i=0;i<sampnum;i++)
	{
		sum+=err_m[i];
	}
	return sum;
}

void SaveParameter(void)
{
	int i;
	int j;
	ofstream outfile("OutParameter.txt");

	if(!outfile)
	{
		cout<<"不能打开目的地文件!\n";
		exit(1);
	}

	outfile<<IN<<'\n';
	outfile<<HN<<'\n';
	outfile<<ON<<'\n';
    outfile<<'\n';
	//output the weight of Hidden-Input layer
	for(i=0;i<HN;i++)
	{
		for(j=0;j<IN+1;j++)
		{
			outfile<<W[i*(IN+1)+j]<<'\n';
		}
	}

	outfile<<'\n';
    //output the translation and dilation of Hidden layer 
	for(i=0;i<HN;i++)
	{
		outfile<<a[i]<<'\t'<<b[i]<<'\n';
	}
 
	outfile<<'\n';
	//output the weight of Output-Hidden layer
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN+1;j++)
		{
			outfile<<V[i*(HN+1)+j]<<'\n';
		}
	}

	outfile.close();
}

void ReadParameter(void)
{
	int i;
	int j;
	ifstream infile("OutParameter.txt");

	if(!infile)
	{
		cout<<"不能打开输入文件!\n";
		exit(1);
	}

	infile>>IN;
	infile>>HN;
	infile>>ON;
    
	//load the weight of Hidden-Input layer
	for(i=0;i<HN;i++)
	{
		for(j=0;j<(IN+1);j++)
		{
			infile>>W[i*(IN+1)+j];
		}
	}

	//load the translation and dilation of Hidden layer
	for(i=0;i<HN;i++)
	{
		infile>>a[i]>>b[i];
	}
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN+1;j++)
		{
			infile>>V[i*(HN+1)+j];
		}
	}

	infile.close();
}

void TestForward(double *test)
{
	int i;
	int j;
	double t;
	double sum;
	//the layer input-hidden layer
	for(i=0;i<HN;i++)
	{
		sum=W[i*(IN+1)+IN]; //the weight of bias
		for(j=0;j<IN;j++)
		{
			sum+=test[j]*W[i*(IN+1)+j];
		}
		X[i]=sum; //隐层的输入
		t=(sum-a[i])/b[i]; 
		H[i]=GaussFunc(t); //隐层的输出
	}
	//the layer hidden-output layer
	for(i=0;i<ON;i++)
	{
		sum=V[i*(HN+1)+HN];
		for(j=0;j<HN;j++)
		{
			sum+=H[j]*V[i*(HN+1)+j];
		}
		//采用了sigmoid函数
		//O[i]=Func(sum); //采用sigmoid函数
		O[i]=sum;
	}
}

⌨️ 快捷键说明

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