反向传播BP思路梳理

学了用了好多神经网络,我却一直没有搞明白神经网络里的反向传播BP是怎么回事。其实具体的公式推导网上有很多资料,都很详细,但是对于数学差劲的我来说每次得看半天才能懂个大概,而且过段时间就忘的一干二净。这次终于下决心要好好理解一下这个东西。

要想学习一个算法,严谨的数学推导固然重要,但最好的办法还是搞清楚它运作的机理,即为什么通过这个方法就可以达到目的?算法中每一个操作的物理意义是什么?搞清楚这些问题后,即使具体的数学推导和证明依然晦涩难懂,但我们却可以把握算法的核心思想,对其有一个直观的理解。本文尽量避免数学推导,希望能以简单直观的方式梳理反向传播的思路。

反向传播是什么?

简单来说,反向传播就是一个利用链式法则,由外而内逐层计算最终输出对每层的变量的梯度的简便算法。该算法在神经网络中得以普遍应用,因为在神经网络中这样由外而内计算梯度的顺序是从输出层到输入层反向进行的,所以形象地被称为反向传播。

为什么要用反向传播?

要回答这个问题,首先我们来回顾一下我们是如何训练神经网络的。

怎么训练神经网络呢?
通过优化一个损失函数loss,使其数值越来越小,那么我们的网络的性能就会越来越好。

怎么改变loss的数值呢?
通过改变我们网络每一层的参数,就能改变网络的输出,进而就可以改变loss的值。

怎么改变参数才能使loss的数值变小呢?
计算loss对每层参数的梯度,每层参数都向loss对其的负梯度方略微改变,只要当前的loss不处于局部最小值且改变的幅度得当,这种操作一般是能够使loss减小的,这便是梯度下降GD的核心思想。

那怎么计算loss对每层参数的梯度呢?
看看上个问题里写的反向传播的定义,知道为什么要用反向传播了吧。在这里,最终输出即是loss,每层的变量即是每层的参数。

反向传播的机理是什么?

关于反向传播的机理,网上有很多资料都写的非常详细,各种推导证明十分严谨,是深入理解反向传播的最佳教材。在这里,我不想班门弄斧,再重新推导一遍这些公式;而是想以不那么严谨但是直观的方法,了解一下反向传播它究竟做了什么,每一步计算需要用到什么,诸如此类的东西。

首先我们说:反向传播到底传什么?你可能会问:刚刚不是才说了反向传播传的是loss对每层参数的梯度吗,为什么又要问一遍?没错,这就是标准答案,但是我觉得这个答案不够形象。接下来完全以我的个人理解,用不太严谨的思路,将反向传播的过程拆成两个部分:计算loss对每层输出的梯度计算每层的输出对其参数的梯度,可以把计算loss对每层输出的梯度看做反向传播路径的主干,而把计算每层的输出对其参数的梯度看做主干在每一层上的分支。我在这里仅仅是为了提醒自己,写一些直观的理解,详细的公式推导可参看参考资料,写的非常好。

简单起见,假定我们有一个不使用激活函数的MLP网络,输出层为第LLL层,每一层的输出为ziz^izi。反向传播的目标是求出损失JJJ对于每一层的权重WiW^iWi和偏置bib^ibi的梯度∂J∂Wi\frac{\partial J}{\partial W^i}∂Wi∂J​和∂J∂bi\frac{\partial J}{\partial b^i}∂bi∂J​。利用链式求导法则,有

∂J∂Wi=∂J∂zi⋅∂zi∂Wi=∂J∂zL⋅∂zL∂zL−1⋅⋯⋅∂zi+1∂zi⋅∂zi∂Wi=(∂J∂zL⋅∂zL∂zL−1⋅⋯⋅∂zi+1∂zi)⋅∂zi∂Wi\frac{\partial J}{\partial W^i} = \frac{\partial J}{\partial z^i}\cdot \frac{\partial z^i}{\partial W^i} = \frac{\partial J}{\partial z^L} \cdot \frac{\partial z^L}{\partial z^{L-1}} \cdot \cdots \cdot \frac{\partial z^{i+1}}{\partial z^i} \cdot \frac{\partial z_i}{\partial W_i} = \left ( \frac{\partial J}{\partial z^L} \cdot \frac{\partial z^L}{\partial z^{L-1}} \cdot \cdots \cdot \frac{\partial z^{i+1}}{\partial z^i} \right ) \cdot \frac{\partial z_i}{\partial W_i}∂Wi∂J​=∂zi∂J​⋅∂Wi∂zi​=∂zL∂J​⋅∂zL−1∂zL​⋅⋯⋅∂zi∂zi+1​⋅∂Wi​∂zi​​=(∂zL∂J​⋅∂zL−1∂zL​⋅⋯⋅∂zi∂zi+1​)⋅∂Wi​∂zi​​,

