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

📄 firsttrain.cpp

📁 简单易懂的elaman离线学习程序
💻 CPP
字号:
// FirstTrain.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"

#define PI  3.14159265
#define NUM_SAM 518//学习样本数
#define NUM_YAN 300//校验样本数
#define MAX_EPOCH 10000//最大训练次数
#define INR 3//输入层神经元数目
#define HN 12//隐层神经元数目
#define CN 12//状态层神经元数目
#define ON 1//输出层神经元数目

const double stepQ=0.2f;//输入层到隐层的学习步长
const double stepH=0.2f;//隐层到输出层的学习步长
const double stepC=0.6f;//状态层到隐层的学习步长
const double alpha=0.28f;//动量项系数
const double beta=0.2f;//记忆系数

double SAM_P[NUM_SAM][INR];//训练样本
double SAM_T[NUM_SAM][ON];//训练样本

double YAN_P[NUM_YAN][INR];//校验样本
double YAN_T[NUM_YAN][ON];//校验样本

double out_I[INR];//输入层的的输出

double v_H[HN];//隐层的输出
double out_H[HN];//隐层的输出

double v_C[CN];//状态层的输出
double out_C[CN];//状态层的输出

double tem_C[CN];//暂态记忆过去的状态层

double v_O[ON];//输层出的输出
double out_O[ON];//输出层的输出

double YU_H[HN];//隐层的阈值
double det_YU_H[HN];//隐层的阈值变化量
double plus_YU_H[HN];//隐层的阈值冲量项

double YU_O[ON];//输出层的阈值
double det_YU_O[ON];//输出层的阈值变化量
double plus_YU_O[ON];//输出层的阈值冲量项

double w_H_I[HN][INR];//输入层到隐层的权值
double detw_H_I[HN][INR];//输入层到隐层的权值变化量
double plus_H_I[HN][INR];//输入层到隐层的权值冲量项

double w_H_C[HN][CN];//状态层到隐层的权值
double detw_H_C[HN][CN];//状态层到隐层的权值变化量
double plus_H_C[HN][CN];//状态层到隐层的权值冲量项

double w_O_H[ON][HN];//隐层到输出层的权值
double detw_O_H[ON][HN];//隐层到输出层的权值变化量
double plus_O_H[ON][HN];//隐层到输出层的权值冲量项

double det_H[HN];//隐层的局部梯度
double det_O[ON];//输出层的局部梯度

double Err;//网络学习的评价误差
double Pre_Err=0.001;//预定义的网络训练精度


