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

📄 main.cpp

📁 BP网络解决异或问题的实例
💻 CPP
字号:
////////////////////////////////////////////////////////////////////////////////////////
// 
//     BP网络解决异或问题实例
//
//     本网络结构为三层BP网络,各层神经元个数可变,更改如下#define即可
//     
//     所用函数和矩阵类都定义在functions.h中
//
////////////////////////////////////////////////////////////////////////////////////////

#include "functions.h"
#include <stdlib.h>

#define IN_NUM    2 //输入层神经元个数
#define OUT_NUM   1 //输出层神经元个数
#define HID_NUM   2 //隐藏层神经元个数
#define SAM_NUM   4 //训练样本数
#define LEARN    0.6 //学习系数
#define ERROR    0.008 //网络总误差上限
#define ALPHA    0 //动量系数,用于改进的BP算法,为0则不增加动量项
#define MAXCOUNT  1e5 //迭代训练次数上限

void main()
{

	cout<<'\n'<<"   (异或问题)BP神经网络结构如下:"<<'\n'<<'\n';	
	cout<<'\t'<<"输出层神经元个数——"<<OUT_NUM<<endl;
	cout<<'\t'<<"隐含层神经元个数——"<<HID_NUM<<endl;
	cout<<'\t'<<"输入层神经元个数——"<<IN_NUM<<endl<<endl;

	CMatrix teacher (SAM_NUM, IN_NUM+OUT_NUM );//导师信号矩阵

	teacher.Set(0,0) = 0;//输入样本00
	teacher.Set(0,1) = 0;
	teacher.Set(0,2) = 0;//期望输出0
	teacher.Set(1,0) = 0;//输入样本01
	teacher.Set(1,1) = 1;					
	teacher.Set(1,2) = 1;//期望输出1
	teacher.Set(2,0) = 1;//输入样本10
	teacher.Set(2,1) = 0;
	teacher.Set(2,2) = 1;//期望输出1					
	teacher.Set(3,0) = 1;//输入样本11
	teacher.Set(3,1) = 1;
	teacher.Set(3,2) = 0;//期望输出0

	cout<<"导师信号:"<<endl<<'\t'<<"输入   "<<'\t'<<"   输出"<<endl;
	teacher.Print(6);

	CMatrix w1 (IN_NUM+1 , HID_NUM);//权值矩阵
	CMatrix w2 (HID_NUM+1 , OUT_NUM);

	w1.Set(0,0) = 0.0513;//输入层到隐藏层权值矩阵初值,也可随机赋值
	w1.Set(1,0) = 0.0579;
	w1.Set(2,0) = 0.0703;//阈值
	w1.Set(0,1) = -0.0291;
	w1.Set(1,1) = 0.0999;
	w1.Set(2,1) = 0.0939;//阈值

	w2.Set(0,0) = 0.0801;//隐藏层到输出层权值矩阵初值,也可随机赋值
	w2.Set(1,0) = -0.0605;
	w2.Set(2,0) = 0.0109;//阈值	
	
	cout<<"输入层到隐藏层权值矩阵初始值:"<<endl;
	w1.Print();
	cout<<"隐藏层到输出层权值矩阵初始值:"<<endl;
	w2.Print();
	cout<<endl;

	CMatrix input (IN_NUM,1);//样本输入
	CMatrix expect (OUT_NUM,1);//期望输出
	CMatrix input_ex (IN_NUM+1, 1);//样本输入扩展(在最后列补上-1,用于减去阈值)
	CMatrix hidden (HID_NUM , 1);//隐藏层输出
	CMatrix hidden_ex (HID_NUM+1, 1);//隐藏层输出扩展(在最后列补上-1,用于减去阈值)
	CMatrix output (OUT_NUM , 1);//实际输出
	CMatrix error_hidden (HID_NUM , 1);//隐藏层误差
	CMatrix error_output (OUT_NUM , 1);//输出层误差
	CMatrix delta_w1 (IN_NUM+1 , HID_NUM);//输入层到隐藏层权值矩阵调整值
	CMatrix delta_w2 (HID_NUM+1 , OUT_NUM);//隐藏层到输出层权值矩阵调整值

	CMatrix last_dw1 (IN_NUM+1 , HID_NUM);//用于保存上次输入层到隐藏层权值矩阵调整值
	CMatrix last_dw2 (HID_NUM+1 , OUT_NUM);//用于保存上次隐藏层到输出层权值矩阵调整值
	last_dw1.zeros();//置零
	last_dw2.zeros();//置零
 
	long turns_count;//迭代训练次数计数
	int sample_count;//样本数计数
	double error_ave=0;//网络总误差,采用“各样本误差的和”,可自定义
	double error_sum=0;		    
		


	for(turns_count=1;turns_count<MAXCOUNT; turns_count++)//开始迭代训练
	{   
		for(sample_count=1;sample_count<=SAM_NUM;sample_count++)//一轮(每个样本逐次训练)
		{
		
			input=teacher.SelectRow(sample_count,1,IN_NUM).transp();			
			expect=teacher.SelectRow(sample_count,IN_NUM+1,OUT_NUM).transp();		
 			input_ex = input.ColumnExpand();
			hidden = w1.transp() * input_ex;
			hidden.SigmoidColumn();		   
			hidden_ex=hidden.ColumnExpand();			
			output = w2.transp() * hidden_ex;
			output.SigmoidColumn();//计算实际输出
				
			for(int i=0;i<OUT_NUM;i++)
				error_output.Set(0,i) = (*(expect.Getp()+i) - *(output.Getp()+i)) * Derivative(*(output.Getp()+i));
			
			CMatrix wRow (1,OUT_NUM);	
				for(i=0;i<HID_NUM;i++)
				{		
					wRow=w2.SelectRow(i+1,1,OUT_NUM);
	    			CMatrix deltaw = wRow * error_output;
					*(error_hidden.Getp()+i) = *(deltaw.Getp()) * Derivative(*(hidden.Getp()+i));		    
				}

			delta_w2=hidden_ex * error_output.transp();
			delta_w2.MultipleK(LEARN);
			w2=w2+delta_w2+last_dw2;//调整阈值			
			delta_w1=input_ex * error_hidden.transp();
			delta_w1.MultipleK(LEARN);
			w1=w1+delta_w1+last_dw1;//调整阈值
			last_dw2=delta_w2;
			last_dw1=delta_w1;
			last_dw2.MultipleK(ALPHA);
			last_dw1.MultipleK(ALPHA);//保留上次调整值		

		}

		error_ave=0;
		for(sample_count=1;sample_count<=SAM_NUM;sample_count++)// 计算网络总误差
		{
			input=teacher.SelectRow(sample_count,1,IN_NUM).transp();
			expect=teacher.SelectRow(sample_count,IN_NUM+1,OUT_NUM).transp();			
 			input_ex = input.ColumnExpand();
			hidden = w1.transp() * input_ex;
			hidden.SigmoidColumn();
			hidden_ex=hidden.ColumnExpand();
			output = w2.transp() * hidden_ex;
			output.SigmoidColumn();//实际输出
			error_sum=0;
			for(int i=0;i<OUT_NUM;i++)
				error_sum+=pow(*(output.Getp()+i) - *(expect.Getp()+i),2);
			error_sum=error_sum/2;//一个样本的输出误差,采用“各个输出误差平方和/2”
			error_ave += error_sum;//网络总误差,采用“各样本误差的和”,可自定义
		}

		if(error_ave<=ERROR)//若成功
			break;
	}

		cout<<"迭代"<<turns_count<<"次后"<<'\n'<<endl;
		cout<<"总误差 E = "<<error_ave<<'\t'<<"成功!"<<'\n'<<endl;
		cout<<"输入层到隐藏层权值矩阵:"<<endl;
		w1.Print();
		cout<<"隐藏层到输出层权值矩阵:"<<endl;
		w2.Print();

		cout<<"实际输出依次为:"<<endl<<endl;
		for(sample_count=1;sample_count<=SAM_NUM;sample_count++)
		{			
			input=teacher.SelectRow(sample_count,1,IN_NUM).transp();
			expect=teacher.SelectRow(sample_count,IN_NUM+1,OUT_NUM).transp();			
 			input_ex = input.ColumnExpand();
			hidden = w1.transp() * input_ex;
			hidden.SigmoidColumn();
			hidden_ex=hidden.ColumnExpand();
			output = w2.transp() * hidden_ex;
			output.SigmoidColumn();
		    output.Print();			
		}
 	
}

⌨️ 快捷键说明

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