Towards Data Science

Backpropagation Explained for Beginners (Part 1): Building the Intuition

8.5内容质量

TL;DR · AI 摘要

反向传播是神经网络训练的核心机制,通过梯度下降优化参数。本文以直观方式拆解其数学原理,适合深度学习入门者。

核心要点

  • 反向传播通过链式法则计算梯度,优化模型参数
  • 激活函数(如ReLU)引入非线性,使神经网络能拟合复杂数据
  • 前向传播计算预测值,反向传播调整权重以最小化损失函数

结构提纲

按章节快速跳转。

  1. 揭示反向传播对理解AI训练的重要性及学习路径

  2. 总结前文构建的神经网络结构与激活函数作用

  3. 解释模型参数优化的数学本质与目标函数

  4. 分步解析链式法则在梯度计算中的应用

  5. 展示权重调整过程与损失函数关系

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 反向传播机制
    • 数学基础
      • 链式法则
      • 梯度计算
    • 网络结构
      • 激活函数
      • 参数优化
    • 训练流程
      • 前向传播
      • 损失函数

金句 / Highlights

值得收藏与分享的关键句。

#深度学习#神经网络#反向传播#梯度下降
打开原文

反向传播入门(第一部分):建立直觉 | Towards Data Science

深度学习

反向传播入门(第一部分):建立直觉

让我们逐步探索神经网络是如何学习的

Nikhil Dasari

2026年7月19日

15分钟阅读

分享

照片由Bálint Varga拍摄

你是否曾经难以理解反向传播?

如果你正在尝试理解现代人工智能系统(如大型语言模型)的训练方式,反向传播是最重要的概念之一。

但如果你问我第一次接触时的感受,看到数学公式时我完全迷失了。这对我来说就像一个心理障碍。

我意识到需要从零开始,逐步建立自己的理解。

这段旅程始于我之前的文章,我们在其中使用简单数据集从零构建了神经网络,并理解了它是如何进行预测的。

这篇博客获得了很好的反响,感谢大家的支持!

现在,让我们继续采用同样的方法。我们将逐步分解反向传播,保持与之前一样简单直观。

在开始之前,我想说一件事。我们将循序渐进。

像反向传播这样的主题起初可能会让人感到压力山大,但一旦我们建立了坚实的基础,其他内容就会变得更容易理解。

那么,让我们开始吧。

欢迎回来!

让我们继续深入学习的旅程。

我们已经对神经网络有了基本的了解,这是在上一篇博客中通过简单数据集探索得出的。

现在,让我们先回顾一下之前关于神经网络博客中学到的内容。

快速回顾

我们考虑了这个简单的数据集。

作者提供的图片

绘制数据后,它看起来像这样:

我们观察到单条直线不足以拟合数据,因此决定使用神经网络来解决这个问题。

接下来,我们了解了单个神经元的方程,之后学习了神经网络中不同层的结构。

为简化起见,我们考虑了一个包含两个隐藏神经元的隐藏层。

接下来,我们观察到两个隐藏神经元产生了两个不同的线性变换,然后我们希望在输出层将它们结合起来。

然而,我们发现将两条直线结合后得到的仍然是直线,而不是能够拟合数据的曲线。

这就是我们意识到激活函数重要性的时刻,因为它们为模型引入了非线性。

因此,我们将隐藏神经元的输出通过激活函数(ReLU)传递,然后在输出层将它们结合起来。

换句话说,我们在输出层对激活函数的输出进行线性组合,最终得到了曲线。

在之前的博客中,我们构建了神经网络架构,并通过前向传播看到了它是如何进行预测的。

在学习反向传播的工作原理之前,让我们先看一下之前博客中讨论的前向传播过程中各层产生的值。

在整个博客中,我们将使用这些值来理解网络如何通过更新参数来学习。

为什么网络需要学习?

当我们观察神经网络产生的最终曲线时,可以发现它拟合效果不佳。

例如,当学习时间(x)为1时,实际考试分数是55,但我们的神经网络预测为28,这存在巨大差异。

