[在 criblate.com 提交字幕更正] 这里有一个硬性假设,即你已经观看了第 3 部分,那里对反向传播算法进行了直观的 walkthrough。在这里,我们将变得更加正式,并深入探讨相关的微积分。这至少会有些令人困惑,因此“定期暂停并深思”这句口诀在这里和在任何地方都同样适用。我们的主要目标是展示机器学习领域的人们如何思考微积分中的链式法则,并将其应用于网络语境中。这与大多数入门级微积分课程处理该主题的方式感觉不同。对于那些对相关知识感到不适的人,我有一套关于该主题的完整系列课程。让我们从一个极其简单的网络开始,其中每一层只有一个神经元。

该网络由三个权重和三个偏置决定,我们的目标是理解成本函数对这些变量的敏感程度。这样,我们就知道对各项参数进行哪些调整会导致成本函数最高效地下降。我们将仅关注最后两个神经元之间的连接。让我们用上标 L 来标记最后一个神经元的激活值,以指示它所在的层,因此前一个神经元的激活值为 a^(L-1)。这些不是指数,只是我们用来索引讨论对象的标记方式,因为我想把下标留给后面不同的索引。假设对于给定的训练样本,我们想要的这个最后激活值是 y,例如 y 可能是 0 或 1。因此,该网络对于单个训练样本的成本是 (a^(L) - y) 的平方。我们将那个单个训练样本的成本记为 C0。

提醒一下,这个最后的激活值是由一个权重决定的,我称之为 w(L),乘以之前神经元的激活值,再加上一些偏置,我称之为 b(L)。然后你将这个结果输入到某种特殊的非线性函数中,比如 sigmoid 或 ReLU。如果我们给这个加权和赋予一个特殊名称,比如 z,并使用与相关激活值相同的上标,这对我们将更加容易。这里有很多术语,你可以这样概念化:权重、之前的激活值和偏置共同用于计算 z,进而让我们计算 a,最后,结合常数 y,让我们计算成本。当然,a^(L-1) 受其自身的权重和偏置等影响……但我们现在不关注那个。

所有这些都只是数字,对吧?把每一个都想象成拥有自己的小数轴是很不错的。我们的第一个目标是理解成本函数对权重 w(L) 微小变化的敏感程度。或者换个说法,C 对 w(L) 的导数是多少?当你看到 del w 项时,将其理解为对 W 的一些微小扰动,比如 0.01 的变化,并将 del C 项理解为由此产生的对成本的扰动。我们需要的是它们的比率。从概念上讲,对 w(L) 的微小扰动导致了对 z(L) 的扰动,进而导致了对 a(L) 的扰动,这直接影响成本。因此,我们首先通过查看 z(L) 的微小变化与 w(L) 的微小变化之比来分解问题,即 z(L) 对 w(L) 的导数。

同样,你随后考虑 a(L) 的变化与导致该变化的 z(L) 微小变化之比,以及最终对 C 的扰动与对 a(L) 的中间扰动之间的比率。这就是链式法则,将这三个比率相乘,就给出了 C 对 w(L) 微小变化的敏感度。现在屏幕上有很多符号,花点时间确保清楚它们各自代表什么,因为现在我们要计算相关的导数。C 对 a(L) 的导数等于 2(a^(L) - y)。请注意,这意味着其大小与网络输出和我们想要的值之间的差成正比,因此如果输出差异很大,即使是微小的变化也可能对最终成本函数产生重大影响。

a(L) 对 z(L) 的导数仅仅是我们 sigmoid 函数(或你选择的任何非线性函数)的导数。而 z(L) 对 w(L) 的导数……在这种情况下,结果为 a^(L-1)。现在我不知道你怎么样,但我认为很容易埋头于公式中,而没有停下来提醒自己它们各自的意义。对于最后一个导数的情况,权重微小扰动对最后一层的影响程度取决于前一个神经元的强度。记住,这就是“一起激发的神经元连在一起”这一想法发挥作用的地方。而这一切都是针对特定单个训练样本的成本关于 w(L) 的导数。

由于完整的成本函数涉及对所有不同训练样本的成本进行平均,其导数需要对所有训练样本平均该表达式。当然,这只是梯度向量的一个组成部分,而梯度向量本身是由成本函数对所有这些权重和偏置的偏导数组成的。但即使这只是我们需要的大量偏导数之一,它也占了超过一半的工作量。例如,对偏置的敏感度几乎相同。我们只需要将 del z / del w 项替换为 del z / del b。

如果你查看相关公式,该导数的结果为 1。此外,这也是反向传播思想所在之处,你可以看到该成本函数对前一层激活值的敏感程度。具体来说,链式法则表达式中的初始导数,即 z 对前一个激活值的敏感度,结果为权重 w(L)。同样,虽然我们无法直接影响前一层激活值,但跟踪它是有帮助的,因为现在我们可以继续迭代相同的链式法则思想向后传播,以查看成本函数对先前权重和先前偏置的敏感程度。你可能会认为这是一个过于简单的例子,因为所有层都只有一个神经元,而对于真实网络,情况将呈指数级复杂化。但老实说,当我们给层赋予多个神经元时,变化并不大,真的只是需要跟踪更多的索引。

给定层的激活值不再简单地是 a^(L),它还将有一个下标,指示该层中的哪个神经元。让我们用字母 k 索引层 L-1,用 j 索引层 L。对于成本,我们再次查看期望的输出,但这次我们计算这些最后层激活值与期望输出之间差异的平方和。也就是说,你对 (a^(L)_j - y_j) 的平方求和。

由于权重数量大幅增加,每个权重都需要额外的索引来追踪其位置,因此我们将连接第 k 个神经元到第 j 个神经元的边上的权重称为 w(L)_jk。这些索引起初可能感觉有些反直觉,但它们与你在我第一部分视频中提到的权重矩阵索引方式是一致的。就像之前一样,给相关的加权和(如 z)起个名字仍然很有用,这样最后一层的激活值就是特殊函数(如 Sigmoid)作用于 z 的结果。你可以看到,所有这些方程本质上与我们之前每层一个神经元的情况相同,只是看起来稍微复杂一些。

确实,描述成本对特定权重敏感度的链式求导表达式看起来基本上是一样的。如果你想的话,可以暂停并思考一下每一项的含义。然而,这里发生变化的是成本对第 L-1 层中某个激活值的导数。在这种情况下,区别在于该神经元通过多条不同的路径影响成本函数。一方面,它影响 a(L)_0,这在成本函数中起作用;另一方面,它也影响 a(L)_1,这也对成本函数起作用,你需要将这些影响加总。

这就差不多了。一旦你知道成本函数对该倒数第二层中激活值的敏感度,你就可以对输入该层的所有权重和偏置重复这一过程。所以,拍拍自己的背吧!如果这一切都讲得通,你现在已经深入了解了反向传播的核心,这是神经网络学习背后的主力。这些链式法则表达式给出了导数,这些导数确定了梯度中的每个分量,通过反复沿梯度下降方向步进,帮助最小化网络的成本。

如果你静下心来思考这一切,这确实有很多层复杂性需要理解,所以如果大脑需要时间来消化所有内容,也不要担心。