📄 firsttrain.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 + -