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

📄 long-bp.cpp

📁 BP神经网络,用VC实现/*********** universal BP algorithm *********** *********** dglag@163.com ***********/
💻 CPP
字号:
/*********** universal	BP algorithm ***********
 ***********     dglag@163.com       ***********/
#include "iostream.h"
#include "iomanip.h"
#include "stdlib.h"
#include "math.h"
#include "stdio.h"
#include "time.h"
#include "fstream.h"



/* definition of user data  */
int N;//学习样本个数
int M;//神经网络层数
int note[10];//各层的节点数,层数一般小于10

/*定义一个输入输出结构*/
struct individual{
double input[50]; //输入小于50个	
double teach[50]; //输出小于50个
};

/* definition of global variables */
double W[50][10][50];//权值
double YU[50][10];//阈值
double X[200][10][50];//每个样本各层的输出,设样本数小于200
double a=0.6; //学习效率
struct individual Study_Data[200];//N个学习样本
double pre_error;//预定误差

/* function prototype */
void talk();//与用户交谈
void initial();//初始化权、阈值
void GetTrainingData();//从txt中读取样本数据
void IO_process();//计算各层输出
void adjust();//调整权、阈值
double Err_Sum();//计算总的误差
void savevalue();//储存权、阈值

/* main program */
int main()
{
	double sum_err;
    int study=0;//训练次数
    srand(static_cast<unsigned>(time(static_cast<time_t *>(NULL))));//随机数种子
	talk();
	GetTrainingData();
    initial();
    do
	{
		IO_process();
		adjust();
		study++;
		sum_err=Err_Sum(); //全部样本全局误差计算
		cout<<"第"<<study<<"次学习的均方误差为"<<sum_err<<endl;
	}while (sum_err>pre_error); 
	cout<<"网络已经学习了"<<study<<"次,学习的均方误差为"<<sum_err<<endl;
    savevalue();
    return 0;
}

/* 与用户交谈 */
void talk()
{
	cout<<"请输入您需要的神经网络层数: ";
	cin>>M;
	cout<<"请输入您需要的各层的节点数(依次从输入到输出层,空格隔开): ";
	for(int i=0;i<M;i++)
		cin>>note[i];
	cout<<"请确保学习样本已存入“学习样本.txt”,并输入学习样本的个数: ";
	cin>>N;
	cout<<"请输入您需要的预定精度: ";
	cin>>pre_error;
	cout<<"学习中....... "<<endl;
}

/* 初始化权、阈值 */
void initial()
{
	double random_0_1;
	int q,i,j;
	
	for(q=0;q<M-1;q++)
	{
		for(i=0;i<note[q+1];i++)
		{
			for(j=0;j<note[q];j++)
			{
				random_0_1=rand()/static_cast<double>(RAND_MAX);//[0.0,1]间
			    W[i][q][j]=2.0*random_0_1-1.0; //初始化所有的权值,[-1.0,1.0]
			}
		}
	}
	
	for(q=0;q<M-1;q++)
	{
		for(i=0;i<note[q+1];i++)
		{
		random_0_1=rand()/static_cast<double>(RAND_MAX);//[0.0,1]间
		YU[i][q]=2.0*random_0_1-1.0;  //阈值初始化 ,[-1.0,1.0]
		}
	}
}
/* 从txt中读取样本数据 */
void GetTrainingData()
{
	ifstream GetTrainingData ( "训练样本.txt", ios::in );
	for(int m=0;m<N;m++)
	{
		for(int i=0;i<note[0];i++)
		{
			GetTrainingData>>Study_Data[m].input[i];  //取得输入数据
		}
		for(int j=0;j<note[M-1];j++)
		{
			GetTrainingData>>Study_Data[m].teach[j];  //取得输出数据
		}
	}
	GetTrainingData.close();
}
/* 计算各层输出 */
void IO_process()
{
	double sigma1;
	double sigma2;
    int i,m,q,h;
	//X[200][10][50]
for(m=0;m<N;m++)
{
	for(i=0;i<note[0];i++)
	X[m][0][i]=Study_Data[m].input[i];//第0层输入即输出
	for(q=1;q<M;q++)
	{
		for(i=0;i<note[q];i++)
		{
			sigma1=0;
			for(h=0;h<note[q-1];h++)
			{
			sigma1+=X[m][q-1][h]*W[i][q-1][h];
			}
			sigma2=sigma1-YU[i][q-1];
			X[m][q][i]=1.0/(1.0+exp(-sigma2));
		}
	}
}

}

/* 调整权、阈值 */
void adjust()
{
	double delta[200][10][50];
	int i,j,k,h,m,q;
for(m=0;m<N;m++)
{
	for(h=0;h<note[M-1];h++)
		delta[m][M-1][h]=(Study_Data[m].teach[h]-X[m][M-1][h])*X[m][M-1][h]*(1-X[m][M-1][h]);
	for(j=M-2;j>0;j--)
	{
		for(i=0;i<note[j];i++) 
		{
			delta[m][j][i]=0;
		for(k=0;k<note[j+1];k++)
		delta[m][j][i]+=delta[m][j+1][k]*W[k][j][i]*X[m][j][i]*(1-X[m][j][i]);
		}
	}
}

for(q=0;q<M-1;q++)
{
	for(i=0;i<note[q+1];i++)
	{
		for(j=0;j<note[q];j++)
		{
			for(m=0;m<N;m++)
			{
				W[i][q][j]+=a*delta[m][q+1][i]*X[m][q][j];//权值调整
			}
		}
	}
}

for(q=0;q<M-1;q++)
{
	for(i=0;i<note[q+1];i++)
	{
		for(m=0;m<N;m++)
			{
				YU[i][q]-=a*delta[m][q+1][i];//阈值调整
			}
	}
}

}


/* 计算总的误差 */
double Err_Sum()
{
	double s_err=0;
	int m,h;
	for(m=0;m<N;m++)
	{
		for(h=0;h<note[M-1];h++)
		{
			s_err+=(Study_Data[m].teach[h]-X[m][M-1][h])*(Study_Data[m].teach[h]-X[m][M-1][h])/2;
		}
	}
	return s_err;
}
/* 储存权、阈值 */
void savevalue()
{
	ofstream outQuanFile( "权值.txt", ios::out );
	ofstream outYuFile( "阈值.txt", ios::out );
	outQuanFile<<"W[i][q][j]:第q层j指向i的权,\n";
	for(int q=0;q<M-1;q++)
	{		
		for(int j=0;j<note[q];j++)
		{
			outQuanFile<<"\n"<<"q="<<q<<","<<"j="<<j<<":"<<endl;
			for(int i=0;i<note[q+1];i++)
			{
			outQuanFile<<W[i][q][j]<<"   ";
			}
		}
		outQuanFile<<"\n";
	}
	
	outYuFile<<"各层的阈值为YU[i][q](第q+1层第i个阈值):\n";
	for(int qq=0;qq<M-1;qq++)
	{
		outYuFile<<"\n"<<"第"<<qq+1<<"层:"<<endl;
		for(int ii=0;ii<note[qq+1];ii++)
		{
		outYuFile<<YU[ii][qq]<<"  ";  //输出层阈值写入文本
		}
	}
	outQuanFile.close();
	outYuFile.close();
}

⌨️ 快捷键说明

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