try ai
科普
编辑
分享
反馈
  • 反向传播

反向传播

SciencePedia玻尔百科
核心要点
  • 反向传播通过从最终输出开始反向应用链式法则,高效地计算神经网络中的误差梯度。
  • 梯度消失等问题会阻碍深度网络的训练,但可以通过 ReLU 激活函数和残差跳跃连接等创新来解决。
  • 反向传播在数学上等同于伴随方法,这是一种在物理学和工程学中用于从观测效果推断原因的原理。
  • 该算法实现了“可微编程”,使得包括计算机图形渲染器在内的整个计算系统都可以使用梯度进行优化。

引言

训练一个拥有数百万参数的深度神经网络,似乎是一项不可能完成的优化任务。我们如何才能有效地将模型最终输出的功劳或过失归于每一个参数?答案就在于反向传播,这个优雅而强大的算法是深度学习革命的引擎。本文旨在揭开这一关键过程的神秘面纱,通过清晰地解释反向传播的核心逻辑,来应对训练复杂模型这一根本性挑战。旅程始于第一节​​“原理与机制”​​,该部分将算法从其链式法则的数学基础,到其实际实现和使其在深度网络中有效的架构创新,进行了分解说明。随后,第二节​​“应用与跨学科联系”​​揭示了反向传播不仅仅是一种机器学习技巧,而是对一个普遍原则的重新发现,将深度学习与物理学、工程学以及新兴的可微编程范式联系起来。

原理与机制

想象你是一名徒步旅行者,迷失在连绵起伏的浓雾中。你的目标是到达这片地貌的最低点——一个深谷。你无法看清几英尺外的任何方向,但你能感觉到脚下地面的坡度。最明智的策略是始终朝着最陡峭的下坡方向迈出一步。这个被称为梯度下降的简单规则,正是我们训练神经网络的核心。“地貌”是​​损失函数​​,即衡量网络误差的指标,其“山谷”代表一个训练良好的模型。“地面”的坡度不是三维的,而是数百万维的——网络中的每个参数都对应一个维度。我们的任务是找到梯度,这个多维斜率,它告诉我们如何调整每一个参数以减少误差。但是,对于一个如此惊人复杂的机器,我们怎么可能计算出这个梯度呢?答案是一种极其优雅和高效的算法:​​反向传播​​。

链式法则:一场导数的接力赛

从本质上讲,神经网络不过是一个巨大的、深度嵌套的函数。输入数据经过第一层,该层对其进行转换;结果再经过第二层,再次进行转换,依此类推,直到产生最终输出和损失值。在数学上,如果我们将带有参数 WtW_tWt​ 的第 ttt 层的运算表示为 ftf_tft​,那么整个过程就是一个复合函数:L=loss(fL(…f1(x,W1)…,WL))L = \text{loss}(f_L(\dots f_1(x, W_1) \dots, W_L))L=loss(fL​(…f1​(x,W1​)…,WL​))。

要找出深层内部某个参数(比如 W1W_1W1​)的微小变化如何影响最终损失 LLL,我们需要使用微积分的​​链式法则​​。你可以把链式法则想象成一场接力赛。要弄清楚最后一棒选手的最终位置如何取决于第一棒选手的起跑,你必须考虑每一位选手是如何将接力棒传递给下一位的。敏感度沿着链条传递,在每个阶段相乘。对于一个简单的函数链 y=f(u)y = f(u)y=f(u) 和 u=g(x)u = g(x)u=g(x),规则很简单:dydx=dydududx\frac{dy}{dx} = \frac{dy}{du} \frac{du}{dx}dxdy​=dudy​dxdu​。yyy 对 xxx 的敏感度是 yyy 对其直接输入 uuu 的敏感度与 uuu 对其输入 xxx 的敏感度的乘积。

对于神经网络来说,这条链要长得多,而且每个环节都是一个矩阵-向量运算。我们可以将这个计算流程可视化为一个​​计算图​​,这是一个有向图,其中节点是运算(如加法或矩阵乘法),边代表数据的流动。即使对于像逻辑回归这样的简单模型,绘制出计算图也有助于看清最终损失是如何通过一系列步骤(点积、sigmoid 激活和交叉熵计算)依赖于权重的。

