初学者都能懂的深度学习之神经网络(三)反向传播算法

注明:本人仔细学习 3Blue1Brown 中提供的深度学习视频,将其整理出此文档。因文章的篇幅和本人的理解能力有限,若有条件的可以观看 3Blue1Brown 在b站上传的深度学习的三个视频以及相关内容。此文档会加入一些自己学习的感悟和理解,若有误烦请诸位指正。


第三部分 深度学习之神经网络反向传播算法


最后一部分,我们将来学习反向传播算法,即神经网络学习的核心算法。如果你看了前两个部分(神经网络结构和梯度下降法)或者你已经足够了解,可以开始本部分的学习 “ 反向传播算法

反向传播算法

假设你已经知道了神经网络是什么,以及它是如何前馈信息的。这里我们考虑的经典例子就是手写数字识别,数字的像素值被输入到网络第一层的 784 各神经元里,这里展示 2 层 16 各神经元隐含层,10 个神经元的输出层代表网络给出的选择。

假设你已经理解了上期的梯度下降法(如果还不了解结构的可以转到:(17条消息) 初学者都能懂的深度学习之神经网络(一)_税纪️的博客-CSDN博客还不了解梯度下降法的可以转到:(17条消息) 初学者都能懂的深度学习之神经网络(二)梯度下降法_税纪️的博客-CSDN博客)。

所谓学习就是指,我们要找到特定的权重偏置,从而使一个代价函数最小化。这里稍微提醒一下:计算一个训练样本的代价,你需要求出网络的输出与期待的输出之间每一项的差的平方和,然后对于成千上万个训练样本都这么计算一遍,最后取平均,这就得到了整个网络的代价值。我们需要求的是代价函数的负梯度(负梯度告诉如何改变所有连线上的权重偏置),才好让代价下降得最快。

本部分得反向传播算法,正是用来求这个复杂到爆的梯度的。需要记住:13002 个参数组成的梯度向量的优化,该梯度向量每一项的大小实在描述代价函数对于每个参数有多敏感。

比如说,你走了一段刚才我说的过程计算了负梯度,对应这条线上或者权重的一项等于 3.2,而对于这条边上的另一项等于 0.1,此时你可以这么来理解,第一个权重对代价函数的值有 32 倍的影响力。所以此时你稍微改变一下第一个权重,它对代价值造成的变化就是改变第二个权重同等大小下的 32 倍。

扫描二维码关注公众号,回复: 17344427 查看本文章

就我而言,我刚开始学习反向传播算法的时候,我觉得最容易搞混的部分就是各种符号和上标下标。不过,一旦捋清了算法的思路,算法的每一步其实都挺直观的,其实就是把许许多多微小的模型一层一层地进行下去而已。

所以,开始讲解时,我将完全抛弃所有的符号,给大家一步步解释,每一个训练样本会对权重偏置的调整造成怎样的影响。因为代价函数牵扯到对成千上万个训练样本的代价取平均值,所以我们调整每一步梯度下降用的权重偏置,也会基于所有的训练样本。虽然原理上应当这么做,但为了计算效率,之后咱们会走个捷径,从而不必每一步都非得要计算所有的训练样本。

现在,我们来只关注一个训练样本:“2”,这个一个训练样本会对调整权重和偏置造成怎样的影响呢?假设网络还没有完全训练好,即该训练样本 “2” 作为训练集中的一个。那么此时输出层的激活值看起来就很随机(也不一定,万一此时的神经网络对这个样本恰好很敏感呢?假设不敏感,即需要这个样本来训练),也许就会出现例如 0.5、0.8、0.2 之类的输出层激活值。现在你想想,如何改变输出层激活值?

没错!改变权重值偏置值。但需要注意的一点是:记住输出层出现怎样的变动还是很有用的。由于我们希望图像最终的分类结果是 2,那么就需要将 “2” 的输出值变大,其他输出值变小,并且变动的大小应该与当前值目标值之间的正比,就比如增加 “2” 神经元的激活值就应该比减小数字 “8” 神经元的激活值更重要(因为后者相对于前者已经非常接近目标值了)。

我们更进一步来关注一下 “2” 这个神经元。我们的目标是要让这个神经元的激活值变大,通过前两部分的学习,你肯定已经非常清楚这个激活值是把前一层所有激活值的加权和加上一个偏置值,再通过 Sigmoid 或ReLU之类的压缩函数(激活函数)计算得出的。所以要增加 “2” 激活值,有三条路可走:

  • 增加权重值
  • 增加偏置值
  • 改变上一层的激活值

我们按照这三条思路分别分析:

一、调整权重值

各个权重它们的影响力各不相同,连接前一层最亮的神经元的权重,影响力也最大。因为这些权重会与大的激活值相乘,所以至少对于这一个训练样本而言,增大了这几个权重值对最终代价函数造成的影响就比增大连接暗淡神经元的权重所造成的影响要大上很多倍。

