Advertisement

BP神经网络的设计实例(MATLAB编程)

阅读量:

该文本通过三个例子展示了如何利用BP网络解决实际问题。第一个例子展示了如何采用动量梯度下降算法训练BP网络,详细描述了训练样本定义、网络结构设置、训练参数配置以及训练结果分析。第二个例子探讨了使用贝叶斯正则化算法提高BP网络的推广能力,通过L-M优化算法和贝叶斯正则化算法对比,分析了不同算法在噪声数据下的表现。第三个例子介绍了“提前停止”方法在胆固醇含量预测中的应用,重点描述了数据预处理、样本划分、网络生成与训练过程,并分析了提前停止对模型推广能力的影响。三个例子均通过具体案例展示了BP网络在不同任务中的应用方法和效果。

基于动量梯度下降算法对BP神经网络进行训练。训练样本定义如下:输入矢量p定义为[-1 -2 3 1;-1 1 5 -3],目标矢量t定义为[-1 -1 1 1]。解:通过编写以下MATLAB代码可以实现

close all
clear
echo on
clc
% NEWFF——生成一个新的前向神经网络
% TRAIN——对 BP 神经网络进行训练
% SIM——对 BP 神经网络进行仿真
pause
% 敲任意键开始
clc
% 定义训练样本
% P 为输入矢量
P=[-1, -2, 3, 1; -1, 1, 5, -3];
% T 为目标矢量
T=[-1, -1, 1, 1];
pause;
clc
% 创建一个新的前向神经网络
net=newff(minmax(P),[3,1],{'tansig','purelin'},'traingdm')
% 当前输入层权值和阈值
inputWeights=net.IW{1,1}
inputbias=net.b{1}
% 当前网络层权值和阈值
layerWeights=net.LW{2,1}
layerbias=net.b{2}
pause
clc
% 设置训练参数
net.trainParam.show = 50;
net.trainParam.lr = 0.05;
net.trainParam.mc = 0.9;
net.trainParam.epochs = 1000;
net.trainParam.goal = 1e-3;
pause
clc
% 调用 TRAINGDM 算法训练 BP 网络
[net,tr]=train(net,P,T);
pause
clc
% 对 BP 网络进行仿真
A = sim(net,P)
% 计算仿真误差
E = T - A
MSE=mse(E)
pause
clc
echo off

通过贝叶斯正则化算法显著提升了 BP 神经网络的推广能力。在本例中,我们采用了 L-M 优化算法(trainlm)和贝叶斯正则化算法(trainbr)作为 BP 神经网络的训练方法。具体而言,输入矢量 P 由 [-1, -0.95, ..., 1] 组成,目标矢量 T 则由 sin(2πP) 加上 0.1 的高斯噪声生成。通过编写以下 MATLAB 程序,可以实现本例的求解过程:

生成一个新的前向神经网络模型
对BP神经网络进行训练
对BP神经网络进行仿真
敲任意键开始
清除窗口
定义训练样本矢量
P为输入矢量
T为目标矢量
设置训练样本输入范围
设置训练目标
绘制样本数据点
显示训练样本点
绘制不含噪声的正弦曲线
清除窗口
创建一个新的前向神经网络
设置网络结构
设置激活函数
设置训练算法
选择训练算法
初始化图形窗口
选择训练算法1
设置训练参数
重新初始化网络
选择训练算法2
设置训练参数
重新初始化网络
调用训练函数
显示训练结果
对网络进行仿真
计算仿真误差
计算均方误差
显示仿真结果
清除窗口
绘制匹配结果曲线
显示训练样本点
显示真实输出曲线
显示理论输出曲线
清除窗口

采用两种不同的训练算法进行训练后,我们获得了图1和图2所示的两种拟合结果。图中,实线表示拟合曲线,虚线代表不含白噪声的正弦曲线,"+"符号标记了含有白噪声的正弦样本数据点。显然,使用trainlm函数训练的神经网络对样本数据点实现了"过拟合",而使用trainbr函数训练的神经网络对噪声不敏感,具有较好的泛化能力。

值得指出的是,当BP网络的训练收敛时,使用trainbr函数通常会输出提示信息"Maximum MU reached"。此外,用户还可以通过观察SSE和SSW的变化情况来判断训练是否收敛:当SSE和SSW的值在经过若干步迭代后保持恒定时,通常说明网络已收敛,此时可以停止训练。通过观察trainbr函数训练BP网络的误差变化曲线,可以发现,当训练迭代至320步时,网络收敛,此时SSE和SSW保持恒定,当前有效网络的参数(包括有效权值和阈值)总数为11.7973。

针对与例2相同的问题,在此例中,我们采用训练函数 traingdx 与‘提前停止’相结合的方法,以增强 BP 神经网络的推广能力。

本例的MATLAB程序如下:

程序运行结果如图1所示。

训练后的仿真数据拟合曲线已得到,其效果令人满意。当训练达到第136步时,训练提前终止。此时网络的误差值为0.0102565。

例3 用BP网络估计胆固醇含量

在医疗领域,神经网络的应用为我们提供了一个创新的解决方案。我们开发了一种新型医疗设备,该设备通过分析血样光谱数据,准确测定血清胆固醇水平。针对261名患者,我们收集了包含21种不同波长光谱数据的样本。通过光谱分析,我们成功建立了hdl、ldl和vldl胆固醇水平的分类模型。

