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

📄 wnn_bp.cpp

📁 用DSP实现的小波神经网络进行图象识别编程,希望对大家有用!
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/************************************
* 采用参考文献中方法进行验证
* 小波神经网络的参数初始化研究 
* 驺春华 陈统坚 叶邦彦 彭永红
* 华南理工大学学报(自然科学版) 第3卷第2期 2003年2月
* 4月10日版的 对a、b不进行反传学习过程
*************************************/
/************************************
* 系统采用的模型为
* 输入层:在输入节点的基础上多加了一个偏置,
* 向隐层求和后经由高斯小波函数求得输出
* 输出层多加了一个偏置,再经由加权求和后经由
* sigmoid函数(或线性函数)获得输出。
* 再通过误差反传调整输出和隐层、隐层和输入之间的权值沿着梯度下降的方向
* 这个版本没有让偏移和缩放尺度加入调整
*************************************/
#include <iostream.h>
#include <iomanip.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <fstream.h>
#include <time.h>
//#define RAND_MAX 65535
#define PI 3.14159267  //pi的近似值
#define ep_min 0.0000001  //本程序中使用的最小数

int sampnum;       //样本数
int IN;            //输入层节点数   
int HN;            //初始隐含层节点数
int ON;            //输出层节点数
double alpha;      //学习因子
double beta;       //动量因子
int iternum;       //最大循环次数
double ep;         //最大误差

double *P;         //单个样本输入数据,初始为P[IN][sampnum]
double *T;         //单个样本教师数据,为T[ON][sampnum]
double *W;         //输入层至隐层的连接权值,为W[HN][IN+1],加入了一个偏置
double *V;         //隐层到输出层的连接权值,为V[ON][HN+1]
double *X;         //X[HN]----隐层的输入
double *H;         //H[HN]----隐层的输出
double *O;         //O[ON]----输出层的输出,在输出层采用的是线性函数叠加

double *tempW;     //为了进行权值的改进,加入一个修正量
double *tempV;     //为了进行权值的改进,加入一个修正量
double *a;         //小波函数的尺度值,大小为a[HN]
double *b;         //小波函数的偏移量,大小为b[HN]

double *err_m;     //err_m[sampnum]----第m个样本的总误差
double *d_err;     //d_err[ON]---输出层至隐层的误差传递
double *e_err;     //e_err[HN]---隐层至输入层的误差传递
//double *a_err;     //a_err[HN]---隐层至输入层的误差a传递
//double *b_err;     //b_err[HN]---隐层至输入层的误差b传递

void Display(int *choice);
void InputData(void);
void MemAlloc(void);
void FreeAlloc(void);
void RandInitialize(int seed);
double RandomNum(int a,int b);
double Func(double x);
double DFunc(double x);
double GaussFunc(double x);
double DGaussFunc(double x);
void ReadSample(void);
void Init_WNN(void);
void FeedForward(int samp);
void Err_O_H(int samp);
void Err_H_I(void);
void Update_O_H(void);
void Update_H_I(int samp);
double Err_sum(void);
void SaveParameter(void);
void ReadParameter(void);
void TestForward(double *test);

