BP神经网络+matlab实例分析
问题描述
辛烷值是汽油最重要的品质指标,传统的实验室检测方法存在样品用量大、测试周期长和费用高等问题,不适用与生产控制,特别是在线测试,今年发展起来的近红外光谱分析方法(NIR),作为一种快速分析方法,已经广泛应用于农业、制药、生物化工、石油产品等领域。其优越性是无损检测、低成本、无污染、能在线分析,更适合于生产和控制的需要。
针对采集得到的60组汽油样品,利用傅立叶近红外变换光谱仪对其扫描,扫描范围为900~1700nm,扫描间隔为2nm,每个样品的光谱曲线共含有401个波长点。同时,利用传统实验室检测方法测定其辛烷值含量。
要求
要求利用BP神经网络建立汽油样品近红外光谱与其辛烷值之间的关系的数学模型,并对模型的性能进行评价。
%% I. 清空环境变量
clear all
clc
%% II. 训练集/测试集产生
%%
% 1. 导入数据
load spectra_data.mat
%%
% 2. 随机产生训练集和测试集
temp = randperm(size(NIR,1));%size(a,1)行数,size(aa,2)列数产生1:60随机数列
% 训练集——50个样本
P_train = NIR(temp(1:50),:)';%单引号矩阵转置,50组随机数据,列50行401
T_train = octane(temp(1:50),:)';
% 测试集——10个样本
P_test = NIR(temp(51:end),:)';
T_test = octane(temp(51:end),:)';
N = size(P_test,2);%=10,列数,10组数据
%% III. 数据归一化
[p_train, ps_input] = mapminmax(P_train,0,1);%归一化训练数据,线性?
p_test = mapminmax('apply',P_test,ps_input);%测试数据同样规则归一化
[t_train, ps_output] = mapminmax(T_train,0,1);
%% IV. BP神经网络创建、训练及仿真测试
%%
% 1. 创建网络
net = newff(p_train,t_train,9);
%P:输入参数矩阵。(RxQ1),其中Q1代表R元的输入向量。
%S:N-1个隐含层的数目(S(i)到S(N-1)
%%
% 2. 设置训练参数
net.trainParam.epochs = 1000;% 训练次数
net.trainParam.goal = 1e-3;%训练目标最小误差
net.trainParam.lr = 0.01;%学习率
%%
% 3. 训练网络
net = train(net,p_train,t_train);
%%
% 4. 仿真测试
t_sim = sim(net,p_test);
%%
% 5. 数据反归一化
T_sim = mapminmax('reverse',t_sim,ps_output);
%% V. 性能评价
%%
% 1. 相对误差error
error = abs(T_sim - T_test)./T_test;
%%
% 2. 决定系数R^2
R2 = (N * sum(T_sim .* T_test) - sum(T_sim) * sum(T_test))^2 / ((N * sum((T_sim).^2) - (sum(T_sim))^2) * (N * sum((T_test).^2) - (sum(T_test))^2));
%%
% 3. 结果对比
result = [T_test' T_sim' error']
%% VI. 绘图
figure
plot(1:N,T_test,'b:*',1:N,T_sim,'r-o')
legend('真实值','预测值')
xlabel('预测样本')
ylabel('辛烷值')
string = {'测试集辛烷值含量预测结果对比';['R^2=' num2str(R2)]};
title(string)
这个实验全名叫《基于近红外光谱的汽油辛烷值预测》, 并非我的原创, 网上应该可以找到相关资料。抱歉长时间没上号才发现有人想要数据文件, 链接如下:
hi,这是我用百度网盘分享的文件~复制这段内容打开「百度网盘」APP即可获取。
链接:https://pan.baidu.com/s/1xqKg4KcRIxMWB9ez6uhBUA
提取码:i8sR
BP(Back Propagation)神经网络的学习过程由信号的正向传播与误差的反向传播两个过程组成。
正向传播时,输入样本从输入层传入,经隐层逐层处理后,传向输出层。若输出层的实际输出与期望输出不符,则转向误差的反向传播阶段。
误差的反向传播是将输出误差以某种形式通过隐层向输入层逐层反传,并将误差分摊给各层的所有单元,从而获得各层单元的误差信号,此误差信号即作为修正各单元权值的依据。
创建BP神经网络需要确定网络的结构,即需要确定以下几个参数:输入变量个数、隐函数层数及个层神经元个数、输出变量个数和训练参数。
训练样本数:隐层节点数必须小于N-1(其中N为训练样本数),否则,网络模型的系统误差与训练样本的特性无关而趋于零,即建立的网络模型没有泛化能力,也没有任何实用价值。一般认为,训练集样本数量占总体样本数量的2/33/4为宜,剩余的1/41/3作为测试集样本。同时,尽量使得训练集与测试集样本的分布规律近似相同。
**输入层节点数n: **取决于样本的属性个数
**输出层节点数l: **取决于预测的节点数
隐含层层数、节点数:
一般认为,增加隐藏层数可以降低网络误差,提高精度,但也使网络复杂化,从而增加了网络训练时间和出现过拟合的倾向。一般情况,应该考虑3层BP网络(即1个隐含层),靠增加隐含层节点数来获取较低的误差(这种训练效果要比增加隐含层数更容易实现)。如果数目太少,网络将不能建立复杂的判断界,训练不出合适的网络,不能识别以前没有看过的样本,容错性差,但数目过大,就会使训练时间过长,网络的泛化能力降低,而且误差也不一定最佳,因此存在一个最佳的隐藏层节点数.确定隐含层节点数的基本原则使:在满足精度的前提下,取尽可能紧凑的结构,即取尽可能少的隐含层节点数。
隐含层节点数必须小于N-1(N是训练样本数),否则网络模型的系统误差与训练样本的特性无关而趋于0,即建立的网络模型没有泛化能力,也没有任何使用价值,同理,输入层的节点数也必须小于N-1;
隐藏层节点数m(有三种确定方法)(n输入层节点数,l为输出层节点数):
①,其中为1-10之间的常数
②
③
相关训练参数:
迭代次数 一般取1000次。由于神经网络计算并不能保证在各种参数配置下迭代结果收敛,当迭代结果不收敛时,允许最大的迭代次数。
允许误差: 一般取0.001~0.00001,当2次迭代结果的误差小于该值时,系统结束迭代计算,给出结果。
学习率(最小训练速率 ):在经典的BP算法中,训练速率是由经验确定,训练速率越大,权重变化越大,收敛越快;但训练速率过大,会引起系统的振荡,因此,训练速率在不导致振荡前提下,越大越好。
60个样品的光谱及辛烷值数据保存在spectra_data.mat文件中,该文件包含两个变量矩阵:NIR为60行401列的样品光谱数据,octane为60行1列的辛烷值数据。这里采用随机法产生训练集和测试集,随机产生50个样品作为训练集,剩余的10个样品作为测试集。
初始设定bp网络为三层,1输入层,1隐含层,1输出层。隐含层参数个数根据公式暂定为8。
最大迭代次数取1000,允许误差取0.001,学习率暂定0.9
模型建立后,将测试集的输入变量送入模型,模型的输出就是对应的预测结果。
通过计算测试集预测值与真实值间的误差,可以对模型的泛化能力进行评价。在此基础上,可以进行进一步的研究和改善。
相对误差越小,表明模型的性能越好。决定系数范围在[0,1]内,越接近于1,表明模型的拟合性能越好,反之,越趋近于0,表明模型的拟合性能越差。
首先应该根据机理确定激活函数的种类,之后确定代价函数种类和权重初始化的方法,以及输出层的编码方式;
其次根据“宽泛策略”先大致搭建一个简单的结构,确定神经网络中隐层的数目以及每一个隐层中神经元的个数;然后对于剩下的超参数先随机给一个可能的值,在代价函数中先不考虑正则项的存在,调整学习率得到一个较为合适的学习率的阈值,取阈值的一半作为调整学习率过程中的初始值 ;
之后通过实验确定minibatch的大小;
之后仔细调整学习率,使用确定出来的 η,用验证数据来选择好的 λ ,搞定 λ 后,重新优化 η。
而学习回合数可以通过上述这些实验进行一个整体的观察再确定。