BP神经网络算法
简介:BP(Back Propagation)网络是1986年由Rumelhart和McCelland为首的科学家小组提出,是一种按误差逆传播算法训练的多层前馈网络,是目前应用最广泛的神经网络模型之一。BP网络能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用最速下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差平方和最小。BP神经网络模型拓扑结构包括输入层(input)、隐层(hide layer)和输出层(output layer)
摘 要:BP神经网络算法是在BP神经网络现有算法的基础上提出的,是通过任意选定一组权值,将给定的目标输出直接作为线性方程的代数和来建立线性方程组,解得待求权,不存在传统方法的局部极小及收敛速度慢的问题,且更易理解。
关键词:固定权值;gauss消元法;BP算法
人工神经网络(artificial neural networks,ANN)系统是20世纪40年代后出现的,它是由众多的神经元可调的连接权值连接而成,具有大规模并行处理、分布式信息存储、良好的自组织自学习能力等特点,在信息处理、模式识别、智能控制及系统建模等领域得到越来越广泛的应用。尤其误差反向传播算法(Error Back-propagation Training,简称BP网络)可以逼近任意连续函数,具有很强的非线性映射能力,而且网络的中间层数、各层的处理单元数及网络的学习系数等参数可根据具体情况设定,灵活性很大,所以它在许多应用领域中起到重要作用。近年来,为了解决BP神经网络收敛速度慢、不能保证收敛到全局最小点,网络的中间层及它的单元数选取无理论指导及网络学习和记忆的不稳定性等缺陷,提出了许多改进算法。
1 传统的BP算法简述
BP算法是一种有监督式的学习算法,其主要思想是:输入学习样本,使用反向传播算法对网络的权值和偏差进行反复的调整训练,使输出的向量与期望向量尽可能地接近,当网络输出层的误差平方和小于指定的误差时训练完成,保存网络的权值和偏差。具体步骤如下:
(1)初始化,随机给定各连接权[w],[v]及阀值θi,rt。
(2)由给定的输入输出模式对计算隐层、输出层各单元输出
bj=f(■wijai-θj) ct=f(■vjtbj-rt)
式中:bj为隐层第j个神经元实际输出;ct为输出层第t个神经元的实际输出;wij为输入层至隐层的连接权;vjt为隐层至输出层的连接权。
dtk=(ytk-ct)ct(1-ct) ejk=[■dtvjt] bj(1-bj)
式中:dtk为输出层的校正误差;ejk为隐层的校正误差。
(3)计算新的连接权及阀值,计算公式如下:
vjt(n+1)=vjt(n)+?琢dtkbj wij(n+1)=wij(n)+?茁ejkaik
rt(n+1)=rt(n)+?琢dtk θj(n+1)=θj(n)+?茁ejk
式中:?琢,?茁为学习系数(0<?琢<1,0<?茁<1)。
(4)选取下一个输入模式对返回第2步反复训练直到网络设输出误差达到要求结束训练。
传统的BP算法,实质上是把一组样本输入/输出问题转化为一个非线性优化问题,并通过负梯度下降算法,利用迭代运算求解权值问题的一种学习方法,但其收敛速度慢且容易陷入局部极小,为此提出了一种新的算法,即高斯消元法。
2 改进的BP网络算法
2.1 改进算法概述
此前有人提出:任意选定一组自由权,通过对传递函数建立线性方程组,解得待求权。本文在此基础上将给定的目标输出直接作为线性方程等式代数和来建立线性方程组,不再通过对传递函数求逆来计算神经元的净输出,简化了运算步骤。没有采用误差反馈原理,因此用此法训练出来的神经网络结果与传统算法是等效的。其基本思想是:由所给的输入、输出模式对通过作用于神经网络来建立线性方程组,运用高斯消元法解线性方程组来求得未知权值,而未采用传统BP网络的非线性函数误差反馈寻优的思想。
2.2 改进算法的具体步骤
对给定的样本模式对,随机选定一组自由权,作为输出层和隐含层之间固定权值,通过传递函数计算隐层的实际输出,再将输出层与隐层间的权值作为待求量,直接将目标输出作为等式的右边建立方程组来求解。
现定义如下符号(见图1):x (p)输入层的输入矢量;y (p)输入层输入为x (p)时输出层的实际输出矢量;t (p)目标输出矢量;n,m,r分别为输入层、隐层和输出层神经元个数;W为隐层与输入层间的权矩阵;V为输出层与隐层间的权矩阵。具体步骤如下:
(1)随机给定隐层和输入层间神经元的初始权值wij。
(2)由给定的样本输入xi(p)计算出隐层的实际输出aj(p)。为方便起见将图1网络中的阀值写入连接权中去,令:隐层阀值θj=wnj,x(n)=-1,则:
aj(p)=f(■wijxi(p)) (j=1,2…m-1)。
(3)计算输出层与隐层间的权值vjr。以输出层的第r个神经元为对象,由给定的输出目标值tr(p)作为等式的多项式值建立方程,用线性方程组表示为:
a0(1)v1r+a1(1)v2r+…+am(1)vmr=tr(1)a0(2)v1r+a1(2)v2r+…+am(2)vmr=tr(2) ……a0(p)v1r+a1(p)v2r+…+am(p)vmr=tr(p) 简写为: Av=T
为了使该方程组有唯一解,方程矩阵A为非奇异矩阵,其秩等于其增广矩阵的秩,即:r(A)=r(A┊B),且方程的个数等于未知数的个数,故取m=p,此时方程组的唯一解为: Vr=[v0r,v2r,…vmr](r=0,1,2…m-1)
(4)重复第三步就可以求出输出层m个神经元的权值,以求的输出层的权矩阵加上随机固定的隐层与输入层的权值就等于神经网络最后训练的权矩阵。
3 计算机运算实例
现以神经网络最简单的XOR问题用VC编程运算进行比较(取神经网络结构为2-4-1型),传统算法和改进BP算法的误差(取动量因子α=0.001 5,步长η=1.653)
算法C++版代码:
#ifndef BP_H
#define BP_H
class BpNet
{
private:
int _nInput; //输入层节点个数
int _nHide; //隐含层节点个数
int _nOutput; //输出层节点个数
double **_pplfWeight1; //输入层-隐含层权系数
double **_pplfWeight2; //隐含层-输出层权系数
double *_plfHideIn, *_plfHideOut; //隐含层的网络输入和输出
double *_plfOutputIn, *_plfOutputOut; //输出层的网络输入和输出
private:
double (*f)(double); //激活函数
public:
/**
构造函数,创建一个未经训练的Bp网络
param nInput 输入层节点个数
param nHide 隐含层节点个数
param nOutput 输出层节点个数
*/
BpNet(int nInput, int nHide, int nOutput);
/**
析构函数,销毁已有的Bp网络
*/
virtual ~BpNet();
/**
通过多组正例,对Bp网络进行训练
param pplfInput 正例的输入
param pplfDesire 正例的理想输出
返回值 训练是否收敛
*/
bool Train(int n, double **pplfInput, double **pplfDesire);
/**
使用当前的Bp网络对指定模式进行分类,分类的结果存储到plfOutput中
param plfInput 待分类的模式
param plfOutput 分类的输出
*/
void Classify(double plfInput[], double plfOutput[]);
};
#endif
#include "bp.h"
#include "memory.h"
#include "math.h"
#include "time.h"
#include "stdlib.h"
#include "stdio.h"
double sigmoid(double x)
{
return 1 / (1 + exp(- x));
}
BpNet::BpNet(int nInput, int nHide, int nOutput)
{
_nInput = nInput;
_nHide = nHide;
_nOutput = nOutput;
srand((unsigned)time(NULL));
_pplfWeight1 = new double *[_nInput];
for (int i = 0; i < _nInput; i++)
{
_pplfWeight1[i] = new double [_nHide];
for (int j = 0; j < _nHide; j++) _pplfWeight1[i][j] = rand() / (double)(RAND_MAX);
}
_pplfWeight2 = new double *[_nHide];
for (int i = 0; i < _nHide; i++)
{
_pplfWeight2[i] = new double [_nOutput];
for (int j = 0; j < _nOutput; j++) _pplfWeight2[i][j] = rand() / (double)(RAND_MAX);
}
_plfHideIn = new double[_nHide];
_plfHideOut = new double[_nHide];
_plfOutputIn = new double[_nOutput];
_plfOutputOut = new double[_nOutput];
f = sigmoid; //使用sigmoid激活函数
}
BpNet::~BpNet()
{
delete []_plfHideIn;
delete []_plfHideOut;
delete []_plfOutputIn;
delete []_plfOutputOut;
for (int i = 0; i < _nInput; i++) delete []_pplfWeight1[i];
for (int i = 0; i < _nHide; i++) delete []_pplfWeight2[i];
delete []_pplfWeight1;
delete []_pplfWeight2;
}
void BpNet::Classify(double plfInput[], double plfOutput[])
{
memset(_plfHideIn, 0, sizeof(double) * _nHide);
memset(_plfHideOut, 0, sizeof(double) * _nHide);
memset(_plfOutputIn, 0, sizeof(double) * _nOutput);
memset(_plfOutputOut, 0, sizeof(double) * _nOutput);
//输入层到隐含层的正向传播
for (int i = 0; i < _nInput; i++)
for (int j = 0; j < _nHide; j++)
_plfHideIn[j] += plfInput[i] * _pplfWeight1[i][j];
for (int j = 0; j < _nHide; j++) _plfHideOut[j] = (*f)(_plfHideIn[j]);
//隐含层到输出层的正向传播
for (int j = 0; j < _nHide; j++)
for (int k = 0; k < _nOutput; k++)
_plfOutputIn[k] += _plfHideOut[j] * _pplfWeight2[j][k];
for (int k = 0; k < _nOutput; k++) _plfOutputOut[k] = (*f)(_plfOutputIn[k]);
if (plfOutput != NULL)
memcpy(plfOutput, _plfOutputOut, sizeof(double) * _nOutput);
}
bool BpNet::Train(int n, double **pplfInput, double **pplfDesire)
{
const double a = 0.1;
const double E = 0.01;
double lfE = E + 1;
//输入层-隐含层权系数增量
double **pplfDeltaWeight1 = new double *[_nInput];
for (int i = 0; i < _nInput; i++)
{
pplfDeltaWeight1[i] = new double [_nHide];
memset(pplfDeltaWeight1[i], 0, sizeof(double) * _nHide);
}
//隐含层-输出层权系数增量
double **pplfDeltaWeight2 = new double *[_nHide];
for (int i = 0; i < _nHide; i++)
{
pplfDeltaWeight2[i] = new double[_nOutput];
memset(pplfDeltaWeight2[i], 0, sizeof(double) * _nOutput);
}
int nCount = 0;
while (lfE > E)
{
lfE = 0;
//对每一个样本进行处理
for (int i = 0; i < n; i++)
{
double *plfInput = pplfInput[i]; //样本输入
double *plfDesire = pplfDesire[i]; //样本期望输出
//计算样本实际输出plfOutput
Classify(plfInput, NULL);
//计算误差测度
double lfEp = 0;
for (int j = 0; j < _nOutput; j++)
lfEp += (plfDesire[j] - _plfOutputOut[j]) * (plfDesire[j] - _plfOutputOut[j]);
lfE += lfEp;
//计算隐含层-输出层权系数增量
double *plfChange2 = new double[_nOutput];
for (int j = 0; j < _nOutput; j++)
plfChange2[j] = _plfOutputOut[j] * (1 - _plfOutputOut[j]) * (plfDesire[j] - _plfOutputOut[j]);
for (int j = 0; j < _nHide; j++)
for (int k = 0; k < _nOutput; k++)
pplfDeltaWeight2[j][k] = a * _plfHideOut[j] * plfChange2[k];
//计算输入层-隐含层权系数增量
double *plfChange1 = new double[_nHide];
memset(plfChange1, 0, sizeof(double) * _nHide);
for (int j = 0; j < _nHide; j++)
{
for (int k = 0; k < _nOutput; k++)
plfChange1[j] += _pplfWeight2[j][k] * plfChange2[k];
plfChange1[j] *= _plfHideOut[j] * (1 - _plfHideOut[j]);
}
for (int j = 0; j < _nInput; j++)
for (int k = 0; k < _nHide; k++)
pplfDeltaWeight1[j][k] = a * plfInput[j] * plfChange1[k];
delete []plfChange1;
delete []plfChange2;
//更新Bp网络权值
for (int i = 0; i < _nInput; i++)
for (int j = 0; j < _nHide; j++)
_pplfWeight1[i][j] += pplfDeltaWeight1[i][j];
for (int i = 0; i < _nHide; i++)
for (int j = 0; j < _nOutput; j++)
_pplfWeight2[i][j] += pplfDeltaWeight2[i][j];
}
nCount++;
if (nCount % 10 == 0) printf("%d%8.5lf\n", nCount, lfE);
}
for (int i = 0; i < _nInput; i++) delete []pplfDeltaWeight1[i];
for (int i = 0; i < _nHide; i++) delete []pplfDeltaWeight2[i];
delete [] pplfDeltaWeight1;
delete [] pplfDeltaWeight2;
return true;
}
分享到:
相关推荐
编程实现BP神经网络算法; 探究BP算法中学习因子算法收敛趋势、收敛速度之间的关系; 修改训练后BP神经网络部分连接权值,分析连接权值修改前和修改后对相同测试样本测试结果,理解神经网络分布存储等特点
本项目是用C#编程语言实现的BP神经网络算法,旨在提供训练和泛化的功能,同时也允许用户自定义动量因子和学习速率,以优化网络的训练效果。下面将详细介绍相关知识点: 1. **C#编程语言**:C#是Microsoft开发的一种...
bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp 神经网络算法bp ...
BP 神经网络算法程序和 Matlab 实例 BP 神经网络是一种常用的机器学习算法,它可以用来解决分类、回归、函数逼近等问题。在本文中,我们将讨论 BP 神经网络的基本原理、算法实现和 Matlab 实例。 BP 神经网络的...
Python实现BP神经网络算法Python实现BP神经网络算法 Python实现BP神经网络算法Python实现BP神经网络算法 Python实现BP神经网络算法Python实现BP神经网络算法 Python实现BP神经网络算法Python实现BP神经网络算法 ...
"BP神经网络算法" BP神经网络算法是一种常用的机器学习算法,用于解决分类和回归问题。 BP神经网络算法的核心思想是使用反向传播算法来调整网络权值,以减小网络输出和目标输出之间的误差。 BP神经网络算法的优化...
Bp神经网络算法推倒与实现Bp神经网络算法推倒与实现 Bp神经网络算法推倒与实现Bp神经网络算法推倒与实现 Bp神经网络算法推倒与实现Bp神经网络算法推倒与实现 Bp神经网络算法推倒与实现Bp神经网络算法推倒与实现 Bp...
**MATLAB-BP神经网络算法实现** BP(Backpropagation)神经网络算法是人工神经网络中最常见的一种学习方法,主要用于训练多层前馈网络。它通过反向传播误差来调整网络权重,从而使得网络能够逐步逼近给定的训练数据...
一种改进的BP神经网络算法及其应用-一种改进的BP神经网络算法及其应用.rar 一种改进的BP神经网络算法及其应用 一种改进的BP神经网络算法及其应用 褚辉,赖惠成 摘要:BP算法是目前应用最为广泛的神经网络学习...
【标题】"基于C#的BP神经网络算法"揭示了这个项目的核心是使用C#编程语言实现了一种经典的机器学习模型——反向传播(Backpropagation, BP)神经网络。BP神经网络是一种多层前馈神经网络,广泛应用于模式识别、函数...
BP神经网络算法由于其通用性强、易于实现且能够逼近任意非线性函数的特点,被广泛应用于各种模式识别和回归分析的场景中。学习BP神经网络算法,理解其原理和数学细节,对于在数据分析、图像处理、自然语言处理等领域...
BP神经网络算法是一种广泛应用的人工神经网络模型,其全称为Backpropagation Neural Network。它主要用于非线性数据的拟合和分类任务。Python作为一种高级编程语言,因其简洁易读的语法和丰富的科学计算库(如NumPy...
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习...Bp神经网络算法推倒与实现源码+项目说明.zip
BP神经网络算法 实现历史数据的样本训练 并对未来数据做出合理预测的案例
bp神经网络改进算法 一.使用说明 该程序有五个主要菜单项: A.数据读入 (从已有数据文件中数据,包括网络结构,权值,学习率,样本等) B.新建数据 (建立新的数据文件) C.学习 D.测试 E.误差显示 操作过程: 1....
### GA-BP神经网络算法应用实例详解 #### 一、概览 本篇文章将详细介绍一个基于MATLAB实现的GA-BP神经网络算法的应用实例。该实例不仅提供了完整的MATLAB源代码,还包含了详细的中文注释,方便用户根据自己的数据...
【标题】"bp神经网络算法_TSP神经网络_bp神经网络matlab_" 指的是使用BP(Backpropagation)神经网络来解决旅行商问题(Traveling Salesman Problem, TSP)。旅行商问题是一个经典的组合优化问题,其目标是找到访问...