原文:
towardsdatascience.com/deep-learning-illustrated-part-2-how-does-a-neural-network-learn-481f70c1b474
欢迎来到深度学习图解系列的第二部分。在上一篇文章(务必先阅读!)中,我们介绍了神经网络的工作原理以及训练好的神经网络如何进行预测。我们还了解到,神经网络在训练过程中会达到最优的权重和偏差值。
在这篇文章中,我们将深入探讨训练过程,并探讨神经网络是如何学习的。
📣 如果你还没有阅读我的上一篇文章,我强烈建议你从我的关于机器学习基础知识的文章系列开始,特别是关于梯度下降的那篇,因为你会发现那里覆盖的许多材料在这里都是相关的。
假设我们想要创建一个神经网络,该网络使用温度和星期几作为特征来预测冰淇淋的日销售额。
这是我们在使用的训练数据集:
要构建一个神经网络,正如我们在上一篇文章中学到的,我们首先需要决定其架构。这包括确定隐藏层的数量、每层的神经元数量以及每个神经元的激活函数。
假设我们决定我们的架构是:1 个隐藏层,包含 2 个神经元,以及 1 个输出神经元,所有这些神经元都使用整流激活函数。
术语过渡:在上一篇文章中,我们学习了如何使用下标来区分不同的权重。在这里,我们将保持相同的约定,并且此外,我们将使用上标来表示偏差和权重所属的层。因此,在上面的图中,我们可以看到进入第一个神经元层的权重和该层的偏差项都具有上标 1。
你还会注意到,我们的预测输出被表示为 r_hat。我们了解到,帽子符号表示它是预测值,因为我们在这里预测的是收入,所以我们使用 r。
一旦我们确定了架构,就是时候通过提供一些数据来训练模型了。在训练过程中,神经网络将学习权重和偏差项的最优值。比如说,使用上面的训练数据训练模型后,它产生了以下最优值:
本文将重点介绍我们是如何得到这些最优值的。
让我们从简单的情况开始。假设我们已经有外层神经元的所有最优值除了偏差项。
由于我们不知道偏差的确切值,我们首先进行一个初始猜测,并将值设置为 0。通常,偏差值在开始时初始化为 0。
现在,我们需要输入所有冰淇淋店的特性来预测收入(即我们从前一篇文章中学到的正向传播),假设最后一个偏差项为 0。让我们将我们的 10 行训练数据传递到神经网络中…
…以得到以下预测:
现在我们有了当最后一个偏差项等于 0 时的预测,我们可以将其与实际收入进行比较。在上一篇文章中,我们了解到我们可以使用成本函数来衡量预测的准确性,具体来说,对于我们的用例,是均方误差(MSE)。
计算具有偏差为 0 的该模型的 MSE:
我们还知道,任何模型的最终目标都是减少 MSE。因此,现在的目标是找到一个最优的偏差值,以最小化这个 MSE。
比较不同偏差值下的 MSE 值的一种方法是通过暴力方法尝试不同的最后一个偏差项的值。例如,让我们对偏差项进行第二次猜测,这个值略高于最后一个值为 0 的值。让我们尝试偏差=0.1。
我们将训练数据传递到具有偏差=0.1 的新模型中…
…这导致了以下预测…
…然后我们使用这些值来计算 MSE:
如我们所见,这个模型的均方误差(MSE,0.03791)略好于之前将偏差设置为 0 时的 MSE(0.08651)。
为了更清楚地可视化这一点,让我们将这些值绘制在图表上。
我们可以通过猜测值来继续使用这种暴力方法。比如说,我们也猜测了 4 个更多的值:偏差=0.2,0.3,0.4,和 0.5。我们重复上述相同的过程来生成一个看起来像这样的 MSE 图表:
我们注意到,当偏差 = 0.3 时,MSE 达到最低点。而当偏差 = 0.4 时,MSE 又开始增加。这告诉我们我们在偏差 = 0.3 时最小化了 MSE。
幸运的是,我们通过几次有根据的猜测后能够确定这一点,并通过额外的尝试来确认。然而,如果最优的 MSE 值是 100 呢?在这种情况下,我们需要进行 1000(100 x 10)次猜测才能达到它。因此,这种方法在寻找最优偏差值方面效率不高。此外,我们如何确定具有最低 MSE 值的偏差确实是 0.3?如果它是 0.2998 或 0.301 呢?使用这种蛮力技术进行如此精确的猜测将是困难的。
梯度下降法
幸运的是,我们有一个更有效的方法来确定最优偏差值。我们将利用一个称为 梯度下降 的概念。而且,太好了——梯度下降已经在(如果我可以这么说的话)一篇之前的文章中介绍过了。所以,在继续之前,请务必阅读那篇文章。
简要来说,通过使用梯度下降和利用导数,我们可以有效地达到任何凸曲线(本质上是一个 U 形曲线)的最低点。在我们的当前情况下,这是理想的,因为上面的 MSE 图形类似于 U 形曲线,我们需要找到 MSE 最小化的山谷。梯度下降通过指示达到曲线底部所需的每一步的大小和方向来引导我们,以便尽可能快地到达底部。
现在,让我们使用梯度下降中概述的步骤重新开始寻找最优偏差的过程。
第 1 步:从随机的初始偏差值开始
例如,我们可以从偏差 = 0 开始:
第 2 步:计算步长
接下来,我们需要确定方向和应该迈出多大的步子。这可以通过计算 步长 来实现,它是将一个称为 学习率 的常数乘以在偏差值处的 MSE 的梯度得到的结果。在这种情况下,这个迭代的偏差值是 0。
注意:学习率是一个用于控制步长的常数。通常,它介于 0 和 1 之间。
让我们更仔细地考察一下导数值。我们知道均方误差(MSE)是 _rhat 的函数,如公式所示:
我们还知道,_rhat 由最后一个神经元的 relu 函数决定,因为我们只能通过利用激活函数来获得 r_hat:
我们还知道,在最后一个神经元中包含偏差项的 relu 函数。
现在,如果我们想计算 MSE 相对于偏差的导数,我们将使用一个叫做链式法则的东西,它是微积分的一个超级重要部分,它利用了上述 3 个关键信息。
我们需要使用链式法则,因为项之间相互依赖,但不是直接依赖。它被称为链式法则,因为它们都链接在一个类似链的结构中。我们可以几乎认为分子和分母相互抵消。
这就是如何计算 MSE 相对于偏差的导数。我们在当前的偏差值(0)处计算这个导数。
第 3 步:使用上述步长更新偏差值
这将给我们提供一个新的偏差值,希望它能让我们更接近最优偏差值。
第 4 步:重复步骤 2-3,直到我们达到最优值
我们将继续重复这个过程,即采取步骤…
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/773d61bb3951822228cd56a0affc1682.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/89c7a21f099264bdb67675f8fb8d2b31.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2d75dee9c8b8ebc736e37b671ea61d97.png
…通过微小跳跃,随着我们接近底部,步骤逐渐缩小…
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e004a0076d9cb311510347991e008a4d.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/241ff2d05c5fe71f8d51511d6e0fd305.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4012f8f3bd2df3899536182dbf4c2597.png
…直到最后…
…我们达到了最优值!
注意:当我们步长接近 0 或者达到算法中设定的最大步数时,我们达到了最优值。
完美。这就是我们如何找到偏差项,假设其他变量的最优值已经已知。
术语过渡:确定这个偏差项值的过程被称为反向传播。在我们之前的文章中,我们关注的是正向传播,它涉及传递输入以获得输出。它被称为正向传播,因为我们实际上是在向前传播输入。同时,这个过程被称为反向传播,因为我们向后移动以更新偏差值。
现在,让我们更进一步,考虑一个场景,即我们知道所有最优值,除了偏差项和进入最后一个神经元的第二个输入的权重。
再次,我们需要找到这两个项的最优值,以便最小化 MSE。对于不同的权重和偏差值,让我们创建一个 MSE 的图表。这个图表将与上面的图表类似,但是在三维空间中。
与之前的 MSE 曲线类似,我们需要找到最小化 MSE 的点。这个点,被称为谷点,将为我们提供偏置和权重项的最优值。再次,我们可以使用梯度下降法达到这个最小点。这个过程在这里基本上也是相同的。
第 1 步:随机初始化权重和偏置的值
第 2 步:使用偏导数计算步长
这时发生了一个小小的偏差。我们不是计算均方误差(MSE)的导数,而是计算所谓的偏导数,并同时更新步长大小。这里的“同时”意味着需要在当前权重和偏置值下计算偏导数的值,我们再次使用链式法则:
第 3 步:同时更新权重和偏置项
第 4 步:重复步骤 2-3,直到收敛到最优值
我们可以对此进行疯狂尝试。现在假设我们想要优化神经网络中的所有 9 个值呢?
然后,我们将有 9 个需要更新的联立方程,以达到最小值。(甚至无法尝试绘制这个 MSE 函数,因为,正如你所能或不能想象的那样,那将是一个看起来非常疯狂的图表)
尽管随着联立方程数量的增加,手工计算数学变得更为复杂,但概念保持不变。我们试图逐渐向山谷底部移动,依靠梯度下降法来引导我们。
通过应用上述方程和优化过程,数据中的隐藏模式自然出现。这使我们能够在没有任何人为干预的情况下找到这些深层模式。
好的,为了回顾,我们现在明白我们总是想要最小化成本函数(在上面的例子中是 MSE),以及如何通过梯度下降法获得最小化 MSE 的权重和偏置项的最优值。
我们了解到,通过使用梯度下降法,我们可以轻松地穿越一个凸形曲线,达到底部。幸运的是,在我们的案例研究中,我们有一个看起来很美的凸曲线。然而,有时我们可能会遇到一个成本函数,它不会产生完美的凸曲线,而是产生类似这样的东西
如果我们使用梯度下降法,有时我们可能会错误地将许多局部最小值(看似最小点但实际上不是)识别为最小点,而不是全局最小值(真正的最小点)。
梯度下降的另一个问题是,随着我们数据集中数据点的数量或项的增加,执行梯度下降所需的时间也会增加。这是因为涉及的数学变得更加复杂。
在我们的小型示例中,我们有 10 个数据点(这非常不现实;通常我们会有数十万个数据点),我们正在尝试优化 9 个参数(这个数字也可以非常高,具体取决于架构的复杂程度)。目前,对于梯度下降的每次迭代,我们使用 10 个数据点来计算偏导数并更新 9 个参数值。
这本质上就是梯度下降所做的事情:
在每次迭代中,我们进行大约 90(910)次小计算来计算每个单独数据点的 MSE 的导数。通常,我们会进行 1000 次这样的迭代,总共计算 90,000(901000)次。
然而,如果我们有 10 万个数据点而不是仅仅 10 个呢?在这种情况下,我们需要计算所有 10 万个数据点的 MSE 并求出 900,000(= 9100,000)个项的导数。通常,我们会进行大约 1000 步的梯度下降来达到最优值,这将导致令人震惊的 900,000,000(900,0001000)次计算。此外,我们的数据可以变得非常复杂,包含数百万的数字和更多的参数需要优化。这可能会迅速变得非常具有挑战性。
为了避免这个问题,我们可以利用更快、更强大的替代优化算法。
随机梯度下降
随机梯度下降(SGD)与梯度下降类似,但有一个微小的区别。在梯度下降中,我们在计算包含所有 10 个值的整个训练数据集的 MSE 后更新我们的值。然而,在 SGD 中,我们仅使用数据集中的一个数据点来计算 MSE。
算法随机选择一个数据点并使用它来更新参数值,而不是使用整个数据集。
这是一个较轻的算法,使其比其全面的对应物更快。
小批量梯度下降
这种方法是将批量梯度下降和随机梯度下降相结合。我们不是基于单个数据点或整个数据集来更新值,而是在每次迭代中处理一批数据点。我们可以选择批量大小的值为 5、10、100、256 等。
例如,如果我们的批量大小是 4,我们将基于 4 行数据计算部分导数的均方误差(MSE)。
在处理梯度下降时,除了大数据问题和局部最小值问题之外,我们还可以遇到另一个问题。还记得学习率吗?我们并没有深入探讨它,但讨论过它是在模型构建过程开始时设置的一个常数项。学习率的选取极大地影响了梯度下降的性能。如果我们设置的学习率太低,我们可能永远无法收敛到最优值,如果我们设置得太高,我们可能会超过我们的步长并偏离最优值。实际上,有一个最佳平衡点。现在的问题是,我们如何找到这个学习率?
选项 #1:尝试很多不同的学习率,看看哪个效果最好
(更聪明的)选项 #2:设计一个自适应学习率,它能够“适应”我们的神经网络和适应我们的均方误差(MSE)景观。
这正是其他优化算法所试图达成的目标。然而,详细讨论它们需要另一整篇文章。如果你感兴趣,可以参考这篇文章,它深入探讨了其中一些流行的优化器。
这就结束了我们对神经网络的探索。这两篇文章文章应该为我们进一步探索深度学习世界提供了一个坚实的基础。而且,为了了解我们如何将这些概念付诸实践,请阅读这篇文章,它使用 TensorFlow(以及 PyTorch)构建了上述冰淇淋收入神经网络!
第三部分:卷积神经网络现在已上线!
除非特别说明,所有图像均为作者所有。
如往常一样,如果你有任何问题或评论,请随时通过LinkedIn与我联系!

被折叠的 条评论
为什么被折叠?