(在第二部分讲解梯度下降的时候,我们并不只看每个参数是该增大还是减小,我们还该看哪个参数的性价比最高)(这有一点像描述生物中神经元的网络如何学习的一个理论:“赫布理论 (Hebbian theory)”,即 “一同激活的神经元关联在一起”,这里权重的最大增长,即连接变得更强的部分就会发生在已经最活跃的神经元和想要更多激发的神经元之间

二、调整上一层神经元的激活值

该方案就是如果正权重连接的神经元更亮(激活值更大),负权重连接的神经元更暗(激活值更小),那么 “2” 神经元就会更强烈的激发。

和方案一类似,我们想造成更大的影响,就要依据对应权重的大小,对于及或者做出成比例的改变。当然我们不能直接改变激活值,我们只能控制权重和偏置值。但就光对最后一层来说,记住我们期待的变化还是很有帮助的。不过!别忘了从全局来看,这只不过是数字 “2” 的神经元所期待的变化,我们还需要最后一层其他的神经元的激发变弱,但这其余的每个输出神经元对于如何改变倒数第二层都有各自的想法。所以,我们把数字 “2” 神经元的期待和别的输出神经元的期待全部加起来作为对如何改变倒数第二层神经元的指示,这些期待变化不仅是对应的权重的倍数,也是每个神经元激活值改变量的倍数。

这其实就是在实现 “反向传播” 的理念了。我们把所有期待的改变加起来,就得到了一串对倒数第二层改动的变化量。有了这些,我们就可以重复这个过程,改变影响倒数第二层神经元激活值的相关参数,从后一层到前一层,把这个过程一直循环到第一层。

放眼大局,我们只是在讨论单个训练样本对所有权重偏置的影响,如果我们只关注这个 “2“ 样本的训练,最后网络只会把所有图像都分类成 ”2“(害,其实也不一定,只是在一定概率上,只是想说其实这样训练的网络是没有意义的),所以要对其他所有的训练样本同样地过一遍反向传播,记录下每个样本想怎样修改权重偏置值,最后再取一个平均值。这里一系列权重偏置的平均微调大小,(不严格地说(不严格是指还没有准确地解释如何量化这些微调))就是第二部分提到的代价函数的负梯度(至少是其标量的倍数)。

(如果你清楚我提到的所有改动:为什么有些数字是其他数字的好几倍、以及最后要怎么全部加起来,你就懂得了反向传播的真实工作原理)

在实际中操作中,如果梯度下降的每一步都用上每一个训练样本来计算的话,那么花的时间就太长了,所以我们一般会这么做:

  • 1.首先把训练样本打乱,然后分成很多组 mini-batch(每个 mini-batch 就当包含 100 个训练样本吧)
  • 2.然后依次计算出每一个 mini-batch 下降的一步。(注意!这不是代价函数真正的梯度,毕竟计算真实梯度得用上所有的样本,而非这个 mini-batch 子集,因此这也不是下山最高效的一步。然而,每个 mini-batch 都会给你一个不错的近似,最重要的是计算量减轻了不少!)

如果把这种策略下的网络沿代价函数的表面下山的路径画出来的话,看上去像醉汉漫无目的地遛下山,但起码步伐很快。而不像细致入微的人,按照之前准确地算好下坡方向,然后再每次小心谨慎地计算并更新下坡方向。这种醉汉下山的技巧就叫做 ”随机梯度下降“

现在我们来总结一下:

反向传播算法算的是单个训练样本想怎样修改权重与偏置值,不仅仅要给到每个参数应该变大还是变小,还包括这些变化的比例是多大才能最快地降低代价。真正的梯度下降得对几万个训练样本都这么操作,然后对这些变化值取平均。但这样算起来太慢了,所以把所有样本分到各个 mini-batch 中,计算一个 mini-batch 来作为梯度下降的一步,计算每个 min-batch 的梯度,调整参数,不断循环,最终就会收敛到代价函数的一个局部最小值上。此时就可以说,该神经网络对付训练数据已经很不错了。

神经网络之反向传播就结束了,但是理解这些理论只完成了学习神经网络的一半,还有数学公式和编程呢!用微积分的形式把神经网络标识出来的数学描述可以参考这期视频:下篇 反向传播的微积分原理_哔哩哔哩_bilibili

收尾之前着重提一点:反向传播算法在内所有包括神经网络在内的机器学习,要让它们工作,咱需要一大坨,这里我们用的手写数字的范例之所以会这么方便,是因为存在着一个 MNIST 数据库,里面所有的样本都已经人为标记好了。所以机器学习领域的人,最熟悉的一个难关莫过于获取标记好的训练数据了。

最基本的神经网络已经全部 ”搬“ 完了,其他如 CNN、RNN、DBM、LSTM 等神经网络的变形,也会把自己的学习记录整理成文档放在这上面。

我的邮箱:[email protected]

如果有条件最好去看看 3B1B 在b站神经网络的 3 个视频,当你看了我的介绍再去学习视频,醍醐灌顶!

猜你喜欢

转载自blog.csdn.net/HISJJ/article/details/126953224