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

📄 bp11.cpp

📁 简单实用的BP神经网络训练测试程序
💻 CPP
字号:
// BP11.cpp : Defines the entry point for the console application.
//

// MYBP0.cpp : Defines the entry point for the console application.


// BPNN1.cpp : Defines the entry point for the console application.
//


//#include "StdAfx.h"
#include <fstream>
#include <iostream.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <iomanip.h>

using namespace std;


//设计神经网络结构
#define NUM_AYER 3             //网络层数
#define IN  2                 //输入层神经元个数  1
#define HN  10                //隐含层神经元个数    6
#define ON  1                //输出层神经元个数    1
#define SAM_NUM   100       //学习样本数
#define SAM_YAN    200    //校验样本数
#define MAX_EPOCH  100000       //最大迭代次数

const double alpha=0.1;     //动量项系数
const double stepH=0.8;      //输出到隐层的学习步长
const double stepQ=0.8;      //隐层到输入的学习步长

double SAM_P[SAM_NUM][IN];    //训练样本
double SAM_T[SAM_NUM];    //训练样本

double Test_P[SAM_YAN][IN];  //校验样本
double Test_T[SAM_YAN];   //期望校验样本

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

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

double In_O;               //输出层的输入
double out_O;             //输出层的输出
double out_e;             //输出层的期望输出

double Yu_H[HN];               //隐层的阈值
double detaYu_H[HN];          //隐层阈值的变化量
double plusYu_H[HN];           //隐层阈值的冲量项

double Yu_O;               //输出层的阈值
double detaYu_O;          //输出层阈值的变化量
double plusYu_O;          //输出层阈值的冲量项

double w_H_I[HN][IN];          //输入层到隐含层的权值
double detaw_H_I[HN][IN];      //输入层到隐含层的权值的变化量
double plusw_H_I[HN][IN];      //输入层到隐层的权值的冲量项

double w_O_H[HN];          //隐含层到输出层的权值
double detaw_O_H[HN];      //隐含层到输出层的权值的变化量
double plusw_O_H[HN];      //隐层到输出层的权值的冲量项

double deta_H[HN];             //隐含层的局部梯度
double deta_O;             //输出层的局部梯度

double Err;                  //网络学习的评价误差
double pre_Err=0.001;        //预定义的网络训练精度
double tem_err;             //出层的局部误差
double tem_err_LR;           //网络的整体误差
double sigma;                //中间变量


double RandomEqualREAL(double Low, double High)		//产生Low-High之间的随机数
{
	return ((double) rand() / RAND_MAX) * (High-Low) + Low;
}