自动微分:逆向工作的巧妙之处

所以,我们有了一个计划:使用链式法则。但具体该怎么做呢?一种天真的方法可能是从头开始,即从输入端开始,向前传播敏感度。这被称为​​前向模式自动微分​​,并且是可行的。然而,对于我们的目的来说,它的效率极其低下。这就好比一次只计算一个参数的梯度。对于数百万个参数,我们得等到天荒地老。

这就是反向传播的巧妙之处所在。它是一种更通用技术——​​反向模式自动微分​​——的实例。我们不是从输入开始,而是从最末端开始:单一的标量损失值 LLL。然后,我们沿着计算图向后推导。

让我们用一个神经网络之外的简单例子来具体说明。假设我们想通过最小化误差 f(X)=∥AX−B∥F2f(X) = \|AX-B\|_F^2f(X)=∥AX−B∥F2​ 来找到最佳求解方程 AX=BAX = BAX=B 的矩阵 XXX。我们可以将其分解:首先计算 Z=AXZ = AXZ=AX,然后计算残差 R=Z−BR = Z-BR=Z−B,最后计算损失 f=∑Rij2f = \sum R_{ij}^2f=∑Rij2​。前向传播计算这些值。反向传播则从一个不证自明的事实开始:fff 对其自身的导数是 1。从那里,我们问:fff 是如何依赖于 RRR 的各项的?答案是 ∂f∂R=2R\frac{\partial f}{\partial R} = 2R∂R∂f​=2R。接下来,RRR 是如何依赖于 ZZZ 的?由于 R=Z−BR = Z - BR=Z−B,依赖关系是一一对应的,所以梯度直接通过:∂f∂Z=∂f∂R\frac{\partial f}{\partial Z} = \frac{\partial f}{\partial R}∂Z∂f​=∂R∂f​。最后,ZZZ 是如何依赖于 XXX 的?由于 Z=AXZ=AXZ=AX,一点矩阵微积分知识表明,关于 XXX 的梯度是 A⊤∂f∂ZA^\top \frac{\partial f}{\partial Z}A⊤∂Z∂f​。通过将这些步骤向后链接,我们高效地找到了梯度 ∇Xf=2A⊤(AX−B)\nabla_X f = 2A^\top(AX-B)∇X​f=2A⊤(AX−B)。

这种反向模式方法的美妙之处在于其效率。计算关于所有输入变量的梯度的成本,仅仅是前向传播本身成本的一个小的常数倍。这正是使训练大规模神经网络变得可行的原因。

实践中的反向传播:矩阵转置的交响曲

当我们将这种反向流动的逻辑应用于神经网络时,一个优美的数学结构便浮现出来。前向传播接收一个激活向量 aℓ−1a_{\ell-1}aℓ−1​ 并计算下一个激活向量:aℓ=σ(Wℓaℓ−1+bℓ)a_\ell = \sigma(W_\ell a_{\ell-1} + b_\ell)aℓ​=σ(Wℓ​aℓ−1​+bℓ​)。反向传播则传播损失的梯度,我们称之为 ∇aℓL\nabla_{a_\ell} L∇aℓ​​L。为了得到关于前一层激活的梯度 ∇aℓ−1L\nabla_{a_{\ell-1}} L∇aℓ−1​​L,链式法则告诉我们,梯度信号必须乘以第 ℓ\ellℓ 层变换的​​雅可比矩阵​​。

值得注意的是,这个操作简化为乘以权重矩阵的​​转置​​ Wℓ⊤W_\ell^\topWℓ⊤​,以及激活函数的逐元素导数。梯度的反向流动与数据的正向流动相互镜像,但使用的是转置后的权重矩阵。这种对称性中蕴含着深刻的优雅。

