BP神经网络

【代码】BP神经网络-建模流程与代码(完整步骤)

作者 : 老饼 发表日期 : 2023-05-08 11:46:15 更新日期 : 2024-12-08 03:07:46
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》www.bbbdata.com



在BP神经网络的实际建模中,往往需要比较细致地处理数据,以及打印评估指标

本文讲解BP神经网络的完整建模流程步骤,包括数据预处理、训练、评估等,并展示一个具体的例子

通过本文,可以了解BP神经网络的建模需要哪些步骤、各个步骤的具体操作,以及matlab具体代码实现






  01. BP神经网络建模-完整步骤  



本节讲解BP神经网络建模的标准完整步骤,和每个步骤的内容



     BP神经网络建模-完整步骤    


BP神经网络的建模流程主要步骤如下:
 
BP神经网络的建模流程
总的来说,主流程共有3个大步骤,6个小步骤,如下
 👉 数据预处理 :数据归一化、数据划分                 
👉 网络构建 :
网络结构设置、网络训练                
👉 效果评估 :
模型训练效果评估、模型预测效果评估




     BP神经网络建模-完整步骤-详述    


BP神经网络建模完整的各个步骤细节如下:
  步骤一、BP神经网络数据预处理 
 1.1. 数据归一化                                                                                         
在模型训练之前,需要把所有数据(X和y)都进行归一化                          
 其中,归一化公式如下:
 
 是原始数据,是归一化后的数据
 1.2. 数据划分                                                            
 
 一般将数据划分成三部分,训练数据、验证数据、检验数据                    
可以按训练数据70%、验证数据15%、检验数据15%的比例随机分割    
每份数据的作用如下:

 训练数据:用于求解(调整w,b)                                                             
 验证数据:验证数据主要用于防止训练走向过拟合                                
 测试数据:不参与任何训练过程,纯粹用于检验模型最后的测试效果     

 步骤二、BP神经网络构建
  2.1. BP神经网络结构设置                                                                          
设置BP神经网络隐层层数(一般都是一个隐层),和隐层神经元个数     

 2.2. BP神经网络训练(求解w,b)                                                              
用训练数据对BP神经网络进行训练,可采用梯度下降法、LM法等等      
在训练过程中,需要不断用验证数据检验模型的泛化能力                      
                       如果训练数据效果越来越好,而验证数据越来越差,则说明开始过拟合了,就停止训练 

 
步骤三、BP神经网络效果评估
 3.1. 模型训练效果评估                                                                              
检验模型对训练数据的预测效果                                                         
 一个BP神经网络训练成功的表现就是训练数据误差达到要求                
 3.2. 模型预测效果评估                                                                              
检验模型对检验数据(未参与训练的数据)的预测效果                       
 一个BP神经网络可用的表现就是模型测试数据误差达到要求               
  模型的评估指标,一般依据实际问题进行设计                      
 对于数值问题,可以使用平均绝对误差MAE,如下:                  
 

 其中
是BP神经网络对样本的预测值
总的来说,先将数据归一化,然后划分为训练数据、验证数据和测试数据
再设置好网络,将训练数据投到网络中训练权重阈值,并用验证数据预防过拟合
最后,检查BP神经网络的训练误差,并用测试数据评估模型的预测能力









    02. BP神经网络建模-完整步骤-代码实现    





本节展示BP神经网络建模的完整代码,以供使用时进行借鉴与复制





     BP神经网络建模代码-具体代码     


本文展现一个按照标准建模流程来实现BP神经网络的DEMO,
包含归一化、训练与测试数据分割、BP网络设置与训练、
训练结果与测试结果展示、模型的使用、提取数学公式等
 在实际建模中,复制该代码进行修改即可,代码较为全面,可依需要进行删减
本例从  中采取100个样本,
利用生成的100个样本建立BP神经网络,然后与原函数进行比较
 步骤包括如下:
 👉 数据 (0)  数据生成                                        
 👉 建模 (1)  数据归一化                                     
(2)  训练测试数据分割            
(3)  网络设置                          
(4)  网络训练                          
(5)  展示训练结果                   
(6)  测试数据的预测结果         
 👉 应用 (7)  模型的使用                                     
(8)  提取模型的表达式            
 具体代码实现如下:
% 本代码是matlab工具箱训练BP神经网络的完整实际使用代码,包括了归一化、训练、测试与提取模型表达式等内容
% 本代码旨在学习与平时使用时方便copy使用(笔者测试代码的版本:matlab2018a)
%  转载请说明来自 《老饼讲解神经网络》 www.bbbdata.com
clear all;close all ;
setdemorandstream(888);                                                   % 随机种子,实际使用时应该去掉
%------------------原始数据---------------------
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
							                                 
%-------数据预处理:预留检验数据与数据归一化------           
randIndex  = randperm(100);                                  
trainIndex = sort(randIndex(1:80));                                       % 随机选出80个数据作为训练数据(这里先选出数据的序号)
testIndex  = sort(randIndex(81:100));                                     % 将剩下的20个数据作为检验数据(这里先选出数据的序号)