void main(void)
{	
	int i;
	int choice;
	int iter; //循环次数
	int m;  //当前样本
	double total_error;

	time_t start,ahead,stop;

	start = clock();
	stop = clock();
	ahead = stop - start;

	ofstream outfile("error2.txt");

	Display(&choice);
	if(choice==1)
	{
	   //InputData();    //输入数据
	   ifstream runfile("runfile.txt");
	   runfile>>sampnum>>IN>>HN>>ON>>alpha>>beta>>iternum>>ep;
	   runfile.close();
	   MemAlloc();     //分配空间
	   ReadSample();   //读入样本和目标值

	   start = clock();
	   time_t t; 
	   RandInitialize((unsigned)time(&t));
	   Init_WNN(); //初始化权值和阈值
	   for(iter=1;iter<iternum;iter++)
	   {
		   if(iter%100==0)
			   cout<<"Current Iteration = "<<iter<<'\n';
		   for(m=0;m<sampnum;m++)
		   {
			   FeedForward(m);
			   Err_O_H(m);
			   Err_H_I();
			   Update_O_H();
			   Update_H_I(m);
		   }
		   total_error=Err_sum();
           total_error/=sampnum;
		   outfile<<total_error<<'\n';
		   if(total_error<ep)
		   {
			   cout<<"Actual Trainning number="<<iter<<'\n';
		       break;
		   }
	   }
	   outfile.close();
	   cout<<"误差为: "<<total_error<<'\n';
	   SaveParameter(); 

	   stop = clock();
	   cout<<"耗费时间为:\n";
	   cout<<stop - start - ahead<<'\n';
	   cout<<"神经网络训练完毕!\n";
	   cout<<"输入2进行网络测试!\n";
	   cin>>choice;
	}
	if(choice==2)
	{
		int testnum;
		double *Stest;      //用于测试样本测试
		cout<<"请输入测试样本个数:\n";
		cin>>testnum;

		ReadParameter();
	
		ifstream test("test.txt");
		ofstream result("result.txt");
		if(!test)
		{
			cout<<"不能打开输入文件!\n";
			exit(1);
		}
        
		Stest=new double[IN];
		m=0;//当前测试样本
	    do
		{
            for(i=0;i<IN;i++)
			{
			    test>>Stest[i];
			}
			//前向测试
			TestForward(Stest);
		    for(i=0;i<ON;i++)
			{
			    result<<O[i]<<'\t';
			}
		    result<<'\n';
		    m++;
		}while(m<testnum);

		delete Stest;
		Stest=NULL;
		test.close();
		result.close();
	}
	FreeAlloc();

}

/*********************************
* 初始选择界面输出
***********************************/
void Display(int *choice)
{
	cout<<"这是一个三层神经网络训练与测试程序:\n";
	cout<<"请先进行训练再进行测试!\n";
	cout<<"有两个选项:\n";
	cout<<"1---神经网络训练\n";
	cout<<"2---神经网络测试\n";
	cout<<"请选择:\n";
	cin>>*choice;
}

/*********************************
* 各个初始量的输入
**********************************/
void InputData(void)
{
	do{
	     cout<<"请输入训练样本数:\n";
	     cin>>sampnum;
	}while(sampnum<=0);

	do
	{
		cout<<"请输入输入层节点数:\n";
		cin>>IN;
	}while(IN<=0);

	do
	{
		cout<<"请输入隐层节点数:\n";
		cin>>HN;
	}while(HN<=0);

	do
	{
		cout<<"请输入输出层节点数:\n";
		cin>>ON;
	}while(ON<=0);

	do
	{
	    cout<<"请输入学习速率(alpha):\n";
	    cin>>alpha;
	}while(alpha<=0||alpha>=1);

	do
	{
	    cout<<"请输入平滑因子(beta):\n";
	    cin>>beta;
	}while(beta<=0||beta>=1);

	do
	{
	cout<<"请输入最大循环次数:\n";
	cin>>iternum;
	}while(iternum<0||iternum>100000);

	do
	{
	    cout<<"请输入目标误差(0.01--0.00001):\n";
	    cin>>ep;
	}while(ep<0.00001||ep>0.01);
}