当然,一个真正的实现需要仔细管理计算和内存。为了执行反向传播,我们需要前向传播期间计算出的激活值。这意味着在训练期间,我们必须存储所有中间激活值,这导致内存占用远大于推理期间,因为在推理时我们可以随用随弃。训练期间的峰值内存与网络的深度 (LLL) 成正比,而推理期间则不然。数据结构的选择也很重要;对于稀疏网络,邻接表是高效的,而密集层则得益于矩阵表示的缓存友好性能。我们如何能确定我们对这个复杂算法的实现是正确的呢?我们可以通过将其输出与一种更简单但慢得多的方法(如​​有限差分​​)进行比较来测试它,后者通过微调每个参数并观察损失如何变化来近似导数。

机器中的幽灵:稳定性与梯度消失

这种梯度的反向传播功能强大,但也有其阴暗面。在一个深度网络中,梯度信号被一连串的矩阵重复相乘:WL⊤DL…W2⊤D2W1⊤D1W_L^\top D_L \dots W_2^\top D_2 W_1^\top D_1WL⊤​DL​…W2⊤​D2​W1⊤​D1​。如果这些矩阵的范数平均小于 1,梯度信号在向后穿越网络时将呈指数级缩小。当它到达早期层时,它可能已经小到几乎为零。这就是臭名昭著的​​梯度消失​​问题。网络的早期层停止学习。相反,如果矩阵范数大于 1,信号可能会爆炸式增长,导致训练不稳定——即​​梯度爆炸​​问题。

激活函数的选择是这里的关键因素。几十年来,平滑的 S 形 sigmoid 函数很受欢迎。然而,其导数的最大值仅为 0.250.250.25。这意味着每当梯度通过一个 sigmoid 层时,其大小最多乘以一个 0.25 的因子。在深度网络中,这正是梯度消失的成因。

​​修正线性单元 (ReLU)​​ 的兴起是一项重大突破,其定义为 ϕ(x)=max⁡(0,x)\phi(x) = \max(0, x)ϕ(x)=max(0,x)。对于任何正输入,它的导数就是 1。这使得梯度能够通过激活的神经元而不会被系统性地削弱。它并没有完全解决问题——权重矩阵仍然重要——但它移除了一个导致不稳定的主要元凶。

驯服猛兽:架构上的修复

即使有了更好的激活函数,训练真正深层的网络仍然是一个挑战。解决方案并非来自新的算法,而是一项杰出的架构创新:​​跳跃连接​​。在残差网络 (ResNet) 中,一个块的输出不仅仅是变换 f(x)f(x)f(x) 的结果,而是变换与原始输入之和:y=x+f(x)y = x + f(x)y=x+f(x)。

让我们看看这对反向传播有什么影响。使用链式法则,块输入端的梯度变为:

dLdx=dLdydydx=dLdy(ddx(x)+ddx(f(x)))=dLdy(1+f′(x))\frac{dL}{dx} = \frac{dL}{dy} \frac{dy}{dx} = \frac{dL}{dy} \left( \frac{d}{dx}(x) + \frac{d}{dx}(f(x)) \right) = \frac{dL}{dy} \left( 1 + f'(x) \right)dxdL​=dydL​dxdy​=dydL​(dxd​(x)+dxd​(f(x)))=dydL​(1+f′(x))

注意那个 1+ 项!它为梯度创造了一条直接、无阻碍的路径。即使通过变换 f′(x)f'(x)f′(x) 的梯度非常小,这个 1 也能确保来自输出的梯度 dLdy\frac{dL}{dy}dydL​ 传递到输入端。这条“梯度高速公路”使得学习信号能够流经数百甚至数千层,有效地屠戮了梯度消失这条恶龙。

更深层次的统一:作为最优控制的反向传播

我们从寻找山谷的简单直觉,走到了构建和训练深度神经网络的实际操作。但故事还有一个最后的美丽转折。反向传播不仅仅是训练网络的一个聪明技巧;它是出现在科学其他领域,特别是在最优控制理论中的一个深刻原则的体现。

我们可以将深度网络看作一个离散时间动力系统。状态向量 xtx_txt​ 代表第 ttt 层的激活,网络的方程描述了这个状态的演化:xt+1=ft(xt,Wt)x_{t+1} = f_t(x_t, W_t)xt+1​=ft​(xt​,Wt​)。训练的目标是找到最优的“控制输入”——权重 WtW_tWt​——使得初始状态 x0x_0x0​ 能够导向一个最小化损失函数的最终状态 xTx_TxT​。

在最优控制中,解决此类问题的方法涉及引入​​协态变量​​(或伴随变量)λt\lambda_tλt​,这些变量在时间上向后传播。支配这种反向递归的方程被称为伴随方程。如果为神经网络系统写下伴随方程,一个惊人的发现便会出现:它们与反向传播的方程完全相同。我们一直在追逐的梯度向量 ∇xtL\nabla_{x_t} L∇xt​​L 正是协态变量 λt\lambda_tλt​。

这种联系重构了我们的理解。梯度消失和梯度爆炸问题并非深度学习所独有;它们是协态反向传播中稳定和不稳定动力学的实例。我们面临的挑战和我们发现的解决方案,都是在工程和物理学领域已知数十年的原则的回响。因此,反向传播并非一项孤立的发明,而是对复杂链式系统中归因的一种基本计算模式的重新发现——它是科学通用语言中优美的一部分。

应用与跨学科联系

在我们穿越反向传播原理的旅程之后,你可能会留下这样的印象:它是一个聪明的技巧,一个专为训练人工神经网络而发明的定制算法。但这样想就只见树木,不见森林了。反向传播的真正美妙之处在于它不是一项发明,而是一项发现。它是数学最基本的思想之一——微积分的链式法则——在计算图上的应用。因此,我们可以在科学和工程最令人惊讶的角落里找到它的回响,通常以不同的名称出现,揭示出我们理解复杂系统方式上惊人的一致性。

反向传播到底是什么?它是一套功劳分配的秘方。如果你有一个产生最终结果的长链事件,你如何弄清楚链条中的每个事件对该结果贡献了多少?反向传播给了你答案。它从最终结果开始,一丝不苟地向后推导,一步一步地计算输出对每个先前动作的敏感度。因此,自然界本身也发现了利用“反向”传播信号的用途,这或许不足为奇。在大脑中,当一个动作电位在轴丘处激发时,它不仅会沿着轴突向前传播,还可以反向侵入树突树。这种“反向传播动作电位”是一种主动的、可再生的信号,而非被动的衰减,它依赖于树突中的电压门控离子通道,将关于神经元输出的信息带回其输入处理机制。虽然这在机制上与我们讨论的梯度计算不同,但它是一个美丽的生物学类比,说明了反向流动的信号可以调节系统功能。

从数据中编织智能

在其最熟悉的形式中,反向传播是现代机器学习的引擎,使我们能够训练出惊人复杂的网络。思考一下读取基因组——一个庞大的 DNA 序列——的挑战。我们可能想构建一台能够识别功能区域的机器,比如剪接位点,它标志着编码和非编码 DNA 之间的边界。循环神经网络 (RNN) 非常适合这个任务,因为它一次处理一个核苷酸,并维持着对已见内容的“记忆”。当我们训练这样一个模型时,在长 DNA 序列末尾犯的错误必须用来调整序列最开始时涉及的参数。随时间反向传播 (BPTT) 算法使这成为可能,它通过将误差信号在展开的序列中一步步向后传播,来分配责任并指导修正。对于非常长的序列,这在计算上可能非常昂贵,因此通常使用一个名为截断 BPTT 的实用版本,它限制了误差信号在“时间”上向后流动的距离。

反向传播的威力在于它不局限于简单的链或序列。它是一种适用于任意有向无环图的算法。这意味着我们可以构建反映更复杂数据结构的模型,例如语言的解析树或化学分子的层次结构。例如,一个树形 RNN 从树的叶节点向上处理信息至根节点,而反向传播可以同样轻松地沿着分支向下流动,以更新每个节点的共享参数。其基本原理保持不变:链式法则的局部应用,系统性地重复。

这种梯度的反向流动也揭示了微妙且有时会带来问题的动态。在像 Transformer 这样的现代架构中,输入通常使用一组不同频率的正弦和余弦函数进行编码,这种技术被称为位置编码。当我们通过这些函数进行反向传播时,一个有趣的“频谱偏差”便出现了:梯度的大小与波的频率成正比。高频分量产生的梯度比低频分量产生的梯度大指数倍。这意味着网络天生就偏向于首先学习高频细节,这可能是福也可能是祸,具体取决于任务。理解这些由反向传播揭示的动态,对于设计和调试我们最先进的模型至关重要。

通往物理学与工程学的桥梁

几十年来,远在深度学习革命之前,物理学家和工程师们就在使用完全相同的数学工具来解决一个不同的问题:逆问题。他们称之为​​伴随方法​​。逆问题是从观测到的效果推断隐藏原因的挑战。你如何根据地表记录的地震波来绘制地球内部的地图?你如何从一张二维显微镜图片重建一个生物细胞的三维图像?

答案是“反向传播波”。在地震成像中,一种名为逆时偏移 (RTM) 的技术会模拟一个源波在前向通过地球模型传播,然后将记录的地震数据作为源,在时间上向后传播一个波场。当前向场和后向场重合的地方,很可能存在一个反射体。这种反向传播在数学上是前向传播算子的​​伴随​​。这种等效性是深刻的:RTM 中使用的成像条件,涉及场的互相关,是机器学习中梯度计算的物理域模拟,两者都可以在频域中理解为与复共轭场的乘法。

同样的原理也适用于光学。要从一个物体的衍射图样重建该物体,可以在计算上反向传播测量的场。这是通过在频域中应用一个相移滤波器来完成的,而该滤波器的数学形式恰好是前向传播滤波器的复共轭。因此,当一个神经网络反向传播梯度时,它执行的基本操作与地球物理学家成像断层线或光学工程师聚焦全息图是相同的。

现在,这种联系已经形成了一个完整的闭环。我们可以将用于解决逆问题的经典迭代算法,例如迭代收缩阈值算法 (ISTA),“展开”成一个固定深度的神经网络。网络的每一层都模仿算法的一次迭代。然后,我们可以使用反向传播从数据中训练这个网络的参数,从而有效地学习出原始算法的一个更优的、数据驱动的版本。这个被称为学习优化的强大思想,代表了经典信号处理与现代深度学习的美妙结合,而这一切都由反向传播所促成。

万物皆可微

反向传播所带来的真正范式转变是​​可微编程​​的思想。如果一个复杂计算中的每一步都是可微的(或可以被一个可微函数近似),那么整个程序就变成了一个我们可以优化的巨大函数。

计算机图形学就是一个惊人的例子。传统上,将 3D 场景渲染成 2D 图像是一个“前向”过程。但如果我们想做相反的事情——调整一个 3D 模型以匹配一张目标照片呢?这就是可微渲染的领域。通过用平滑的、“软”的近似替换渲染管线中不可微的部分,比如一个像素是否被一个三角形覆盖的二元问题,我们可以使整个过程变得可微。然后,我们就可以真正地将误差(渲染图像与目标图像之间的差异)一路反向传播到 3D 场景的参数,例如模型顶点的位置,并使用基于梯度的方法来优化它们。

这甚至延伸到了优化本身。许多现实世界的问题涉及不完全平滑的目标函数。例如,我们可能想通过在损失函数中加入 L1L_1L1​ 惩罚项 ∣w∣|w|∣w∣ 来鼓励模型具有稀疏参数(许多参数被设置为零)。绝对值函数在零点有一个尖角,是不可微的。反向传播是否遇到了对手?完全没有。我们可以将问题分开:使用反向传播计算损失函数平滑部分的梯度,执行一个标准的梯度步长,然后应用一个称为“近端算子”的特殊校正,它能处理尖锐的、不可微的部分。这个算子具有将小值精确推向零的显著效果,从而实现了所需的稀疏性。反向传播成为一个更强大优化框架中的关键模块,展示了其多功能性。

从生物学到地球物理学,从优化理论到计算机图形学,链式法则以各种伪装出现,提供了一种从结果追溯到原因的通用方法。反向传播仅仅是它最现代、计算能力最强的化身。它证明了支撑所有科学的深刻、统一的原则,并且是一个持续扩展我们创造和发现边界的工具。