原文来自 老饼玩转-BP神经网络https://www.bbbdata.com/nn
目录
本文介绍在matlab神经网络工具箱(2012b以后)的建模方式和DEMO代码。
新的matlab神经网络工具箱训练BP神经网络模流程只需要三个步骤,这有区别于老方式。
一、建模的步骤
1、设置神经网络及参数
主要是设置隐层节点数、训练步数等。
2、将所有数据投入训练
工具自动将数据分割为三份(训练,验证和测试,默认70%,15%,15%),训练数据用于训练,验证数据在训练过程中检验是否过拟合,测试数据留给用户自行测试。
PASS:数据不需要归一化,工具箱会自动归一化
3、查看结果
从工具箱的训练结果中抽出训练数据和测试数据,检验两者的结果。
PASS:网上很多代码仍然在使用归一化、自留检测数据的方式,主要是跟了旧版本的教材。2012前,神经网络工具箱没有这么自动化。
二、建模代码
matlab版本为2014b,代码如下:
clear all;
close all ;
%================原始数据====================
x1 = linspace(-3,3,100); % 在[-3,3]之间线性生成100个数据
x2 = linspace(-2,1.5,100); % 在[-2,1.5]之间线性生成100个数据
X = [x1;x2]; % 将x1,x2作为输入数据
y = 10*sin(x1)+0.2*x2.*x2; % 生成y
setdemorandstream(88); % 老饼为了每次运行的结果一致设定随机种子,实际中可以去掉
%==============网络训练 ============================
%使用用输入输出数据(X,y)建立网络,
%隐节点个数设为3.其中输入层到隐层、隐层到输出层的节点分别为tansig和purelin,使用trainlm方法训练。
net = newff(X,y,3,{'tansig','purelin'},'trainlm');
%设置一些常用关键参数
net.trainparam.goal = 0.00001; % 训练目标:均方误差低于0.0001
net.trainparam.show = 400; % 每训练400次展示一次结果
net.trainparam.epochs = 15000; % 最大训练次数:15000.
net.divideParam.trainRatio=0.7; % 用于训练的数据比例
net.divideParam.valRatio=0.15 ; % 用于验证过拟合的数据比例
net.divideParam.testRatio=0.15; % 用于比例
net.trainparam.max_fail =6; % 过拟合验证失败次数
[net,tr,net_y] = train(net,X,y); % 调用matlab神经网络工具箱自带的train函数训练网络y,net返回
% ===========画图==================================
figure
subplot(2,1,1);
title('训练数据的拟合效果')
hold on
plot(1:length(tr.trainInd),y(tr.trainInd),'b')
plot(1:length(tr.trainInd),net_y(tr.trainInd),'r')
subplot(2,1,2);
title('测试数据的拟合效果')
hold on
plot(1:length(tr.testInd),y(tr.testInd),'b')
plot(1:length(tr.testInd),net_y(tr.testInd),'r')
%=============网络对新输入的使用==========================
sim_y = sim(net,X); % 实际与上面的net_y一致
三、模型的提取流程
训练完后,如果需要提取权重和阈值,则也需要三个步骤:
1、提取网络的权重阈值WB
2、提取网络的输入输出阈值
3、将网络的权重阈值反归一化
四、模型提取的代码
模型提取代码如下(代码续训练代码):
% %----------------------提取表达式(对应归一化数据)------------------------------------
% 提取权重WB
w12 = net.iw{1,1}; % 第1层(输入层)到第2层(隐层)的权值
b2 = net.b{1}; % 第2层(隐层)的神经元阈值
w23 = net.lw{2,1}; % 第2层(输入层)到第3层(输出层)的权值
b3 = net.b{2}; % 第3层(输出层)的神经元阈值
% 提取输入输出范围
iMin = net.inputs{1}.range(:,1);
iMax = net.inputs{1}.range(:,2);
oMin = net.outputs{2}.range(:,1);
oMax = net.outputs{2}.range(:,2);
% 将网络的WB反归一化
W12 = w12 * 2 ./repmat(iMax' -iMin',size(w12,1),1);
B2 = -w12* (2*iMin ./(iMax - iMin) + 1) + b2;
W23 = w23 .*repmat((oMax -oMin),1,size(w23,2))/2;
B3 = (oMax -oMin) .*b3 /2 + (oMax -oMin)/2 + oMin;
% 最后的验证按表达式计算与用工具箱计算的差异
formula_sim_y = W23*tansig( W12 *X + repmat(B2,1,size(X,2))) + repmat(B3,1,size(X,2));
formula_err = max(max(abs(formula_sim_y - sim_y)));
五、一些个性化操作
1、自留测试数据
如果需要自己留测试数据,则自留测试数据,再把其余数据投入网络训练,并把测试占比改为0,训练与检验占比和改为1即可:
net.divideParam.trainRatio=0.85; % 用于训练的数据比例
net.divideParam.valRatio=0.15 ; % 用于验证过拟合的数据比例
net.divideParam.testRatio=0; % 用于比例
这样需要自己把测试数据投入sim函数中获取预测结果。
2、不作泛化检验
net.divideParam.trainRatio=0.85; % 用于训练的数据比例
net.divideParam.valRatio=0 ; % 用于验证过拟合的数据比例
net.divideParam.testRatio=0.15; % 用于比例
相关文章