/*********************************
* 分配内存
*********************************/
void MemAlloc(void)
{
	//P[IN][sampnum]---单个样本输入数据
	P=new double[IN*sampnum];
	if(P==NULL)
	{
		cout<<"P内存分配失败!\n";
		exit(1);
	}
	memset(P,0,sizeof(double)*IN*sampnum);

	//T[ON][sampnum]---单个样本教师数据
	T=new double[ON*sampnum];
	if(T==NULL)
	{
		cout<<"T内存分配失败!\n";
		exit(1);
	}
	memset(T,0,sizeof(double)*ON*sampnum);

	//W[HN][IN+1]---输入层至隐层权值
	W=new double[(IN+1)*HN];
	if(W==NULL)
	{
		cout<<"W内存分配失败!\n";
		exit(1);
	}
	memset(W,0,sizeof(double)*(IN+1)*HN);

	//tempW[HN][IN+1]---加入的修正量
    tempW=new double[(IN+1)*HN];
	if(tempW==NULL)
	{
		cout<<"tempW内存分配失败!\n";
		exit(1);
	}
	memset(tempW,0,sizeof(double)*(IN+1)*HN);

	//V[ON][HN+1]---隐层至输出层权值
	V=new double[(HN+1)*ON];
	if(V==NULL)
	{
		cout<<"V内存分配失败!\n";
		exit(1);
	}
	memset(V,0,sizeof(double)*(HN+1)*ON);

	//tempV[ON][HN+1]---加入的修正量
    tempV=new double[(HN+1)*ON];
	if(tempV==NULL)
	{
		cout<<"tempV内存分配失败!\n";
		exit(1);
	}
	memset(tempV,0,sizeof(double)*(HN+1)*ON);

	//X[HN]----隐层的输入
	X=new double[HN];
	if(X==NULL)
	{
		cout<<"X内存分配失败!\n";
		exit(1);
	}
	memset(X,0,sizeof(double)*HN);

	//H[HN]---隐层的输出
	H=new double[HN];
	if(H==NULL)
	{
		cout<<"H内存分配失败!\n";
		exit(1);
	}
	memset(H,0,sizeof(double)*HN);

	//O[ON]---输出层的输出,在输出层采用的是线性函数叠加
	O=new double[ON];
	if(O==NULL)
	{
		cout<<"O内存分配失败!\n";
		exit(1);
	}
	memset(O,0,sizeof(double)*ON);
    
	//a[HN]---隐层的偏移量
	a=new double[HN];
	if(a==NULL)
	{
		cout<<"a内存分配失败!\n";
		exit(1);
	}
    memset(a,0,sizeof(double)*HN);
	
	//b[HN]---隐层的缩放尺度
	b=new double[HN];
	if(b==NULL)
	{
		cout<<"b内存分配失败!\n";
		exit(1);
	}
	memset(b,0,sizeof(double)*HN);
        
	//err_m[sampnum]----第m个样本的总误差
	err_m=new double[sampnum];
	if(err_m==NULL)
	{
		cout<<"err_m内存分配失败!\n";
		exit(1);
	}
	memset(err_m,0,sizeof(double)*sampnum);

	//d_err[ON]---输出层至隐层的误差传递
	d_err=new double[ON];
	if(d_err==NULL)
	{
		cout<<"d_err内存分配失败!\n";
		exit(1);
	}
    memset(d_err,0,sizeof(double)*ON);

	//e_err[HN]---隐层至输入层的误差传递
	e_err=new double[HN];
	if(e_err==NULL)
	{
		cout<<"e_err内存分配失败!\n";
		exit(1);
	}
	memset(e_err,0,sizeof(double)*HN);
}

/*************************************
* 释放空间
**************************************/
void FreeAlloc(void)
{
	delete []P;           P=NULL;
	delete []T;           T=NULL;
	delete []W;           W=NULL;
	delete []tempW;       tempW=NULL;
	delete []tempV;       tempV=NULL;
	delete []V;           V=NULL;
	delete []X;           X=NULL;
	delete []H;           H=NULL;
	delete []O;           O=NULL;
	delete []a;           a=NULL;
	delete []b;           b=NULL;
	delete []err_m;   err_m=NULL;
	delete []d_err;   d_err=NULL;
	delete []e_err;   e_err=NULL;
}

/********************************
* 产生随机数种子
*********************************/
void RandInitialize(int seed)
{
	srand(seed);
}
/*********************************
* 产生一个位于(a,b)的随机数
*********************************/
double RandomNum(int a,int b)
{
	double result;
	result=(b-a)*(double)rand()/(double)RAND_MAX+a;
	return result;
}

double Func(double x)
{
	double result;
	result=1/(1+exp(-x));
	return result;
}

⌨️ 快捷键说明

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