现在,我们需要让神经网络表现得更好,这意味着它应该预测出更接近实际考试分数的值。

要做到这一点,神经网络需要学习。通过学习,我们的意思是找出哪些参数需要增加、哪些需要减少以降低损失。

从熟悉的例子中学习

现在,我们如何做到这一点呢?

目前,我们还不知道如何实现这一点。

让我们做一件事。让我们从我们已经知道的内容开始。

但我们已经知道什么呢?

我们已经对简单线性回归有一定的了解,知道如何计算损失,以及损失曲线的形状。

也许我们可以从中学到一些东西。

在简单线性回归中,我们需要找到β0(截距)和β1(斜率)的最优值。

当然,我们已经有了公式,但我们自己也推导过这些公式。

我们所做的就是绘制了一个三维坐标图。一个轴表示β0,第二个轴表示β1,第三个轴表示损失。

我们绘制了不同β0和β1值对应的损失值,并观察到了一个碗状曲线。

我们了解到,损失的最小值出现在曲线的底部,此时损失曲面的斜率为零。

为了找到这个点,我们使用了偏微分,并最终解出方程得到了公式。

在简单线性回归中,我们可以使用不同的损失函数,如平方误差和(SSE)、均方误差(MSE)或其他适合问题的损失函数。

在这里,我们将均方误差(MSE)作为我们的损失函数。

对于简单线性回归,损失函数为

$$ L(\beta_0,\beta_1)=\frac{1}{n}\sum_{i=1}^{n}\left(y_i-\hat{y}_i\right)^2 $$

其中

$$ \hat{y}_i=\beta_0+\beta_1x_i. $$

注意,损失仅依赖于两个参数,$\beta_0$和$\beta_1$

我们需要找到使损失最小的$\beta_0$和$\beta_1$的值。

现在,让我们看看我们的神经网络。

由于当前的问题是一个非线性回归问题,我们可以继续使用相同的均方误差(MSE)。

现在,损失函数可以表示为

$$ L(w_1,w_2,w_3,w_4,b_1,b_2,b_3) = \frac{1}{n} \sum_{i=1}^{n} \left(y_i-\hat{y}_i\right)^2. $$

然而,与简单线性回归不同,我们的预测不再由

$$ \hat{y}=\beta_0+\beta_1x $$

给出,而是由整个神经网络生成。

对于我们的神经网络,

$$ \hat{y}_i = w_3\,\mathrm{ReLU}(w_1x_i+b_1) + w_4\,\mathrm{ReLU}(w_2x_i+b_2) + b_3. $$

因此,损失不再仅依赖于两个参数。现在,它依赖于神经网络的所有七个参数,即 $[w_1,w_2,w_3,w_4,b_1,b_2,b_3]$

与简单线性回归一样,我们的目标仍然是相同的:找到使损失最小的这些参数的值。

为了实现这一点,我们需要了解在保持其他参数不变的情况下,改变每个参数时损失是如何变化的。

换句话说,我们需要计算如下偏导数:

$$ \frac{\partial L}{\partial w_1}, \quad \frac{\partial L}{\partial w_2}, \frac{\partial L}{\partial w_3}, \ldots, \frac{\partial L}{\partial b_3}. $$

这些偏导数告诉我们损失对每个参数的敏感程度,并帮助我们确定该参数是应该增加还是减少以降低损失。

设定目标

在简单线性回归中,当我们绘制不同斜率和截距组合对应的损失值时,会在三维空间中得到一个碗状曲线。

然而,对于我们的神经网络来说,我们无法以相同方式可视化损失曲面,因为现在它存在于八维空间中。

尽管我们无法可视化它,但我们的目标保持不变,即找到使损失最小的参数值。

了解链式法则的时机

现在,基于我们从简单线性回归中已知的内容,我们找到了继续前进的方法,即计算损失对每个参数的偏导数。

这些参数是

$$w_1,w_2,w_3,w_4,b_1,b_2,b_3$$