int main(int argc, char* argv[])
{
	
	int n,k;
	
	ifstream Ex_out("exout.txt",ios::in);             //网络的期望输出
	ifstream Train_in("Trainin.txt",ios::in);         //网络的训练输入
	ifstream Test_in("Yanin.txt",ios::in);                 //测试输入
	ifstream Test_out("Yanout.txt",ios::in);               //测试输出
    
	ofstream Act_out("Actout.txt",ios::out);          //网络的实际输出
	ofstream out_weightH("outweightH.txt",ios::out);     //隐层权值输出
	ofstream out_weightO("outweightO.txt",ios::out);     //输出层权值输出
	ofstream Err_out("err.txt",ios::out);                 //误差输出
	
	
	//文件打开检查
	if((Ex_out.fail())||(Train_in.fail())||(Test_in.fail())||(Test_out.fail()))
	{
		printf("Error input file!\n");
		exit(0);
	}
	if((out_weightH.fail())||(Act_out.fail())||Err_out.fail()||(out_weightO.fail()))
	{
		printf("Error output file!\n");
		exit(0);
	}
	//网络初始化
	
	for(k=0;k<HN;k++)
	{
		for(n=0;n<HN;n++)
		{
			w_H_I[k][n] = RandomEqualREAL(-0.5,0.5);
			plusw_H_I[k][n]=0.0;
		}
		
		
		w_O_H[k] = RandomEqualREAL(-0.5,0.5);
		Yu_H[k] = RandomEqualREAL(-0.5,0.5);
		
		plusYu_H[n]=0.0;
		
		plusw_O_H[n]=0.0;
		
	}
	
	Yu_O=0.12061;				    //输出层阈值初始化
	plusYu_O=0.0;
	
	int epoch=0;                   //训练循环次数
	int ts=0;                      //样本训练次数
	//误差值初始化  正向传播
	Err = 1.0 + pre_Err;
	while((Err>pre_Err)&&(epoch<MAX_EPOCH))
	{
		Err=0.0;		
		for(ts=0;ts<SAM_NUM;ts++)
		{
			for(n=0;n<HN;n++)
			{
				//输入样本
			Train_in>>SAM_P[ts][n];       //输入样本
			
			out_I[n] = SAM_P[ts][n];
			}
			out_I[0]=out_I[0]/0.3;
			out_I[1]=out_I[1]/5;
			 //输出样本
				Ex_out>>SAM_T[ts]; 
			out_e=SAM_T[ts];
			out_e=out_e/15;               //数字根据自己的输入样本的最大值自己改
			
			sigma=0.0;
			
			//隐层的输入输出
			for(k=0;k<HN;k++)
			{
				for(n=0;n<IN;n++)
				{
					In_H[k]=out_I[n]*w_H_I[k][n]+Yu_H[k];            //隐层的输入
					out_H[k]=1.0/(1.0+exp(-In_H[k]));            //隐层各神经元的输出
					sigma+=out_H[k]*w_O_H[k];
				}
				
			}
			//输出层的输入输出
			
			In_O=sigma+Yu_O;                  ////输出层的输入
			
			out_O=1.0/(1.0+exp(-In_O));        //输出层的输出
			
			
			//计算评价误差
			tem_err = out_e-out_O;
			tem_err_LR=0.5*pow(tem_err,2);  //网络的整体误差的平方和
			
			Err+=tem_err_LR;                  //网络学习的评价误差
			
			
			//计算局部误差   //反向传播			
			deta_O=tem_err*out_O*(1.0-out_O);  //输出层的局部梯度
			
			detaYu_O=stepH*deta_O;
			Yu_O+=detaYu_O+alpha*plusYu_O;
			plusYu_O=detaYu_O+alpha*plusYu_O;
			
			
			for(k=0;k<HN;k++)
			{
				deta_H[k]=deta_O*w_O_H[k]*out_H[k]*(1.0-out_H[k]);        //隐层的局部梯度
				
				detaw_O_H[k]=stepH*deta_O*out_H[k];					//调整输出层到隐层的变化权值 
				w_O_H[k]+=detaw_O_H[k]+alpha*plusw_O_H[k];
				plusw_O_H[k]=detaw_O_H[k]+alpha*plusw_O_H[k];
				for(n=0;n<IN;n++)
				{
					detaw_H_I[k][n]=stepQ*deta_H[k]*out_I[n];				//调整隐层到输入层的变化权值
					w_H_I[k][n]+=detaw_H_I[k][n]+alpha*plusw_H_I[k][n];
					plusw_H_I[k][n]=detaw_H_I[k][n]+alpha*plusw_H_I[k][n];
					
					detaYu_H[k]=stepQ*deta_H[k];
					Yu_H[k]+=detaYu_H[k]+alpha*plusYu_H[k];
					plusYu_H[k]=detaYu_H[k]+alpha*plusYu_H[k];
				}
				
			}		
		}
		epoch++;
		cout<<epoch<<" "<<Err<<"\n";
		Err_out<<Err<<"\n";
}
	
	for(k=0;k<HN;k++)
	{
		for(n=0;n<IN;n++)
		{
			out_weightH<<w_H_I[k][n]<<"\n";
		}
		
		out_weightO<<w_O_H[k]<<"\n";
	}
	
	
	int i,j;
	for(i=0;i<SAM_YAN;i++)
	{
		Test_in>>Test_P[i][n];       //输入样本   
		Test_out>>Test_T[i];         //输出样本
		for(n=0;n<IN;i++)
		{
			out_I[n] = Test_P[i][n];
		}
		out_I[0]=out_I[0]/0.3;
		out_I[1]=out_I[1]/5;
		
		out_e=Test_T[i];
		out_e=out_e/15;
		//隐层的输入输出
		
		sigma=0.0;
		for(j=0;j<HN;j++)
		{
			for(n=0;n<IN;i++)
			{
				In_H[j]=out_I[n]*w_H_I[j][n]+Yu_H[j]; 
			}
			           //隐层的输入
			out_H[j]=1.0/(1.0+exp(-In_H[j]));            //隐层各神经元的输出
			sigma+=out_H[j]*w_O_H[j];
		}
		//输出层的输入输出
		
		In_O=sigma+Yu_O;                  //网络输入
		
		out_O=1.0/(1.0+exp(-In_O));        //网络输出
		
		Act_out<<out_O<<"	"<<out_I<<"\n";
		
		cout<<out_I<<"	"<<out_O<<"\n";
	}	
	
	Ex_out.close();
	Train_in.close();
    Err_out.close();
	Act_out.close();
	out_weightH.close();
	out_weightO.close();
	Test_in.close();
	Test_out.close();
	
	return 0;
	
}

⌨️ 快捷键说明

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