深度学习:反向传播算法简介
反向传播算法简介
链式法则
-
在这个线性拟合示例中,我们通过线性方程 ( y = w x + b y = wx + b y=wx+b ) 来预测 ( y y y ) 的值,其中 ($ w$ ) 和 ( $b $) 是模型参数,( x x x ) 是输入变量。为了优化模型的预测性能,我们使用了最小二乘法作为损失函数。损失函数 ( L L L ) 定义为 ( L = 1 2 ( y − y gt ) 2 L = \frac{1}{2}(y - y_{\text{gt}})^2 L=21(y−ygt)2 ),其中 ($ y_{\text{gt}}$ ) 代表 ($ y$ ) 的真实值。
-
在本例中,输入值 ($ x$ ) 为$ 1.5$,真实 ( y ) 值 ( y gt y_{\text{gt}} ygt ) 为 0.8。模型参数 ( w ) 和 ( b ) 的初始值分别为 0.8 和 0.2。基于这些参数,我们可以计算出 ( $y = 0.8 \times 1.5 + 0.2 = 1.4 KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲。进而计算损失函数 \( L$ ) 的值为 ( 0.18 0.18 0.18 )。
-
为了优化模型参数 ( w ) 和 ( b ),我们需要计算损失函数 ( L ) 关于这两个参数的梯度,即偏导数。使用梯度下降算法,参数更新的方向应当逆着梯度的方向。
-
计算 ( ∂ L ∂ y \frac{\partial L}{\partial y} ∂y∂L ):损失函数对预测值 ( y y y ) 的偏导数为 ( ∂ L ∂ y = y − y gt \frac{\partial L}{\partial y} = y - y_{\text{gt}} ∂y∂L=y−ygt )。在当前参数下,这个偏导数为 ( 1.4 − 0.8 = 0.6 1.4 - 0.8 = 0.6 1.4−0.8=0.6 )。
-
应用链式法则计算 ( ∂ L ∂ w \frac{\partial L}{\partial w} ∂w∂L ) 和 ( ∂ L ∂ b \frac{\partial L}{\partial b} ∂b∂L ):
- 对 ( w w w ) 的偏导:由于 ( y = w x + b y = wx + b y=wx+b ),因此 ( ∂ y ∂ w = x \frac{\partial y}{\partial w} = x ∂w∂y=x )。所以 ( ∂ L ∂ w = ∂ L ∂ y ⋅ ∂ y ∂ w = 0.6 × 1.5 = 0.9 \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial w} = 0.6 \times 1.5 = 0.9 ∂w∂L=∂y∂L⋅∂w∂y=0.6×1.5=0.9 )。
- 对 ( b b b ) 的偏导:由于 ( y = w x + b y = wx + b y=wx+b ),因此 ($ \frac{\partial y}{\partial b} = 1$ )。所以 ($ \frac{\partial L}{\partial b} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial b} = 0.6 \times 1 = 0.6$ )。
-
更新 ( w w w ) 和 ( b b b ):使用梯度下降算法,我们可以更新 ($ w$ ) 和 ( b b b )。如果设学习率 ( ϵ \epsilon ϵ ) 为一个小常数,比如 0.1,则参数更新公式为:
- ( w ← w − ϵ ⋅ ∂ L ∂ w = 0.8 − 0.1 × 0.9 = 0.71 w \gets w - \epsilon \cdot \frac{\partial L}{\partial w} = 0.8 - 0.1 \times 0.9 = 0.71 w←w−ϵ⋅∂w∂L=0.8−0.1×0.9=0.71 )
- ( b ← b − ϵ ⋅ ∂ L ∂ b = 0.2 − 0.1 × 0.6 = 0.14 b \gets b - \epsilon \cdot \frac{\partial L}{\partial b} = 0.2 - 0.1 \times 0.6 = 0.14 b←b−ϵ⋅∂b∂L=0.2−0.1×0.6=0.14 )
-
-
通过上述步骤,我们沿着损失函数的梯度方向逐步调整 ( $w $) 和 ( b b b ),以期达到最小化损失函数 ( $L $),从而使模型预测值 ( y y y ) 更接近真实值 ( y gt y_{\text{gt}} ygt )。这种基于梯度的优化方法是机器学习中常用的参数调整手段,有效地指导了模型的学习过程。
反向传播
- 在这个线性拟合的示例中,我们采用了最小二乘法作为损失函数,通过反向传播算法来优化参数 ( w w w ) 和 ( b b b )。反向传播算法是一种高效的网络参数训练方法,主要用于计算损失函数关于各参数的梯度。
步骤分解:
-
前向传播:
- 输入 ($ x $) 为 1.5 1.5 1.5。
- 参数 ( w w w ) 和 ( $b $) 的初始值分别为 0.8 0.8 0.8 和$ 0.2$。
- 根据线性方程 ($ y = wx + b KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲,计算得到的预测值 \( y $) 为 ( 0.8 × 1.5 + 0.2 = 1.4 0.8 \times 1.5 + 0.2 = 1.4 0.8×1.5+0.2=1.4 )。
- 真实值 ($ y_{\text{gt}}$ ) 为 0.8 0.8 0.8。
- 损失函数 ( L ) 为 ($ \frac{1}{2} (y - y_{\text{gt}})^2 = \frac{1}{2} (1.4 - 0.8)^2 = 0.18$ )。
-
反向传播计算梯度:
- 损失函数 ( $L $) 对 ( $y KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲ 的偏导 \( \frac{\partial L}{\partial y} = y - y_{\text{gt}} = 1.4 - 0.8 = 0.6$ )。
- 根据链式法则:
- ($ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial w} = 0.6 \times 1.5 = 0.9 $)。
- ( ∂ L ∂ b = ∂ L ∂ y × ∂ y ∂ b = 0.6 × 1 = 0.6 \frac{\partial L}{\partial b} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial b} = 0.6 \times 1 = 0.6 ∂b∂L=∂y∂L×∂b∂y=0.6×1=0.6 )。
-
参数更新:
- 设定学习率 ( ϵ \epsilon ϵ ) 为 0.1 0.1 0.1。
- 更新 (
w
w
w ) 和 (
b
b
b ):
- ( w ← w − ϵ × ∂ L ∂ w = 0.8 − 0.1 × 0.9 = 0.71 w \gets w - \epsilon \times \frac{\partial L}{\partial w} = 0.8 - 0.1 \times 0.9 = 0.71 w←w−ϵ×∂w∂L=0.8−0.1×0.9=0.71 )。
- ( b ← b − ϵ × ∂ L ∂ b = 0.2 − 0.1 × 0.6 = 0.14 b \gets b - \epsilon \times \frac{\partial L}{\partial b} = 0.2 - 0.1 \times 0.6 = 0.14 b←b−ϵ×∂b∂L=0.2−0.1×0.6=0.14 )。
-
重新计算预测和损失:
- 使用新的参数 ($ w = 0.71$ ) 和 ( $b = 0.14 $),计算新的 ( y = 0.71 × 1.5 + 0.14 = 1.205 y = 0.71 \times 1.5 + 0.14 = 1.205 y=0.71×1.5+0.14=1.205 )。
- 新的损失 ( L = 1 2 ( 1.205 − 0.8 ) 2 = 0.082 L = \frac{1}{2} (1.205 - 0.8)^2 = 0.082 L=21(1.205−0.8)2=0.082 ),较原始损失降低。
结论
- 通过应用反向传播算法,我们不仅优化了参数 ($ w$ ) 和 ($ b$ ),还显著降低了模型的预测误差和损失值。这种从后向前计算梯度,并更新参数的方法,是机器学习中用于优化神经网络的核心技术之一,它依赖于链式法则来高效地计算各参数的梯度,从而指导参数向损失函数减小的方向调整。这种方法的实现,确保了模型预测值 ( $y $) 更加接近真实值 ( y gt y_{\text{gt}} ygt ),体现了反向传播算法在参数优化中的强大能力和重要性。
- 这个例子介绍了一个包含两个线性变换层的简单神经网络,其中输入 ( x x x ) 首先通过第一个线性变换 ($ y_1 = w_1x + b_1$ ) 得到中间变量 ( y 1 y_1 y1 ),然后 ( y 1 y_1 y1 ) 经过第二个线性变换 ( y 2 = w 2 y 1 + b 2 y_2 = w_2y_1 + b_2 y2=w2y1+b2 ) 得到输出 ( y 2 y_2 y2 )。这种层叠的线性变换体现了神经网络结构的基本形式,其中 ( $w_1, b_1, w_2, b_2 $) 是需要学习的参数。
正向传播
- 第一层变换:( y 1 = w 1 × x + b 1 y_1 = w_1 \times x + b_1 y1=w1×x+b1 )
- 第二层变换:( y 2 = w 2 × y 1 + b 2 y_2 = w_2 \times y_1 + b_2 y2=w2×y1+b2 )
损失函数
- 损失函数 ( L ) 用于衡量预测输出 ( y 2 y_2 y2 ) 与真实值 ($ y_{\text{gt}}$ ) 之间的差异,通常用于训练过程中优化模型参数。
反向传播算法
- 反向传播算法是一种有效计算网络中所有权重的梯度的方法。该算法使用链式法则反向传递误差信息,从而得到关于损失函数的每个参数的梯度。
- 计算损失函数对 ( y 2 y_2 y2 ) 的偏导:( ∂ L ∂ y 2 \frac{\partial L}{\partial y_2} ∂y2∂L ),这是计算其他梯度的起点。
- 应用链式法则计算对 ( $w_2 KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲ 和 \( b_2 $) 的偏导:
- ( $\frac{\partial L}{\partial w_2} = \frac{\partial L}{\partial y_2} \times \frac{\partial y_2}{\partial w_2} = \frac{\partial L}{\partial y_2} \times y_1 $)
- ($ \frac{\partial L}{\partial b_2} = \frac{\partial L}{\partial y_2} \times \frac{\partial y_2}{\partial b_2} = \frac{\partial L}{\partial y_2} \times 1$ )
- 计算 (
y
1
y_1
y1 ) 对 (
w
1
w_1
w1 ) 和 ($ b_1$ ) 的偏导需要先求 (
∂
L
∂
y
1
\frac{\partial L}{\partial y_1}
∂y1∂L ):
- ( ∂ L ∂ y 1 = ∂ L ∂ y 2 × ∂ y 2 ∂ y 1 = ∂ L ∂ y 2 × w 2 \frac{\partial L}{\partial y_1} = \frac{\partial L}{\partial y_2} \times \frac{\partial y_2}{\partial y_1} = \frac{\partial L}{\partial y_2} \times w_2 ∂y1∂L=∂y2∂L×∂y1∂y2=∂y2∂L×w2 )
- 继续应用链式法则:
- ( ∂ L ∂ w 1 = ∂ L ∂ y 1 × ∂ y 1 ∂ w 1 = ∂ L ∂ y 1 × x \frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y_1} \times \frac{\partial y_1}{\partial w_1} = \frac{\partial L}{\partial y_1} \times x ∂w1∂L=∂y1∂L×∂w1∂y1=∂y1∂L×x )
- ( ∂ L ∂ b 1 = ∂ L ∂ y 1 × ∂ y 1 ∂ b 1 = ∂ L ∂ y 1 × 1 \frac{\partial L}{\partial b_1} = \frac{\partial L}{\partial y_1} \times \frac{\partial y_1}{\partial b_1} = \frac{\partial L}{\partial y_1} \times 1 ∂b1∂L=∂y1∂L×∂b1∂y1=∂y1∂L×1 )
结论
- 反向传播是一种从输出层到输入层依次计算梯度的方法,此过程确保了每个参数的梯度都可以通过已计算的梯度进行有效计算。这种从后向前的计算过程不仅优化了计算效率,而且在训练深层神经网络时尤为关键,因为它可以准确快速地更新网络中的所有权重。通过连续的迭代,这种方法逐步减小损失函数值,从而提高了模型的预测准确性和性能。
计算图
- 在深度学习框架中,计算图(Computational Graph)是一种表达和计算神经网络中各个变量间关系的有效工具。如图所示,它以图形的方式描绘了从输入变量到输出结果的整个计算过程。计算图的优势在于它将复杂的计算分解成一系列简单的、可复用的操作单元,这些单元通常涉及基本的数学运算,如乘法和加法。
计算图的构建
-
变量和操作的定义:
- 输入 ( x x x )、权重 ($ w_1$ ) 和偏置 ( b 1 b_1 b1 ) 是首批变量。
- 首个操作是乘法:定义 ( u 1 = w 1 × x u_1 = w_1 \times x u1=w1×x )。
- 接下来,通过加法得到第一个线性变换的输出:( y 1 = u 1 + b 1 y_1 = u_1 + b_1 y1=u1+b1 )。
-
进一步的操作链:
- 第二层的权重 ( w 2 w_2 w2 ) 和偏置 ( b 2 b_2 b2 ) 类似地参与运算。
- 第二个乘法操作定义为 ( u 2 = w 2 × y 1 u_2 = w_2 \times y_1 u2=w2×y1 )。
- 第二个线性变换的输出是 ( y 2 = u 2 + b 2 y_2 = u_2 + b_2 y2=u2+b2 )。
计算图的优点
- 模块化:计算图将整个计算过程拆分成独立的模块。每个模块执行一个基本的算术操作,如乘法或加法,使得整个过程清晰且易于管理。
- 复用性:由于每个操作单元的简单性和一致性,计算图中的结构可以在不同的模型和不同的问题中被复用。
- 易于优化:计算图的结构使得自动微分技术(如反向传播)可以有效地应用,从而自动计算梯度,这对于使用梯度下降等优化算法至关重要。
正向传播和反向传播
- 正向传播:如图所示的过程,正向传播是从输入 ( $x $) 开始,顺序执行所有定义的操作,直至计算出最终输出 ( y 2 y_2 y2 )。
- 反向传播:反向传播则从损失函数 ( L L L ) 开始,逆向通过每一个操作计算梯度。这在计算图中表现为对每一个操作的微分求解,利用链式法则传递梯度。
结论
- 计算图不仅为复杂的神经网络提供了一个直观且系统的视图,而且通过其结构的高度模块化,大大提高了计算效率和灵活性。在实际应用中,这意味着更快的计算速度,更清晰的逻辑,以及在进行网络设计和调试时更高的透明度。
- 在深度学习中,计算图是一种描述和计算复杂函数的工具,特别适用于神经网络中的梯度计算。这个计算过程可以分为正向传播和反向传播两个主要阶段。正向传播过程中计算每个变量的输出值,而反向传播则用于计算损失函数 ( L L L ) 对每个参数的偏导数,即梯度。
正向传播
正向传播按照从输入层到输出层的顺序逐层计算中间变量和输出值:
- 输入 ( x x x ) 通过权重 ( w 1 w_1 w1 ) 计算得到中间变量 ( $u_1 = w_1 \times x $)。
- 将 ( $u_1 KaTeX parse error: Can't use function '\)' in math mode at position 1: \̲)̲ 与偏置 \( b_1$ ) 相加,得到下一层的输入 ( y 1 = u 1 + b 1 y_1 = u_1 + b_1 y1=u1+b1 )。
- ( y 1 y_1 y1 ) 再经过第二层的权重 ( w 2 w_2 w2 ) 计算得到 ( u 2 = w 2 × y 1 u_2 = w_2 \times y_1 u2=w2×y1 )。
- ( u 2 u_2 u2 ) 加上偏置 ($ b_2$ ) 得到最终输出 ( y 2 = u 2 + b 2 y_2 = u_2 + b_2 y2=u2+b2 )。
反向传播(梯度计算)
反向传播是计算图中用于求解参数梯度的关键步骤,其核心是链式法则:
- 损失函数 ( L L L ) 关于输出 ( y 2 y_2 y2 ) 的偏导数(记为 ($ \frac{\partial L}{\partial y_2} $))是计算开始的点。
- 由于 ( y 2 = u 2 + b 2 y_2 = u_2 + b_2 y2=u2+b2 ),我们有 ( $\frac{\partial L}{\partial u_2} = \frac{\partial L}{\partial y_2} \times \frac{\partial y_2}{\partial u_2} = \frac{\partial L}{\partial y_2} \times 1 = \frac{\partial L}{\partial y_2} $)。
- ($ \frac{\partial L}{\partial b_2} $) 同样直接等于 ( $\frac{\partial L}{\partial y_2} $),因为 ( $y_2 $) 对 ( b 2 b_2 b2 ) 的偏导数是 1。
进一步反向传播到更早的层:
- ( ∂ L ∂ y 1 = ∂ L ∂ u 2 × ∂ u 2 ∂ y 1 = ∂ L ∂ y 2 × w 2 \frac{\partial L}{\partial y_1} = \frac{\partial L}{\partial u_2} \times \frac{\partial u_2}{\partial y_1} = \frac{\partial L}{\partial y_2} \times w_2 ∂y1∂L=∂u2∂L×∂y1∂u2=∂y2∂L×w2 )。
- 对 ( $w_1 $) 和 ( $b_1 $) 的梯度计算利用 (
∂
L
∂
y
1
\frac{\partial L}{\partial y_1}
∂y1∂L ):
- ( ∂ L ∂ w 1 = ∂ L ∂ y 1 × ∂ y 1 ∂ w 1 = ∂ L ∂ y 1 × x \frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial y_1} \times \frac{\partial y_1}{\partial w_1} = \frac{\partial L}{\partial y_1} \times x ∂w1∂L=∂y1∂L×∂w1∂y1=∂y1∂L×x )。
- ($ \frac{\partial L}{\partial b_1} = \frac{\partial L}{\partial y_1} \times \frac{\partial y_1}{\partial b_1} = \frac{\partial L}{\partial y_1} \times 1$ )。
参数更新
利用上述计算得到的梯度,可以更新每个参数:
- ( $w_1 \gets w_1 - \alpha \times \frac{\partial L}{\partial w_1} $)
- ( $b_1 \gets b_1 - \alpha \times \frac{\partial L}{\partial b_1} $)
- ( w 2 ← w 2 − α × ∂ L ∂ w 2 w_2 \gets w_2 - \alpha \times \frac{\partial L}{\partial w_2} w2←w2−α×∂w2∂L )
- ( b 2 ← b 2 − α × ∂ L ∂ b 2 b_2 \gets b_2 - \alpha \times \frac{\partial L}{\partial b_2} b2←b2−α×∂b2∂L )
其中 ($ \alpha $) 是学习率,一个超参数,控制学习的步长。
结论
通过反向传播算法,计算图为参数梯度的高效计算提供了一种结构化方法,确保了深度学习模型可以根据损失函数系统地调整其参数。这种方法是实现神经网络训练的核心技术。
- 在深度学习框架如PyTorch中,计算图通过定义每个运算单元的前向传播和反向传播函数来实现自动微分,从而便于梯度的计算和参数的更新。这种结构化的设计方法不仅确保了计算的准确性,还大幅度提高了计算效率。
前向传播(Forward Pass)
- 在前向传播阶段,函数接收输入变量
x
和y
,并执行运算z = x * y
来计算输出。这里,z
是x
和y
的乘积。在 PyTorch 中,这个过程是通过定义一个自定义的torch.autograd.Function
类来实现的。例如,类Multiply
定义了如何计算两个输入的乘积。这个类中的forward
方法直接进行计算并返回结果z
。
class Multiply(torch.autograd.Function):
@staticmethod
def forward(ctx, x, y):
ctx.save_for_backward(x, y)
z = x * y
return z
反向传播(Backward Pass)
反向传播是深度学习中用于计算梯度的关键技术。在 Multiply
类中,backward
方法计算传入的上游梯度 grad_z
关于每个输入的偏导数。这些偏导数是通过应用链式法则得出的:
- 对于
x
的梯度(grad_x
)计算为grad_z * y
。 - 对于
y
的梯度(grad_y
)计算为grad_z * x
。
这种方法确保了损失函数 L
对 x
和 y
的梯度可以通过简单的乘法运算得到,从而为参数更新提供所需的梯度。
@staticmethod
def backward(ctx, grad_z):
x, y = ctx.saved_tensors
grad_x = grad_z * y
grad_y = grad_z * x
return grad_x, grad_y
结论
- 在深度学习框架中,自定义的前向和反向传播方法提供了灵活性和效率,使得框架能够自动计算梯度,并使用这些梯度来执行复杂的优化算法,如梯度下降。这种自动微分机制是现代深度学习框架能够支持复杂模型和大规模训练的基础。通过这种方式,开发者可以更加集中于模型的设计和实验,而不是梯度计算的具体实现细节。
总结
反向传播算法(Back-Propagation, 简称BP算法)是深度学习中最为关键的优化技术之一。其主要功能是高效地计算神经网络中所有参数的梯度。这一过程是机器学习模型学习从输入到输出的映射关系的基础,特别是在复杂的深度神经网络中。
BP算法的核心原理
-
正向传播:在正向传播阶段,数据通过网络层按照初始化的参数(如权重和偏置)进行传递,每一层的输出成为下一层的输入,直到最后一层输出预测结果。
-
计算损失:损失函数计算实际输出与期望输出之间的差异,这个值表明了当前网络的性能,即预测错误的程度。
-
反向传播:在反向传播阶段,计算损失函数关于每个参数的梯度。这一计算过程从输出层开始,逆向经过隐藏层,直到输入层。利用链式法则,可以系统地计算出网络中所有权重的梯度。
计算图与模块化运算
在实际的计算机实现中,反向传播算法通常采用计算图来进行模块化的运算。计算图是一种图形化表示方法,用于描绘所有的计算步骤,每一个节点代表运算操作(如加、乘),每一条边代表数据的流向(如张量)。这样的表示方法不仅直观,而且利于算法实现,因为:
- 自动微分:计算图配合自动微分技术,使得梯度的计算自动化,准确和高效。
- 模块化设计:每个计算节点可以看作是一个独立的模块,具有特定的功能,如执行特定的数学运算。这种模块化设计使得计算图易于扩展和维护。
梯度下降与参数更新
一旦得到了损失函数关于所有参数的梯度,就可以使用梯度下降算法来更新网络参数,以最小化损失函数。参数更新的基本公式是:
[
θ
new
=
θ
old
−
η
⋅
∇
L
(
θ
)
\theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla L(\theta)
θnew=θold−η⋅∇L(θ)
]
其中 ( θ \theta θ) 表示网络参数,( η \eta η) 是学习率,( ∇ L ( θ ) \nabla L(\theta) ∇L(θ)) 是参数的梯度。这一步骤是训练过程中不断迭代的,直至网络性能达到最优或满足其他停止条件。
结论
反向传播算法是实现深度学习模型优化的基石,它通过精确计算梯度并更新参数,使神经网络能够在各种任务上达到良好的性能。计算图的使用进一步提升了这一过程的效率和可扩展性,是现代深度学习框架如TensorFlow和PyTorch的核心组成部分。