同理,

∂J∂bi=∂J∂zi⋅∂zi∂bi=∂J∂zL⋅∂zL∂zL−1⋅⋯⋅∂zi+1∂zi⋅∂zi∂bi=(∂J∂zL⋅∂zL∂zL−1⋅⋯⋅∂zi+1∂zi)⋅∂zi∂bi\frac{\partial J}{\partial b^i} = \frac{\partial J}{\partial z^i}\cdot \frac{\partial z^i}{\partial b^i} = \frac{\partial J}{\partial z^L} \cdot \frac{\partial z^L}{\partial z^{L-1}} \cdot \cdots \cdot \frac{\partial z^{i+1}}{\partial z^i} \cdot \frac{\partial z_i}{\partial b_i} = \left ( \frac{\partial J}{\partial z^L} \cdot \frac{\partial z^L}{\partial z^{L-1}} \cdot \cdots \cdot \frac{\partial z^{i+1}}{\partial z^i} \right ) \cdot \frac{\partial z_i}{\partial b_i}∂bi∂J​=∂zi∂J​⋅∂bi∂zi​=∂zL∂J​⋅∂zL−1∂zL​⋅⋯⋅∂zi∂zi+1​⋅∂bi​∂zi​​=(∂zL∂J​⋅∂zL−1∂zL​⋅⋯⋅∂zi∂zi+1​)⋅∂bi​∂zi​​。

我们明显可以看到,上面两个式子存在一个公共部分,即用括号括起来的部分,而且似乎用“反向传播”来形容这个部分似乎更加贴切:这部分正是将梯度从输出层一级一级地回传到需要更新参数的当前层的过程!首先计算损失JJJ对网络输出层的输出zLz^LzL的梯度∂J∂zL\frac{\partial J}{\partial z^L}∂zL∂J​,之后使用链式法则,通过将其乘以输出层的输出对上一层的输出的梯度∂zL∂zL−1\frac{\partial z^L}{\partial z^{L-1}}∂zL−1∂zL​,就能得到损失JJJ对倒数第二层输出的梯度。以此类推,可以很方便地由后至前逐步计算出JJJ对每一层的输出ziz^izi的梯度∂J∂zi\frac{\partial J}{\partial z^i}∂zi∂J​。这部分即是上述计算loss对每层输出的梯度

得到了损失JJJ对本层输出的梯度∂J∂zi\frac{\partial J}{\partial z^i}∂zi∂J​,接下来继续应用链式法则,只要求出本层输出对相应权重WWW和偏置bbb的梯度∂zi∂Wi\frac{\partial z_i}{\partial W_i}∂Wi​∂zi​​和∂zi∂bi\frac{\partial z_i}{\partial b_i}∂bi​∂zi​​并与之相乘,就能得到我们所需要的用于梯度下降的∂J∂Wi\frac{\partial J}{\partial W^i}∂Wi∂J​和∂J∂bi\frac{\partial J}{\partial b^i}∂bi∂J​了。这部分即是上述计算每层的输出对其参数的梯度

如果添加激活函数,则可将ziz^izi看作“未激活输出”,每次∂zi−1∂zi\frac{\partial z_{i-1}}{\partial z_i}∂zi​∂zi−1​​的部分会包含激活函数的导数。卷积层与全连接层类似,可以在参考文献里找到详细讲解。

要想实现有效的反向传播,有什么条件?

有效的反向传播最终能够计算出用于梯度下降的∂J∂Wi\frac{\partial J}{\partial W^i}∂Wi∂J​和∂J∂bi\frac{\partial J}{\partial b^i}∂bi∂J​。那什么时候反向传播会达不到我们想要的结果呢?一是无法进行反向传播,比如前向过程出现不可导的操作时,反向传播会在此中止;二是如果每次反向传播得到的梯度都是0,那么将无法进行参数更新。这里在尽量不涉及数学公式的情况下着重讨论一下后者。

上一节我们把反向传播分为两个部分:主干计算loss对每层输出的梯度和分支计算每层的输出对其参数的梯度。想要反向传播得到有效的梯度,主干中的任何一个中间梯度都不能为0,否则在本次反向传播中其后的所有梯度都将为0;而分支的梯度为0会使得本次本层的权重WWW或偏置bbb获得0梯度而无法更新。依据参考文献,在这里做一个简单的归纳。同样以MLP为例,不考虑激活函数。