int _tmain(int argc, _TCHAR* argv[])
{
	ofstream read_sample;//读每一个节拍训练样本
	ofstream weight;//每个节拍阈值前后变化以及网络信息
	ofstream err_epoch;//训练时的每次误差
	ofstream netvsact;//网络与实际输出之比较
	ofstream check_out;//校验样本经过网络的结果

	ifstream train_sample("1231.txt",ios::in);//训练样本
//	ifstream check_sample("jy01.txt",ios::in);//校验样本
//	ifstream init_weight("iniweight.txt",ios::in);//网络初始化权值

	int i=0,j=0,k=0;
	int st=0;//实际机器人需要运行的节拍
	const int ST=NUM_SAM;//实际机器人需要运行的最大节拍
	int timeS=0;//样本遍历一遍在线学习循环次数
	int ii=0;//一个节拍中整个训练样本学习次数
	double tem_err[ON],tem_err_LR;
	double sigma=0.0;

	read_sample.open("read_sample.txt");
	weight.open("weight.txt");
	err_epoch.open("err_epoch.txt");
	netvsact.open("netvsact.txt");
	check_out.open("check_out.txt");

	if((read_sample.fail())||(weight.fail())||(err_epoch.fail())
		||(netvsact.fail())||(check_out.fail()))
	{
		printf("Erorr_output!\n");
		exit(0);
	}

	if((train_sample.fail()))
	{
		printf("Erorr_input!\n");
		exit(0);
	}
	/////////////////////////////////////////////////////////////////////////////////////////////	
	//说明性文字
	weight<<"本程序为采用简化的BPTT算法离线学习的Elman网络:";
	weight<<"\n每个节拍离线训练样本个数:"<<NUM_SAM;
	weight<<"\n校验个数:"<<NUM_YAN;
	weight<<"\n每个节拍最大训练次数:"<<MAX_EPOCH;
	weight<<"\n输入层神经元个数:"<<INR;
	weight<<"\n隐层层神经元个数:"<<HN;
	weight<<"\n状态层神经元个数:"<<HN;
	weight<<"\n输出层神经元个数:"<<ON;
	weight<<"\n前后学习速率分别是:"<<stepQ<<"\t"<<stepH<<"\t"<<stepC;
	weight<<"\n冲量系数:"<<alpha;
	weight<<"\n记忆系数:"<<beta;
	weight<<"\n\n";

	read_sample<<setiosflags(ios::fixed);
	read_sample<<setprecision(12);//文件输出时精度
	
	for(i=0;i<NUM_SAM;i++)
	{
		read_sample<<setw(5)<<i;
		for(j=0;j<INR;j++)
		{
			train_sample>>SAM_P[i][j];
			read_sample<<setw(20)<<SAM_P[i][j];
		}
		for(k=0;k<ON;k++)
		{
			train_sample>>SAM_T[i][k];
			read_sample<<setw(20)<<SAM_T[i][k];
		}
		read_sample<<"\n";
	}
	printf("样本获取成功.\n");

	//在线学习的权值初始化,应以离线学习得到的网络的权值为初值
	srand( (unsigned)time( NULL ) );//播种
	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
/*	for(i=0;i<HN;i++)
	{
		for(j=0;j<INR;j++)
		{
			init_weight>>w_H_I[i][j];//输入到隐层的权值初始化
		}
	}
	for(i=0;i<HN;i++)
	{
		for(k=0;k<CN;k++)
		{
			init_weight>>w_H_C[i][k];//状态层到隐层的权值初始化
		}
	}
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN;j++)
		{
			init_weight>>w_O_H[i][j];//隐层到输出层的权值初始化
		}
	}
	for(i=0;i<HN;i++)
	{
		init_weight>>YU_H[i];//隐层阈值初始化
	}
	for(i=0;i<ON;i++)
	{
		init_weight>>YU_O[i];//输出层阈值初始化
	}
*/
	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	for(i=0;i<HN;i++)
	{
		for(j=0;j<INR;j++)
		{
			w_H_I[i][j] = (double)(rand()/32767.0)*0.5 - 0.25;//输入到隐层的权值初始化
		}
	}
	for(i=0;i<HN;i++)
	{
		for(k=0;k<CN;k++)
		{
			w_H_C[i][k] = (double)(rand()/32767.0)*0.5 - 0.25;//状态层到隐层的权值初始化
		}
	}
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN;j++)
		{
			w_O_H[i][j] = (double)(rand()/32767.0)*0.5 - 0.25;//隐层到输出层的权值初始化
		}
	}
	for(i=0;i<HN;i++)
	{
		YU_H[i] = (double)(rand()/32767.0)*0.5 - 0.25;//隐层阈值初始化
	}
	for(i=0;i<ON;i++)
	{
		YU_O[i] = (double)(rand()/32767.0)*0.5 - 0.25;//输出层阈值初始化
	}
	weight<<"调整前权值:\n";
	for(i=0;i<HN;i++)
	{
		for(j=0;j<INR;j++)
		{
			weight<<w_H_I[i][j]<<"\t";
			if(j==INR-1)weight<<"\n";
		}	
	}
	weight<<"\n";
	for(i=0;i<HN;i++)
	{
		for(j=0;j<CN;j++)
		{
			weight<<w_H_C[i][j]<<"\t";
			if(j==CN-1)weight<<"\n";
		}	
	}
	weight<<"\n";
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN;j++)
		{
			weight<<w_O_H[i][j]<<"\t";
			if(j==HN-1)weight<<"\n";
		}
	}	
	weight<<"\n调整前阈值:\n";
	for(i=0;i<HN;i++)
	{
		weight<<YU_H[i]<<"\t";
	}
	weight<<"\n\n";
	for(i=0;i<ON;i++)
	{
		weight<<YU_O[i]<<"\t";
	}
	weight<<"\n\n";
