MATLAB 2016b–神经网络工具箱中BP网络的实现
在干活的过程中整理下来的,希望对大家有帮助。
上一篇介绍的是MATLAB 2016b–神经网络工具箱中图形用户界面的使用
这一篇就介绍如何利用神经网络工具箱中包含的函数(其中包括BP网络创建函数、传递函数、训练函数等)进行编程,从而实现BP网络的具体功能与应用。
我用的是MATLAB 2016b,它新增了一些网络函数,并对老版中一些网络函数进行了调整。
1.BP神经网络基本函数
对于BP神经网络的实现,MATLAB神经网络工具箱提供了五个基本函数:feedforwardnet,configure,init,train和sim,它们分别对应五个基本步骤,即新建、配置、初始化、训练和仿真。
(1)新建函数feedforwardnet
功能:创建一个BP神经网络。
调用格式:net=feedforwardnet
net=feedforwardnet(hiddenSizes,trainFun)
参数说明:hiddenSizes为表示每个隐含层神经元个数的行向量,默认值为10。例如,如果需要创建一个有3个隐含层的神经网络,其中第一个隐含层有10个神经元,第二个隐含层有8个神经元,第三个隐含层有5个神经元,那么hiddenSizes为[10,8,5]。trianFcn为反向传播训练函数,可选的训练函数有’trainlm’(默认值) 、“trainbr”、“trainbfg”、“trainrp”、“trainscg”等,将在下面专门给予介绍。
新旧版比较:相较于使用旧版函数newff创建网络时需要逐层设置激活函数的形式、神经元数量、输入输出的范围以及训练方式等,新版函数feedforwardnet只需要设定每个隐藏层的大小及训练函数,使用更加简捷。
(2)配置函数configure
功能:对新创建的网络进行配置
调用格式:net=configure(net,P,T)
参数说明:net为创建的网络,P为输入矩阵,T为输出矩阵。配置是为了使网络的输入、输出、连接权重和阈值能够匹配输入矩阵和输出矩阵。train可以自动完成这一过程,但如果想在train之前就对网络进行仿真,则需先进行configure。
(3)初始化函数init
功能:对网络进行自定义的初始化。
调用格式:net=init(net)
参数说明:初始化是对连接权值和阈值进行初始化。BP神经网络在训练之前必须要对权值和阈值进行初始化,train()函数可以自动完成这一过程,但是无法重新赋初值。如果想重新初始化,可以应用init()函数,使网络恢复到初始化的情况。
(4)训练函数train
功能:对网络的权值和阈值进行反复地调整,以减少网络性能函数net.perforFen的值,直到达到预先的要求。
调用格式:[net,tr]=train (net,X,T,Xi,Ai,EW)
参数说明:X和T分别为输入/输出矩阵,net为由feedforwardnet产生的要训练的网络,Xi为初始输入延迟条件,Ai为初始层延迟条件。需要注意的是T、Xi和Ai的默认值是零矩阵,EW是误差权重,net为训练后的网络,tr为训练的记录(训练步数epmh和性能pelf)。train()是通过调用参数net.trainFcn设定的训练函数来实现网络训练的,而且训练的方式由参数net.trainParam的值来确定。
(5)仿真函数sim
功能:对网络进行仿真。
调用格式:[Y,Xf,Af]=sim(net,X,Xi,Ai,T)
参数说明:输入参数与train函数定义的相同,而Y为仿真输出,Xf为最终输入延迟条件,Af为最终层延迟条件.同样的,Xi, Ai, Xf和Af 的默认值都是零矩阵。利用此函数可以在网络训练前后分别进行输入/输出的仿真,以作比较,从而对网络进行修改评价。需要注意的是在网络训练前进行仿真,一定要先进行网络配置操作。
2.BP网络改进的训练函数
BP算法的主要缺点是:收敛速度慢、易陷入局部极值、难以确定隐含层数和隐含层节点的个数。在MATLAB神经网络工具箱中提供了多种改进的BP训练函数,如traingd、traingdm、traingdx、trainrp、traincgf、traincgp、traincgb、trainscg、trainoss、trainlm、trainbr等,每种训练函数各有特点,但是没有一种函数能适应所有情况下的训练过程,现分别介绍如下。
(1)基本的梯度下降训练函数traingd
当将参数trainFcn的值设置为traingd时,执行命令train,就可以根据基本梯度下降算法,沿网络性能参数的负梯度方向调整网络的权值和阈值。
训练函数traingd有七个参数:epochs、show、goal、time、min_grad、max_fail和lr。如果不设置就表示应用内定默认值。
net.trainParam.epochs 最大训练次数(默认为10)
net.trainParam.goal 训练要求精度(默认为0)
net.trainParam.lr 学习率(默认为0.01)
net.trainParam.max_fai 最大失败次数(默认为5)
net.trainParam.min_grad 最小梯度要求(默认为le-10)
net.trainParam.show 显示训练迭代过程(NaN表示不显示,默认为25)
net.trainParam.time 最大训练时间(默认为inf)
训练过程中,只要满足下面五个条件之一,训练就会停止。
① 超过最大迭代次数epochs;
② 表现函数值小于误差指标goal;
③ 训练所用时间超过时间限制time;
④ 最大失败次数超过次数限制max_fail;
⑤ 梯度值小于要求精度min_grad。
(2)动量负梯度下降函数traingdm
动量负梯度下降函数traingdm实现的也是一种批处理的前馈神经网络训练算法,它不但具有更快的收敛速度,而且引入了一个动量项,有效地避免了局部最小问题在网络训练中的出现。所谓动量项的加入就是指在网络每次的权值和阈值改变量中加入前一次的改变量,第k次循环中的权值和阈值改变量可表示为:
mc是动量系数。mc的值在0~1之间,当mc为0时,权值和阈值的改变量就由此时计算出的负梯度来确定;当mc为1时,权值和阈值的改变量就等于它们前一时刻的改变量。而且如果在某个循环内,网络的性能函数值超过了参数max_perf.inc的值,mc的值将被自动设置为0。
函数traingdm的使用类似于函数traingd,只是它有两个特殊的训练参数,mc和max_perf.inc。
(3)自适应修改学习率算法函数traingdx
在负梯度算法中,学习率是一个固定的常数,而且它的值将直接影响到网络的训练性能。如果选择得太大,会降低网络的稳定性;如果选择得过小,会导致过长的训练时间。如果学习率在训练的过程中得到适当的变化,又使得它的值不会过大,就可以加快网络的训练速度,而且确保网络的稳定性。
函数traingdx就是将自适应修改学习率的算法和动量负梯度下降算法有机地结合了起来,所以网络的训练速度更快。
(4)有弹回的BP算法函数trainrp
多层的BP神经网络,常常使用S型传递函数。S型函数的特点是可以把无限的输入映射到有限的输出,而且当输入很大或者很小时,函数的斜率接近于0。这使得在训练具有S型神经元的多层BP网络时,计算出的梯度会出现很小的情况,这时网络权值和阈值的改变量也会很小,从而影响了网络的训练速度。
有弹回的BP算法的目的就是为了解决这个问题,以消除梯度模值对网络训练带来的影响。有弹回的BP算法的训练速度比标准的负梯度算法快得多,而且不需要存储网络权值和阈值的改变量,所以它对内存的需求量也比较小。
(5)共轭梯度算法函数traincgf、traincgp、traincgb、trainscg
标准的负梯度算法是沿网络性能函数的负梯度方向调整权值和阈值,虽然这是减低网络性能函数值的最快方法,但是它并不是网络收敛的最快算法。在共轭梯度算法中,通过变换梯度来加快网络训练的收敛速度。实验证明,共轭梯度算法的训练速度比自适应修改学习率的训练速度要快,有时还快于trainrp。而且它需要的内存也只比一般的算法多一点,所以对于训练具有大规模权值的BP神经网络,共轭梯度算法是一个非常好的选择。
traincgf:Fletcher—Reeves共轭梯度法,为共轭梯度法中存储量要求最小的算法。
traincgp:Polak—Ribiers共轭梯度法,存储量比traincgf稍大,仅对某些问题收敛快。
traincgb:Powell—Beale共轭梯度算法,存储量比traincgp稍大,但一般收敛更快。以上三种共轭梯度法,都需要进行线性搜索。
trainscg:归一化共轭梯度法,是唯一一种不需要线性搜索的共轭梯度法。这样免去了在每个训练周期中线性地搜索网络的调整方向,节省了大量的搜索时间。
(6)BFGS—拟牛顿法函数trainbfg
其需要的存储空间比共轭梯度法要大,每次迭代的时间也要多,但通常在其收敛时所需要的迭代次数要比共轭梯度法少,比较适合小型网络。
(7)一步分割法函数trainoss
trainoss为共轭梯度法和拟牛顿法的一种折中方法。
(8)Levenberg—Marquardt算法函数trainlm
对中等规模的网络来说,trainlm是速度最快的一种训练算法,其缺点是占用内存大。
(9)贝叶斯规则法函数trainbr
对Levenberg—Marquardt算法进行修改,以使网络的泛化能力更好,同时降低了确定最优网络结构的难度。
3.BP网络函数逼近实例
BP网络的功能之一即为函数逼近,对于BP网络而言一个重要结论为:三层或三层以上的BP网络可以逼近任何在闭区间内的一个连续函数,前提是隐含层的神经元个数可以随意调整。在进行BP网络设计前,一般应从网络的隐含层数、隐含层结点数、初始值以及学习方法等方面来进行考虑。下面结合MATLAB讨论一下相关的分析设计问题。
(1)隐含层数
一般认为,增加隐含层数可以降低网络误差,从而提高精度,但也使网络复杂化,从而增加了网络的训练时间和出现“过拟合”的可能性。Hornik等早已证明:若输入层和输出层采用线性转换函数,隐含层采用Sigmoid转换函数,则含一个隐含层的MLP网络能够以任意精度逼近任何有理函数。显然,这是一个存在性结论,在设计BP网络时可参考这一点,应优先考虑三层BP网络(即有一个隐含层)。一般地,靠增加隐含层节点数来获得较低的误差,其训练效果要比增加隐含层数更容易实现。对于没有隐含层的神经网络模型,实际上就是一个线性或非线性(取决于输出层采用线性或非线性转换函数形式)回归模型。因此,一般将不含隐含层的网络模型归入回归分析中,这里不再赘述。
(2)隐含层节点数
在BP网络中,隐含层节点数的选择非常重要,它不仅对建立的神经网络模型的性能影响很大,而且是训练时出现“过拟合”的直接原因,但是目前理论上还没有一种科学的确定方法。确定隐含层节点数的最基本原则是:在满足精度要求的前提下取尽可能紧凑的结构,即取尽可能少的隐含层节点数。研究表明,隐含层节点数不仅与输入/输出层的节点数有关,更与需解决的问题的复杂程度和转换函数的形式以及样本数据的特性等因素有关。在确定隐含层节点数时必须满足下列条件。
① 隐含层节点数必须小于 (其中N为训练样本数)。否则,网络模型的系统误差与训练样本的特性无关而趋于零,即建立的网络模型没有泛化能力,也没有任何实用价值。
② 训练样本数必须多于网络模型的连接权数,一般为2~10倍,否则,样本必须分成几部分并采用“轮流训练”的方法才可能得到可靠的神经网络模型。
(3)学习率和冲量系数
学习率影响学习过程的稳定性。大的学习率可能使网络权值每一次的修正量过大,甚至会导致权值在修正过程中超出某个误差的极小值,呈不规则跳跃而不收敛;但过小的学习率导致学习时间过长,不过能保证收敛于某个极小值。所以,一般倾向选取较小的学习率以保证学习过程的收敛性(稳定性),通常在0.01~0.8之间。
增加动量项的目的是为了避免网络训练陷于较浅的局部极小值。理论上其值大小应与权值修正量的大小有关,但实际应用中一般取常量。通常在0~1之间,而且一般比学习率要大。
(4)网络的初始连接权值
BP算法决定了误差函数一般存在多个局部极小点,不同的网络初始权值直接决定了BP算法收敛于哪个局部极小点或是全局极小点。因此,要求计算程序必须能够自由改变网络初始连接权值。由于Sigmoid转换函数的特性,一般要求初始权值分布在-0.5~0.5之间比较有效。
例子 设计一个简单的三层BP网络,实现对非线性正弦函数的逼近。
解:本例设计的三层BP网络结构如下图所示。
参数设置为:隐含层节点数为10,输出节点数为1,隐含层传递函数选取S型的正切函数tansig,输出层选取纯线性函数purelin。2016b中神经网络工具箱在net的layer属性中,设置每层的传递函数(Transfer Function),BP网络训练函数选取trainlm函数,使得训练速度尽可能快(注:如果计算机内存不够大,不建议采用trainlm函数,建议采用训练函数trainbfg或trainrp,以免出现死机情况,本例中计算机内存为8GB),正弦函数频率设置为1。其MATLAB程序代码如下。
clc
clear all
%下面两个参数值可变
k=1;%设置非线性函数的频率
n=10;%设置网络隐单元的神经元数目
%定义要逼近的非线性函数
P=[-1:0.05:1];%输入向量
T=sin(k*pi*P);%目标函数输出向量
plot(P,T,'-')
title('要逼近的非线性函数');
xlabel('输入向量');
ylabel('非线性函数目标输出向量');
%建立相应的BP网络
net=feedforwardnet(n,'trainlm');
net.layers{1}.transferFcn = 'tansig'; %把输入层之后的第1层(隐含层)的传递函数设置为tansig
net.layers{2}.transferFcn = 'purelin'; %把输入层之后的第2层(输出层)的传递函数设置为purelin
net=configure(net,P,T); %配置网络
%对没有训练的网络进行仿真
y1=sim(net,P);
%训练网络
net.trainParam.epochs=50;%训练次数最大值
net.trainParam.goal=0.01;%网络目标误差
net=train(net,P,T);
%对训练后的网络进行仿真
y2=sim(net,P);
%绘出训练前后的仿真结果对比
figure;
plot(P,T,'-',P,y1,'--',P,y2,'*')
title('训练前后的网络仿真结果对比');
xlabel('输入向量');
ylabel('输出向量');
legend('目标函数输出向量','未训练BP网络输出','已训练BP网络输出');
仿真结果图如图1所示,
(a)要逼近的非线性函数曲线
(b)训练后的网络输出及比较
图1 训练后的网络输出及与目标函数的对比
网路训练结果信息界面如图2所示。
图2 神经网络训练结果
由仿真结果图可以看出,未经训练的BP网络输出与目标函数差距很大,逼近效果很不理想,而对BP网络训练之后的输出可以较精确地逼近目标函数。神经网络训练结果信息界面可以直观的看到所创建的神经网络结构、所采用的训练函数、训练过程以及网络的性能。函数逼近效果、网络训练的收敛速度与原始非线性函数的频率、BP网络隐含层单元神经元的数目以及BP网络训练函数的选取都有关。观察它们对网络性能的影响发现,非线性函数的频率越高,对网络的要求也越高。而且并非网络隐含层单元神经元数目越多,逼近效果越好。
转载:https://blog.csdn.net/woai210shiyanshi/article/details/104675146