但在继续之前,我们需要理解一个重要的概念,即链式法则,因为它是接下来所有工作的基础。

当一个量依赖于另一个量,而该量又依赖于另一个量时,就会用到链式法则。

让我们通过一个简单例子来理解这一点。

假设

y=x^2

z=y^3

现在,我们想找到

\frac{dz}{dx}

首先,让我们使用经典微分法计算这个导数。

注意到$$z$$是用$$y$$表示的,而不是$$x$$。由于我们希望对$$x$$求导,可以通过将$$y=x^2$$代入$$z$$的方程来消除中间变量。

代入后,

z=(x^2)^3=x^6

现在表达式仅依赖于$$x$$,我们可以直接对其进行微分。

根据幂法则,

\frac{d}{dx}(x^6)

6x^5

对于这种简单问题,这种方法可能很容易,因为我们能轻松地将一个表达式代入另一个表达式。

然而,想象一个包含多个中间变量的更大表达式。

在微分之前重写整个方程会变得困难,且出错的可能性更高。

与其先将所有内容合并成一个表达式,我们有一种更系统的方法,称为链式法则。

使用链式法则时,我们不需要消除中间变量,而是可以逐步处理它们。

让我们看看如何实现链式法则。

我们已经知道,$$\frac{dz}{dx}$$告诉我们当$$x$$发生微小变化时,$$z$$的变化量。

在这里,$$z$$并不直接依赖于$$x$$。

相反,关系如下:

x → y → z.

这意味着每当$$x$$变化时,它首先改变$$y$$,然后$$y$$的变化再改变$$z$$。

现在,我们不再尝试一次性对所有内容进行微分,而是通过链式法则将问题分解为更小的部分。

$$\frac{dz}{dx}=\frac{dz}{dy}\times\frac{dy}{dx}$$

现在让我们分别计算每个部分。

由于

z=y^3,

我们得到

$$\frac{dz}{dy}=3y^2$$.

同样,由于

y=x^2,

$$\frac{dy}{dx}=2x$$.

将它们相乘,

$$\frac{dz}{dx}=3y^2\times2x$$.

最后,我们知道

因此将其代入方程。

$$\frac{dz}{dx}=3(x^2)^2\times2x=6x^5$$.

我们可以在这里观察到的重要一点是,我们从未一次性对整个表达式进行微分。

相反,我们将问题分解为更小的导数,逐个解决,然后将它们相乘。

在我们的神经网络中,我们将使用完全相同的理念。

唯一的不同是,现在链式法则的链条稍长一些。

使用经典微分法逐步求解

现在我们已经理解了链式法则,接下来让我们计算每个参数的偏导数。

直到现在,我们使用特定的权重和偏置值来理解前向传播的工作原理。然而,我们的目标是从数据中学习这些值。

因此,我们不再使用固定值,而是首先用参数来表示它们。

我们的神经网络输出由以下公式给出:

$$ \hat{y}=w_3a_1+w_4a_2+b_3 $$

$$ a_1=\mathrm{ReLU}(z_1) $$

$$ z_1=w_1x+b_1 $$

$$ a_2=\mathrm{ReLU}(z_2) $$

$$ z_2=w_2x+b_2 $$

使用这个输出,我们可以计算均方误差(MSE),这是神经网络的损失函数。

MSE 的一般公式为:

$$ L(w_1,w_2,w_3,w_4,b_1,b_2,b_3)=\frac{1}{n}\sum_{i=1}^{n}(y_i-\hat{y}_i)^2 $$

现在,让我们将预测公式代入损失函数中。

$$ L(w_1,w_2,w_3,w_4,b_1,b_2,b_3)=\frac{1}{n}\sum_{i=1}^{n}\left(y_i-\left(w_3a_{1i}+w_4a_{2i}+b_3\right)\right)^2 $$

$$ a_{1i}=\mathrm{ReLU}(w_1x_i+b_1) $$

$$ a_{2i}=\mathrm{ReLU}(w_2x_i+b_2) $$