首先来看主干的部分,即∂J∂zL⋅∂zL∂zL−1⋅⋯⋅∂zi+1∂zi⋯\frac{\partial J}{\partial z^L} \cdot \frac{\partial z^L}{\partial z^{L-1}} \cdot \cdots \cdot \frac{\partial z^{i+1}}{\partial z^{i}} \cdots∂zL∂J​⋅∂zL−1∂zL​⋅⋯⋅∂zi∂zi+1​⋯。只要损失函数可导,那么∂J∂zL\frac{\partial J}{\partial z^L}∂zL∂J​这部分肯定没有问题。接下来思考∂zi+1∂zi\frac{\partial z^{i+1}}{\partial z^i}∂zi∂zi+1​里一般会包含什么内容?由ziz^izi到zi+1z^{i+1}zi+1的前向传播过程一定与Wi+1W^{i+1}Wi+1和bi+1b^{i+1}bi+1相关,为zi+1=Wi+1zi+bi+1z^{i+1}=W^{i+1}z^i+b^{i+1}zi+1=Wi+1zi+bi+1。此前向过程对ziz^izi求导,得到Wi+1W^{i+1}Wi+1,而因为bi+1b^{i+1}bi+1与ziz^izi无关,被当成常数项处理而不被包含。如果Wi+1=0W^{i+1} = 0Wi+1=0,则∂zi+1∂zi=0\frac{\partial z^{i+1}}{\partial z^i}=0∂zi∂zi+1​=0,本次反向传播中断,此层及此后所有层得到的∂J∂zi=0\frac{\partial J}{\partial z^i}=0∂zi∂J​=0,得不到有效的梯度信息。

假设主干得到了本层有效的梯度∂J∂zi≠0\frac{\partial J}{\partial z^i}\neq 0∂zi∂J​​=0,我们再来看分支的情况,即∂zi∂Wi\frac{\partial z_i}{\partial W_i}∂Wi​∂zi​​和∂zi∂bi\frac{\partial z_i}{\partial b_i}∂bi​∂zi​​。这次我们把目光聚焦在与WiW^iWi、bib^ibi和ziz^izi有关的前向传播部分,即由zi−1z^{i-1}zi−1到ziz^izi的前向传播过程zi=Wizi−1+biz^i=W^iz^{i-1}+b^izi=Wizi−1+bi。该过程对WiW^iWi求导得到zi−1z^{i-1}zi−1,而对bib^ibi求导得到常数111。因此,WiW^iWi能否更新除了和主干有关,还和本层输入zi−1z^{i-1}zi−1有关,而bib^ibi的更新则只与主干的梯度有关。

总结一下,如果某层的权重Wi=0W^i=0Wi=0,则∂zi∂zi−1=0\frac{\partial z^i}{\partial z^{i-1}}=0∂zi−1∂zi​=0,主干中断,该层之后的所有层在本次反向传播中得不到任何回传的梯度;如果某层的输入zi−1=0z^{i-1}=0zi−1=0,WiW^iWi的分支中断,本次本层的WiW^iWi获得的梯度为0,无法更新,但bib^ibi不受影响。

加入激活函数与上述分析类似,只是需要考虑激活函数的导数,其中不含影响结论的变量;使用卷积网络思路基本相同,分析推导过程不同,结论大致相同。

结语

写这个文章的起因是和同学讨论,如果卷积层的WWW和bbb都初始化为0的话能不能更新其参数?现在我们可以不严谨地回答一下这个问题了:如果有顺次相连的两个及两个以上的卷积层的WWW和bbb都初始化为0,那么包括这这几个卷积层在内及其之前所有的层,其WWW全部无法更新,并且除了最后一个0初始化卷积层的bbb之外的bbb都无法更新。因为最后一个卷积层权重WiW^iWi为0,第一次反向传播主干中断,仅最后一层的参数可能获得更新;而由于其之前的卷积层参数也均为0,故最后一层的输入为0,可知WiW^iWi无法更新,依然全部为0,仅bib^ibi能够获得更新,但bib^ibi的更新并不能影响反向传播,如此一来便始终有Wi=0W^i=0Wi=0。这样的话主干始终不通,第iii层及其之前层的所有参数除bib^ibi外都不会更新。

另外,除了将网络参数初始化为全0,将所有参数初始化为相同的常数可能使梯度对称,从而使同一层的所有参数总是同步更新而导致训练无效。

写了一堆,感觉挺乱,而且缺少公式不甚严谨,就权当是给自己写个备忘吧。如有错误,欢迎指出。

