神经网络-专题教程

【代码】梯度下降法实现BP神经网络-代码

作者 : 老饼 发表日期 : 2022-10-25 15:44:38 更新日期 : 2024-11-12 18:46:22
本站原创文章,转载请说明来自《老饼讲解-BP神经网络》www.bbbdata.com



梯度下降法是BP神经网络的一个基础训练算法,也是用于学习的基本例子

本文展示一个梯度下降法求解BP神经网络的例子,以及具体的实现matlab代码

通过本文可以了解梯度下降法是如何训练BP神经网络的,以及如何用matlab自实现BP神经网络





  01. 梯度下降法求解BP神经网络-例子  




本节展示一个梯度下降法求解BP神经网络的例子




   问题描述    


现有如下数据: 
 
BP神经网络自实现-数据
y实际是由 生成
现在需要利用数据训练一个BP神经网络,对其进行拟合,
并测试网络的预测结果与真实结果  的差异





   设置BP神经网络结构   


对于本问题,我们采用三层结构,其中隐层包含3个隐神经元
隐层激活函数为tansig,输出层激活函数为purelin的结构
 则对应的神经网络拓扑结构如下:
  BP神经网络拓扑结构
 它的模型数学表达式为: 
 BP神经网络数学表达式





   BP神经网络训练   


下面采用梯度下降法对BP神经网络进行训练
 
算法流程如下:
 先初始化W,b,
(1) 按照梯度公式算出梯度
(2) 将W往负梯度方向调整
不断循环(1)和(2),直到达到终止条件(例如达到最大迭代次数,或误差足够小)
其中,三层BP神经网络梯度公式如下:
一、输出层梯度公式                                                                              
  输出层权重梯度:             
 输出层阈值梯度:                  
二、隐层梯度公式                                                                                 
                   隐层权重梯度:   
                      隐层阈值梯度:             
符号说明:
 
为样本个数、输出个数                               
 
是第m个样本第k个输出的误差         
 
是第m个样本第j个隐节点的激活值          
 
是第m个样本第i个输入                                 






  02. 梯度下降法求解BP神经网络-代码实现  




本节展示如何用代码实现梯度下降法求解BP神经网络





   梯度下降法求解BP神经网络-代码实现   


下面是 梯度下降法 求解 BP神经网络 的代码实现
具体代码实现如下:
% 本代码展示梯度下降法求解BP神经网络(笔者测试代码的版本:matlab2018a)
% 本代码来自《老饼讲解神经网络》 www.bbbdata.com
close all;clear all;
%-----------数据----------------------
x1 = [-3,-2.7,-2.4,-2.1,-1.8,-1.5,-1.2,-0.9,-0.6,-0.3,0,0.3,0.6,0.9,1.2,1.5,1.8];   % x1:x1 = -3:0.3:2;
x2 = [-2,-1.8,-1.6,-1.4,-1.2,-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1,1.2];       % x2:x2 = -2:0.2:1.2;
X  = [x1;x2];                                                                       % 将x1,x2作为输入数据
y  = [0.6589,0.2206,-0.1635,-0.4712,-0.6858,-0.7975,-0.8040,...
    -0.7113,-0.5326,-0.2875 ,0,0.3035,0.5966,0.8553,1.0600,1.1975,1.2618];          % y: y = sin(x1)+0.2*x2.*x2;

%--------参数设置与常量计算------------
setdemorandstream(88);                                                               % 设置随机种子
hide_num = 3;                                                                        % 隐节点个数
lr = 0.05;                                                                           % 学习率
[in_num,sample_num] = size(X);                                                       % 输入个数与样本个数
[out_num,~] =  size(y);                                                              % 输出个数

%--------初始化w,b和预测结果-----------
w32 = rand(out_num,hide_num);                                                        % 隐层到输出层的权重 
b3  = rand(out_num,1);                                                               % 输出层阈值
w21 = rand(hide_num,in_num);                                                         % 输入层到隐层权重
b2  = rand(hide_num,1);                                                              % 隐层阈值
simy = w32*tansig(w21*X+repmat(b2,1,size(X,2)))+repmat(b3,1,size(X,2));              % 预测结果
mse_record = [sum(sum((simy - y ).^2))/(sample_num*out_num)];                        % 预测误差记录
																	                 
% ---------用梯度下降训练---------------                                        
for i = 1:5000                                                                       
    %计算梯度                                                                        
    hide_Ac = tansig(w21*X+repmat(b2,1,sample_num));                                 % 隐节点激活值
    dNo     = 2*(simy - y )/(sample_num*out_num);                                    % 输出层节点梯度
    dw32    = dNo*hide_Ac';                                                          % 隐层-输出层权重梯度
    db3     = sum(dNo,2);                                                            % 输出层阈值梯度
													                                 
    dNh     = (w32'*dNo).*(1-hide_Ac.^2);                                            % 隐层节点梯度
    dw21    = dNh*X';                                                                % 输入层-隐层权重梯度
    db2     = sum(dNh,2);                                                            % 隐层阈值梯度
													                                 
    %往负梯度更新w,b                                                                 
    w32 = w32 - lr*dw32;                                                             % 更新隐层-输出层权重 
    b3  = b3  - lr*db3;                                                              % 更新输出层阈值
    w21 = w21 - lr*dw21;                                                             % 更新输入层-隐层权重 
    b2  = b2  - lr*db2;                                                              % 更新隐层阈值
    
    % 计算网络预测结果与记录误差
    simy = w32*tansig(w21*X+repmat(b2,1,size(X,2)))+repmat(b3,1,size(X,2));          % 计算输出
    mse_record =[mse_record, sum(sum((simy - y ).^2))/(sample_num*out_num)];         % 记录误差
end

% --------绘制训练结果与打印模型参数--------               
h = figure;                                                                          % 初始化画布
subplot(1,2,1)                                                                       % 第一个子图
plot(mse_record)                                                                     % 绘画误差曲线
subplot(1,2,2)                                                                       % 第二个子图
plot(1:sample_num,y);                                                                % 绘画真实值
hold on                                                                              % hold on
plot(1:sample_num,simy,'-r');                                                        % 绘画预测值
set(h,'units','normalized','position',[0.1 0.1 0.8 0.5]);                            % 设置图像位置
%--模型参数--                                                                       
w32                                                                                  % 隐层到输出层的权重 
b3                                                                                   % 输出层阈值
w21                                                                                  % 输入层到隐层权重
b2                                                                                   % 隐层阈值
代码运行结果如下:
 
训练误差曲线和模型的拟合效果:
 自实现BP神经网络的代码运行结果
 训练好的模型参数: 
 
训练好的BP神经网络参数 
 将参数代回三层BP神经网络的模型表达式,即可得到模型为:
     







  03. BP神经网络-模型效果检验  




下面测试构建好的BP神经网络的实际预测效果 





   BP神经网络的预测结果和真实结果    


不妨将  作为测试数据,此时真实输出为:
     
将它代入上述训练的BP神经网络,预测结果如下:
 
 
网络的预测值0.6610与真实值0.5294 误差0.1316
这个误差不算太大,但也不算小
  整体来说,训练的BP神经网络模型已具有一定的效果,说明算法是可行的
 PASS:为什么训练数据这么好,而预测值仍然有这么大的差距?
读者们能想明白吗?能改善吗?要怎么才能改善?






好了,以上就是梯度下降法训练BP神经网络的全部内容了~








 End 




联系老饼