完整的损失函数变为:

$$ L(w_1,w_2,w_3,w_4,b_1,b_2,b_3)=\frac{1}{n}\sum_{i=1}^{n}\left(y_i-\left(w_3\mathrm{ReLU}(w_1x_i+b_1)+w_4\mathrm{ReLU}(w_2x_i+b_2)+b_3\right)\right)^2 $$

注意:水平滚动以查看完整公式。

现在,让我们开始计算任意一个参数的偏导数,先从 $w_1$ 开始。

因此,我们需要计算:

$$ \frac{\partial}{\partial w_1}\left[\frac{1}{n}\sum_{i=1}^{n}\left(y_i-\left(w_3\mathrm{ReLU}(w_1x_i+b_1)+w_4\mathrm{ReLU}(w_2x_i+b_2)+b_3\right)\right)^2\right] $$

这个方程看起来难以解决。如何从这样一个复杂的方程中找到对 $w_1$ 的偏导数?

让我们使用已知的微分思想逐步简化问题。

我们希望计算:

$$ \frac{\partial L}{\partial w_1} $$

将损失函数代入导数中:

$$ \frac{\partial}{\partial w_1} \left( (y_i-\hat{y}_i)^2 \right) $$

请注意,我们暂时不代入 $\hat{y}_i$ 的完整表达式。只有在必要时才会这样做。

由于 $\frac{1}{n}$ 是常数,我们知道它可以移到导数外面。

求和也是线性的,因此导数可以穿过求和项。

我们是什么意思?

这意味着在求和中我们相加了许多项,我们可以分别对每一项求导,然后将导数相加。

$$ \frac{\partial L}{\partial w_1} = \frac{1}{n} \sum_{i=1}^{n} \frac{\partial}{\partial w_1} \left( (y_i-\hat{y}_i)^2 \right) $$

现在对平方项求导

设 $A=y_i-\hat{y}_i$,则:

$$ \frac{\partial}{\partial w_1}(A^2) = 2A \frac{\partial A}{\partial w_1} $$

将这个结果代入之前的方程:

$$ \frac{2}{n} A $$

将 $A$ 替换为 $y_i-\hat{y}_i$:

$$ (y_i-\hat{y}_i) $$

对内部表达式求导

我们已知真实目标(实际观测值)$y_i$ 是常数,

$$ \frac{\partial y_i}{\partial w_1} = 0 $$

因此,

$$ -\frac{\partial\hat{y}_i}{\partial w_1} $$

将此结果代入:

$$ -\frac{2}{n} \frac{\partial\hat{y}_i}{\partial w_1} $$

现在对预测值求导 $\frac{\partial\hat{y}_i}{\partial w_1}$

我们知道在神经网络的输出层:

$$ w_3a_{1i} + w_4a_{2i} + b_3 $$

代入隐藏层神经元激活函数的方程:

$$ w_3\mathrm{ReLU}(w_1x_i+b_1) + w_4\mathrm{ReLU}(w_2x_i+b_2) $$

对 $w_1$ 求导

分别对每一项求导。

由于 $w_3$ 是常数,

$$ w_3 \mathrm{ReLU}(w_1x_i+b_1) $$

第二项只包含 $w_2$,因此:

$$ = 0 $$

同时,

$$ \frac{\partial b_3}{\partial w_1}=0 $$

因此,

对ReLU表达式求导

$$ u = w_1x_i + b_1 $$

$$ \mathrm{ReLU}(u) $$

现在进行求导

关于 $w_1$

$$ \frac{du}{dw_1} = x_i $$

现在对激活函数求导。

$$ \frac{d\,\mathrm{ReLU}(u)}{du} $$

$$ \mathrm{ReLU}'(u) $$

这里我们使用链式法则,

$$ \frac{du}{dw_1} $$

代入 $\frac{du}{dw_1} = x_i$

$$ \mathrm{ReLU}'(u)x_i $$

替换 $u$

$$ \mathrm{ReLU}'(w_1x_i + b_1)x_i $$