(1) 样本数据的定义与预处理。
choles_all.mat 文件中存储了网络训练所需要的全部样本数据。
利用 load 函数可以在工作空间中自动载入网络训练所需的输入数据 p 和目标数据 t,即
load choles_all
sizeofp = size (p)
sizeofp = 21 264
sizeoft = size (t)
sizeoft = 3 264
可见,样本集的大小为 264。为了提高神经网络的训练效率,通常要对样本数据作适当的预处理。首先,利用 prestd 函数对样本数据作归一化处理,使得归一化后的输入和目标数据均服从正态分布,即 [pn,meanp,stdp,tn,meant,stdt] = prestd(p,t);
然后,利用 prepca 函数对归一化后的样本数据进行主元分析,从而消除样本数据中的冗余成份,起到数据降维的目的。
[ptrans,transMat] = prepca(pn,0.001);
[R,Q] = size(ptrans)
R = 4 Q = 264
可见,主元分析之后的样本数据维数被大大降低,输入数据的维数由 21 变为 4。
(2) 对训练样本、验证样本和测试样本进行划分。
为了提高网络的推广能力和识别能力,训练中采用“提前停止”的方法,因此,在训练之前,需要将上面处理后的样本数据适当划分为训练样本集、验证样本集和测试样本集。
(3) 网络生成与训练。 选用两层 BP 网络,其中网络输入维数为 4,输出维数为 3,输出值即为血清胆固醇的三个指标值大小。网络中间层神经元数目预选为 5,传递函数类型选为 tansig 函数,输出层传递函数选为线性函数 purelin,训练函数设为 trainlm。网络的生成语句如下:
net = newff(minmax(ptr),[5 3],{'tansig' 'purelin'},'trainlm');
利用 train 函数对所生成的神经网络进行训练,训练结果如下:
[net,tr]=train(net,ptr,ttr,[],[],val,test);
见,网络训练迭代至第 20 步时提前停止,这是由于验证误差已经开始变大。利用下面语句可以绘制出训练误差、验证误差和测试误差的变化曲线,如图 4.50 所示。由图可见,验证误差和测试误差的变化趋势基本一致,说明样本集的划分基本合理。由训练误差曲线可见,训练误差结果也是比较满意的。
(4) 网络仿真。 为了进一步检验训练后网络的性能,下面对训练结果作进一步仿真分析。利用 postreg函数可以对网络仿真的输出结果和目标输出作线性回归分析,并得到两者的相关系数,从而可以作为网络训练结果优劣的判别依据。仿真与线性回归分析如下:
an = sim(net,ptrans);
a = poststd(an,meant,stdt);
for i=1:3
figure(i)
[m(i),b(i),r(i)] = postreg(a(i,:),t(i,:));
end

%导入原始测量数据
load choles_all;
%对原始数据进行规范化处理,prestd是对输入数据和输出数据进行规范化处理,
%prepca可以删除一些数据,适当地保留了变化不小于0.01的数据
[pn,meanp,stdp,tn,meant,stdt]=prestd(p,t);
[ptrans,transMat]=prepca(pn,0.001);
[R,Q]=size(ptrans)
%将原始数据分成几个部分作为不同用途四分已用于确证,四分一用于测试,二分一用于训练网络
iitst=2:4:Q;
iival=4:4:Q;
iitr=[1:4:Q 3:4:Q];
%vv是确证向量,.P是输入,.T是输出,vt是测试向量
vv.P=ptrans(:,iival);
vv.T=tn(:,iival);
vt.P=ptrans(:,iitst);
vt.T=tn(:,iitst);
ptr=ptrans(:,iitr);
ttr=tn(:,iitr);
%建立网络,隐层中设计5个神经元,由于需要得到的是3个目标,所以网络需要有3个输出
net=newff(minmax(ptr),[5 3],{'tansig' 'purelin'},'trainlm');
%训练网络
net.trainParam.show=5;
[net,tr]=train(net,ptr,ttr,[],[],vv,vt);
%绘出训练过程中各误差的变化曲线
plot(tr.epoch,tr.perf,'r',tr.epoch,tr.vperf,':g',tr.epoch,tr.tperf,'-.b');
legend('训练','确证','测试',-1);
ylabel('平方误差');
xlabel('时间');
pause;
%将所有数据通过网络(包括训练,确证,测试),然后得到网络输出和相应目标进行线性回归,
%对网络输出进行反规范化变换,并绘出个各级别的线性回归结果曲线
an=sim(net,ptrans);
a=poststd(an,meant,stdt);
%得到3组输出,所以进行3次线性回归
for i=1:3
figure(i)
[m(i),b(i),r(i)] = postreg(a(i,:),t(i,:));
end

对网络输出数据和目标数据进行线性回归分析后,前两个输出对目标的预测效果较好,其R值接近0.90。然而,第三个输出的预测效果并不理想,这可能需要我们在这点上进行更多改进。具体来说,可以考虑增加隐层神经元的数量,或者采用贝页斯规范的训练技术,同时结合早停法进行训练。

将隐层数目调整为20时,网络的三种误差值非常接近,相应的R值也有所提升。但需要注意的是,并非神经元数量越多越好。多层神经网络具有强大的逼近能力,其精度可以达到任意水平,但BP网络不一定能找到全局最优解。在训练过程中,学习速率过高可能导致网络不稳定,过低则会导致训练时间过长。此外,不同的训练算法对网络性能的影响也较大。值得注意的是,BP网络对隐层神经元的数量非常敏感,当隐层神经元数量不足时,网络可能无法有效学习;而当隐层神经元数量过多时,可能会导致过拟合现象。

出乎意料地超出预期的性能表现,我想这得益于其简洁的设计和直观的代码结构。

全部评论 (0)

还没有任何评论哟~