//	::MessageBox(NULL,"Start Training!","Train",MB_OK);
	//////////////////////////////////////////////////////////////////////////////
	//复合编程部分
	cout<<setiosflags(ios::fixed);
	cout<<setprecision(8);//屏幕显示精度
	cout<<setiosflags(ios::showpoint);

	//Offline Train*********************************************************************
	//误差值初始化
	Err=1+Pre_Err;
	while(Err>Pre_Err&&ii<MAX_EPOCH)
	{
		Err=0.0;
		//正向传播	
		for(timeS=0;timeS<NUM_SAM;timeS++)
		{	
			//输入样本
			for(i=0;i<INR;i++)
			{
				out_I[i]=SAM_P[timeS][i];
			}
			//状态层的记忆
			if(timeS==0)
			{
				for(i=0;i<CN;i++)
				{
					v_C[i]=0.0;
					out_C[i]=v_C[i];
					tem_C[i]=0.0;
				}		
			}
			else
			{
				for(i=0;i<CN;i++)
				{
					v_C[i]=out_H[i];
					out_C[i]=v_C[i];
					tem_C[i]=out_C[i];
				}
			}

			//隐层的输入输出
			for(i=0;i<HN;i++)
			{
				sigma=0.0;
				for(j=0;j<INR;j++)
				{
					sigma+=out_I[j]*w_H_I[i][j];//输入层的的输入
				}
				for(k=0;k<CN;k++)
				{
					sigma+=out_C[k]*w_H_C[i][k];//加入状态层的输入
				}
				sigma+=beta*tem_C[i];//加上暂态记忆的输入
				v_H[i]=sigma-YU_H[i];//加上阈值的输入
				out_H[i]=1.0/(1.0+exp(-v_H[i]));//隐层各神经元的的输出
			}		

			for(i=0;i<ON;i++)
			{	
				sigma=0.0;
				for(j=0;j<HN;j++)
				{
					sigma+=out_H[j]*w_O_H[i][j];//输出层的输入
				}
				v_O[i]=sigma-YU_O[i];//加上阈值的输入
				out_O[i]=v_O[i];//输出层的输出
			}

			tem_err_LR=0.0;//误差都是从零开始的
			for(i=0;i<ON;i++)
			{
				tem_err[i]=SAM_T[timeS][i]-out_O[i];
				tem_err_LR+=(tem_err[i])*(tem_err[i]);
			}
			tem_err_LR/=2;
			Err+=tem_err_LR;
			//计算局部误差
			for(i=0;i<ON;i++)
			{
				det_O[i]=tem_err[i];
			}	
			for(i=0;i<HN;i++)
			{
				sigma=0.0;
				for(j=0;j<ON;j++)
				{
					sigma+=det_O[j]*w_O_H[j][i];
				}
				det_H[i]=sigma*out_H[i]*(1.0-out_H[i]);
			}
			//调整输出层到隐层的变化权值		
			for(i=0;i<ON;i++)
			{
				for(j=0;j<HN;j++)
				{
					detw_O_H[i][j]=stepH*det_O[i]*out_H[j];
					w_O_H[i][j]+=(detw_O_H[i][j]+alpha*plus_O_H[i][j]);
					plus_O_H[i][j]=detw_O_H[i][j];
				}
				det_YU_O[i]=stepH*det_O[i]*(-1);//阈值的调整
				YU_O[i]+=(det_YU_O[i]+alpha*plus_YU_O[i]);
				plus_YU_O[i]=det_YU_O[i];
			}


			//调整隐层到输入层的变化权值		
			for(i=0;i<HN;i++)
			{
				for(j=0;j<INR;j++)
				{
					detw_H_I[i][j]=stepQ*det_H[i]*out_I[j];
					w_H_I[i][j]+=(detw_H_I[i][j]+alpha*plus_H_I[i][j]);
					plus_H_I[i][j]=detw_H_I[i][j];
				}
				det_YU_H[i]=stepQ*det_H[i]*(-1);//阈值的调整
				YU_H[i]+=det_YU_H[i]+alpha*plus_YU_H[i];
				plus_YU_H[i]=det_YU_H[i];
			}

			//调整状态层到隐层的变化权值
			for(i=0;i<HN;i++)
			{
				for(j=0;j<CN;j++)
				{
					detw_H_C[i][j] = stepC  * det_H[i] *(out_C[j]+beta*tem_C[j]);
					w_H_C[i][j] += (detw_H_C[i][j] + alpha * plus_H_C[i][j]);
					plus_H_C[i][j] = detw_H_C[i][j];
				}
			}

			for(i=0;i<ON;i++)
			{
				check_out<<setw(20)<<SAM_T[timeS][i]<<setw(20)<<out_O[i]<<setw(20);
			}
			check_out<<"\n";
		}
		cout<<"第"<<ii<<"次误差"<<Err<<"\n";
		err_epoch<<ii<<"\t"<<Err<<"\n";
		ii++;
	}	

	//学习完后的权值和阈值	
	weight<<"调整后权值:\n";
	for(i=0;i<HN;i++)
	{
		for(j=0;j<INR;j++)
		{
			weight<<w_H_I[i][j]<<"\t";
			if(j==INR-1)weight<<"\n";
		}
	}
	weight<<"\n\n";	
	for(i=0;i<HN;i++)
	{
		for(j=0;j<CN;j++)
		{
			weight<<w_H_C[i][j]<<"\t";
			if(j==CN-1)weight<<"\n";
		}	
	}
	weight<<"\n\n";	
	for(i=0;i<ON;i++)
	{
		for(j=0;j<HN;j++)
		{
			weight<<w_O_H[i][j]<<"\t";
			if(j==HN-1)weight<<"\n";
		}
	}	

	weight << "\n调整后阈值:\n" ;
	for(i=0;i<HN;i++)
	{
		weight<<YU_H[i]<<"\t";
	}

	weight<<"\n\n";
	for(i=0;i<ON;i++)
	{
		weight<<YU_O[i]<<"\t";
	}
	weight<<"\n";



	///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////		  
	/*	//进行校验样本校验	
	printf("检查调整后的权值是否满足要求:\n");
	check_out<<setiosflags(ios::fixed);
	check_out<<setprecision(8);//文件输出时精度

	for(i=0;i<NUM_YAN;i++)
	{
	for(j=0;j<INR;j++)
	{
	check_sample>>YAN_P[i][j];
	}
	for(k=0;k<ON;k++)
	{
	check_sample>>YAN_T[i][k];
	}
	}

	for(timeS=0;timeS<NUM_YAN;timeS++)
	{
	//输入样本
	for(i=0;i<INR;i++)
	{
	out_I[i]=YAN_P[timeS][i];
	}

	//状态层的记忆
	if(timeS==0)
	{
	for(i=0;i<CN;i++)
	{
	v_C[i]=0;
	out_C[i]=v_C[i];
	tem_C[i]=0.0;
	}
	}
	else
	{
	for(i=0;i<CN;i++)
	{
	v_C[i]=out_H[i];
	out_C[i]=v_C[i];
	tem_C[i]=out_C[i];
	}
	}

	//隐层的输入输出
	for(i=0;i<HN;i++)
	{			
	sigma=0.0;
	for(j=0;j<INR;j++)
	{
	sigma+=out_I[j]*w_H_I[i][j];//输入层的的输入
	}
	for(k=0;k<CN;k++)
	{
	sigma+=out_C[k]*w_H_C[i][k];//加入状态层的输入
	}
	sigma+=beta*tem_C[i];//加上暂态记忆的输入
	v_H[i]=sigma-YU_H[i];//加上阈值的输入
	out_H[i]=1.0/(1.0+exp(-v_H[i]));//隐层各神经元的的输出
	}		

	for(i=0;i<ON;i++)
	{	
	sigma=0.0;
	for(j=0;j<HN;j++)
	{
	sigma+=out_H[j]*w_O_H[i][j];//输出层的输入
	}
	v_O[i]=sigma-YU_O[i];//加上阈值的输入
	out_O[i]=1.0/(1.0+exp(-v_O[i]));//输出层的输出
	}

	for(i=0;i<ON;i++)
	{
	tem_err[i]=YAN_T[timeS][i]-out_O[i];
	tem_err_LR+=(tem_err[i])*(tem_err[i]);
	}

	check_out<<setw(5)<<timeS;
	for(i=0;i<ON;i++)
	{
	check_out<<setw(20)<<YAN_T[timeS][i]<<setw(20)<<out_O[i]<<setw(20)<<tem_err[i];
	}
	check_out<<"\n";
	}
	*/
    ///////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////
	//关闭文件			
	train_sample.close();
//	init_weight.close();
	read_sample.close();
	weight.close();
	err_epoch.close();
	netvsact.close();
	check_out.close();
	return 0;
}

⌨️ 快捷键说明

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