这个ReLU推导可能会让人困惑,让我们放慢脚步,看看我们实际上在这里做了什么。

我们知道ReLU激活函数并不直接依赖于 $w_1$。

它依赖于 $w_1x_i + b_1$ 的值。

同时,表达式 $w_1x_i + b_1$ 依赖于 $w_1$。

因此当 $w_1$ 改变时,它首先改变 $w_1x_i + b_1$,这又改变了ReLU的输出。

这正是我们需要使用链式法则的情况。

因此,为了找到ReLU如何随 $w_1$ 变化,我们首先找到 $w_1x_i + b_1$ 如何随 $w_1$ 变化,然后找到ReLU如何随 $w_1x_i + b_1$ 变化。

最后,我们使用链式法则将这两个结果结合起来。

现在代入回原式

之前我们发现

我们还计算了

$$ \mathrm{ReLU}'(w_1x_i + b_1) $$

$$ x_i $$

最终结果

我们推导出

这告诉我们权重变化时损失函数如何变化。

起初,这个方程可能看起来难以理解,但实际上非常简单。

因为它告诉我们当我们对权重 $w_1$ 做出非常小的改变时,总损失如何变化,这个值被称为梯度,正是梯度下降用来更新权重的。

为了计算这个梯度,方程考虑了数据集中每一个训练样本。

对于每一个训练样本:

$$ (y_i - \hat{y}_i) $$

告诉我们预测值与实际值之间的差距。

$$ w_3 $$

告诉我们第一个隐藏神经元对最终预测的贡献程度。

$$ \mathrm{ReLU}'(w_1x_i + b_1) $$

告诉我们 $w_1$ 的变化是否能通过ReLU激活函数。

$$ x_i $$

告诉我们 $w_1$ 的微小变化对神经元输入的影响程度。

每个训练样本根据这些量贡献自己的梯度。

我们将所有这些单独的贡献相加,由于我们使用的是均方误差(MSE)损失函数,除以 $n$ 得到整个数据集的平均梯度。

这个平均梯度告诉我们 $w_1$ 应该如何调整以减少整体损失,而不是仅仅针对单个训练样本的误差。

结论

如果还记得我们关于简单线性回归的讨论,我们当时只计算了两个参数的偏导数。

在这篇博客中,我们成功推导出

$$ \frac{\partial L}{\partial w_1} $$

尽管推导过程较长,但我们在每一步都使用了已知的微积分思想。

我们只是逐步应用求导,并在需要时使用链式法则。

现在,我们的神经网络还有六个更多参数,每个参数都有自己的偏导数。

那么你觉得呢?

我们需要为每个权重和偏置重复这个整个过程吗?

幸运的是,不需要。

随着神经网络变得更大,手动推导每个梯度会很快变得困难且低效。

必须有一种更好的方法。

好消息是我们不需要任何新的数学知识。

我们只需要一种更好的方法来组织这些计算。

所有内容仍然基于我们整篇文章一直使用的链式法则。

在下一部分中,我们将看到链式法则如何在整个神经网络中被高效应用,从而引出深度学习中最重要的算法之一:反向传播。

希望你从本文中学到了一些东西。如果你对神经网络仍然感到困惑,或者想重新回顾基础知识,可以随时阅读我之前的这篇文章。

如果你觉得这篇文章有帮助,不妨与可能需要它的人分享。

如果你有任何疑问或想法,可以在LinkedIn上评论。

“只要不停止,慢一点也没关系。” — 孔子

感谢阅读,我们将在第二部分再见!

作者:Nikhil Dasari

查看Nikhil Dasari的全部文章

反向传播

,

深度解析

机器学习

神经网络

分享本文

  • 在Facebook上分享
  • 在LinkedIn上分享
  • 在X上分享

Towards Data Science是一份社区出版物。提交你的见解以触达全球受众,并通过TDS作者支付计划获得报酬。

将href更新为你的实际投稿链接

为TDS撰写文章

✦ 结束CTA ✦