参考资料

深度神经网络(DNN)反向传播算法(BP)
卷积神经网络(CNN)反向传播算法

反向传播BP思路梳理相关推荐

  1. 深度学习图像处理目标检测图像分割计算机视觉 04--神经网络与误差反向传播BP算法

    深度学习图像处理目标检测图像分割计算机视觉 04--神经网络与误差反向传播BP算法 摘要 一.神经元 二.前馈网络 2.1 Delta学习规则 2.2 目标函数J(w) 三.误差反向传播算法(BP算法 ...

  2. 神经网络——反向传播BP算法应用案例

    案例应用(一)--20个样本的两层(单隐藏层)神经网络 知识点: 1.tolist() 链接:http://blog.csdn.net/akagi_/article/details/76382918 ...

  3. 反向传播BP 算法之一种直观的解释

    0. 前言 之前上模式识别课程的时候,老师也讲过 MLP 的 BP 算法, 但是 ppt 过得太快,只有一个大概印象.后来课下自己也尝试看了一下 stanford deep learning 的 wi ...

  4. TensorFlow精进之路(十一):反向传播BP

    1.概述 全连接神经网络和卷积神经网络用的是反向传播(BackPropagation,BP),而卷积神经网络用的是随时间反向传播(BackPropagation Through Time,BPTT), ...

  5. 深度学习笔记--pytorch从梯度下降到反向传播BP到线性回归实现,以及API调用和手写数据集的实现

    梯度下降和反向传播 目标 知道什么是梯度下降 知道什么是反向传播 1. 梯度是什么? 梯度:是一个向量,导数+变化最快的方向(学习的前进方向) 回顾机器学习 收集数据 x x x ,构建机器学习模型 ...

  6. 神经网络反向传播BP算法举例说明

    0. 前言 上篇博客对BP算法的大致步骤进行了总结,本篇博客将通过一个具体的例子来模拟一下这个算法的实现过程 ! 1. BP算法例子说明 1.1 网络结构 1.2 权重及偏移 w = ( 0.1 , ...

  7. 反向传播 BP 理解

    参考: 一文弄懂神经网络中的反向传播法--BackPropagation

  8. 多层感知机Perceptron反向传播BP算法推导(Back Propagation)

    看了很多BP的推导,都不够简洁直观,这里总结一下.多层Perceptron就是全连接的网络,定义第l层的输入为x(l)x^{(l)}x(l),那么全连接的线性输出z(l)=W(l)x(l)+b(l)z ...

  9. LSTM模型与前向反向传播算法

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 前  言 在循环神经网络(RNN)模型与前向反向传播算法中,我们总 ...

最新文章

  1. 多视图几何总结——从本质矩阵恢复摄像机矩阵
  2. JQuery闭包,插件的写法
  3. 验证码之字符的特征提取
  4. linux ctrlc 退出循环_linux按行读取 (while read line与forloop)
  5. 学习使用资源文件[2] - Ico
  6. 如何选择WEB报表工具(二)
  7. MongoDB 计划从“Data Sprawl”中逃脱!
  8. caffe学习日记--lesson4:windows下caffe DEMO (mnist and cifar10)
  9. oracle数据库的安全测试
  10. java反射机制的实现机制_Java反射机制实践
  11. 一篇文章搞懂BIM技术的要点和前景
  12. 窗函数的介绍以及画出常见窗函数(汉宁窗,矩形窗,汉明窗,布莱克曼窗)的时域图和频谱图
  13. 学python看谁的视频比较好-python学习视频好的有哪些
  14. 会员数据化运营(一)
  15. Symantec的SEP服务器(SEPM)从12.1 RU6MP5 升级到14 MP1 操作手册
  16. QFD修改工作流并重新发布中的问题
  17. 鸿蒙手机会在千元机吗,鸿蒙OS升级计划表曝光,华为千元机也有份!
  18. Jenkins Mac本地环境搭建
  19. ubuntu设置时间为utc标准时间
  20. l003 Driller Augmenting Fuzzing Through Selective Symbolic Execution_2016_NDSS学习笔记

热门文章

  1. 常用类-Object类
  2. js阻止世界冒泡的方法-真有效
  3. XPath用法及常用函数
  4. 16012009徐小东_考核二
  5. 导数应用(一):差分计算(导数)
  6. 广播电视新技术应用分析及发展趋势
  7. 知客CRM:客户关系管理2.0
  8. Bilevel Optimization
  9. pid控制电机转速,偏差为0时,电机如何保持恒定转速
  10. 基于BP神经网络的手写体数字识别matlab仿真实现