%由于需要归一化,先将归一化信息抓取出来
%(这里获取训练数据的最大最小值,因为只有训练数据投到网络中进行)
iMax = max(X(:,trainIndex),[],2);                                         % 训练数据X的最大值
iMin = min(X(:,trainIndex),[],2);                                         % 训练数据X的最小值
oMax = max(y(:,trainIndex),[],2);                                         % 训练数据Y的最大值
oMin = min(y(:,trainIndex),[],2);                                         % 训练数据Y的最小值

%对数据进行归一化
normX=2*(X -repmat(iMin,1,size(X,2)))./repmat(iMax-iMin,1,size(X,2)) -1;  % 对X归一化
normY=2*(y -repmat(oMin,1,size(y,2)))./repmat(oMax-oMin,1,size(y,2)) -1;  % 对y归一化

% 从归一化后的数据中抽出训练数据与测试数据
X_train  = normX(:,trainIndex);                                           % 根据序号选出80个用于训练的输入
X_test   = normX(:,testIndex);                                            % 根据序号选出20个用于检验的输入
y_train  = normY(:,trainIndex);                                           % 根据序号选出80个用于训练的输出
t_test   = normY(:,testIndex);                                            % 根据序号选出20个用于检验的输出

%----------------网络训练 ---------------------
%使用用输入输出数据(X_train、y_train)建立网络,
%隐节点个数3,隐层、输出层的激活函数为tansig和purelin,方法训练为trainlm
net = newff(X_train,y_train,3,{'tansig','purelin'},'trainlm');           % 初始化BP神经网络

%设置一些常用参数
net.trainparam.goal        = 0.00001;                                    % 训练目标:均方误差低于0.0001
net.trainparam.show        = 400;                                        % 每训练400次展示一次结果
net.trainparam.epochs      = 15000;                                      % 最大训练次数:15000.
net.divideParam.trainRatio = 0.85;                                       % 用于训练的数据比例
net.divideParam.valRatio   = 0.15 ;                                      % 用于验证过拟合的数据比例
net.divideParam.testRatio  = 0;                                          % 注意要关掉测试数据占比
[net,tr] = train(net,X_train,y_train);                                   % 训练模型

%----------训练数据的拟合效果----------------
figure;
%训练数据的拟合效果
simout_train = sim(net,X_train);                                         % 训练数据的预测值
subplot(2,1,1);                                                          % 第一个子图
title('训练数据的拟合效果')                                              % 标题
hold on                                                                  % hold on 
t= 1 : length(simout_train);                                             % 序号
plot(t,y_train,t,simout_train,'r')                                       % 画图,对比原来的y和网络预测的y
										                                
%检验数据的拟合效果                                                     
simout_test = sim(net,X_test);                                           % 测试数据的预测值
subplot(2,1,2);                                                          % 第二个子图
title('未训练数据的拟合效果')                                            % 标题
hold on                                                                  % hold on 
t = 1:length(simout_test);                                               % 序号
plot(t,t_test,t,simout_test,'r')                                         % 画图,对比原来的y和网络预测的y

% 打印mae指标
mae_train = mean(abs(y_train -simout_train))                             % 训练数据的MAE
mae_test  = mean(abs(t_test -simout_test))                               % 预测数据的MAE

%----------真正使用时的流程--------------------
X        = [-2.9;-1.9];                                                  % 要预测的X
normX    = 2*(X -iMin)./(iMax-iMin) -1;                                  % 对X归一化
normSimY = sim(net,normX);                                               % 用网络预测
simy     = (normSimY+1).*(oMax-oMin)./2 + oMin;                          % 对结果反归一


%-----------提取表达式(对应归一化数据)----
%提取权重
w12 = net.iw{1,1};                                                       % 第1层(输入层)到第2层(隐层)的权值
b2 = net.b{1};                                                           % 第2层(隐层)的神经元阈值
w23 = net.lw{2,1};                                                       % 第2层(输入层)到第3层(输出层)的权值
b3 = net.b{2};                                                           % 第3层(输出层)的神经元阈值
%对应的数学表达式(输入和输出都是归一化后的数据):
sim_y_norm = w23 *tansig( w12 *normX + repmat(b2,1,size(normX,2))) + repmat(b3,1,size(normX,2));
代码运行结果如下:
 
BP神经网络的建模代码运行结果 





    答疑:关于为什么要将数据进行归一化    


有小伙伴提问,为什么工具箱明明归一化了,本篇代码为什么还要进行归一化呢?
说来都是泪,这纯粹出于matlab工具箱的BUG,如下:
matlab工具箱虽然对y作了归一化,但在训练时,计算梯度使用的误差并没有使用归一化后的误差
它引用的是原始y的误差,如此一来,如果y数量级很大,梯度的步幅就会很大,从而影响了训练效果

总的来说,一般不需要自行作归一化
但如果y的数值很大(也不用很大,例如100,就已经是1的100倍了),最好还是做一下归一化
 其实只需要对y进行归一化就能消除这个BUG,本文干脆把X,Y都归一化算了,无他





好了,关于BP神经网络的建模完整代码实现就到这里了~







 End 





联系老饼