反向传播的基本原理
- 基本概念
- 什么是链式法则?
- 反向传播的过程
- 反向传播步骤
- 举例:具体计算梯度
- 1. 前向传播:
- 2. 计算损失:
- 3. 反向传播:
- 为什么梯度的方向是函数值增加最快的方向?
- 1. 梯度的直观理解
- 2. 梯度的定义
- 3. 具体的例子
- 4. 在点 (1, 1) 处的梯度
- 5. 梯度的几何解释
- 6. 数学证明
- 7. 反向传播和梯度的关系
反向传播(Backpropagation, BP)是一种用于训练神经网络的技术。它通过链式法则
计算损失函数相对于每个参数的梯度,从而进行参数更新。
基本概念
反向传播是一种优化算法,用于通过计算梯度来最小化神经网络的损失函数。反向传播的核心思想是使用链式法则来计算损失函数相对于每个网络参数的梯度,从而更新参数以减少损失。
什么是链式法则?
链式法则(Chain Rule)是微积分中的一个重要法则,用于计算复合函数的导数。它告诉我们,如果一个函数 f f f 可以表示为另一个函数 g g g 的复合,即 f ( g ( x ) ) f(g(x)) f(g(x)) ,那么 f f f 对 x x x 的导数可以分解为 f f f 对 g g g 的导数乘以 g g g 对 x x x 的导数。
数学上,链式法则可以表示为:
d d x f ( g ( x ) ) = f ′ ( g ( x ) ) ⋅ g ′ ( x ) \frac{d}{dx} f(g(x)) = f'(g(x)) \cdot g'(x) dxdf(g(x))=f′(g(x))⋅g′(x)
反向传播的过程
假设我们有一个简单的两层神经网络:
- 输入层: x x x
- 隐藏层: h = f ( W x + b ) h = f(Wx + b) h=f(Wx+b) ,其中 W W W 是权重矩阵, b b b 是偏置, f f f 是激活函数。
- 输出层: y ^ = g ( V h + c ) \hat{y} = g(Vh + c) y^=g(Vh+c) ,其中 V V V 是权重矩阵, c c c 是偏置, g g g 是激活函数。
目标是通过最小化损失函数 L ( y ^ , y ) L(\hat{y}, y) L(y^,y) 来训练网络,其中 y y y 是真实标签。
反向传播步骤
-
前向传播(Forward Propagation):
- 计算隐藏层输出: h = f ( W x + b ) h = f(Wx + b) h=f(Wx+b)
- 计算最终输出: y ^ = g ( V h + c ) \hat{y} = g(Vh + c) y^=g(Vh+c)
-
计算损失(Loss Calculation):
- 损失函数: L ( y ^ , y ) L(\hat{y}, y) L(y^,y)
-
反向传播(Backward Propagation):
- 目标:计算损失函数 L L L 相对于所有参数 W , b , V , c W, b, V, c W,b,V,c 的梯度。
举例:具体计算梯度
假设激活函数 f f f 和 g g g 都是简单的线性函数(即 f ( x ) = x f(x) = x f(x)=x 和 g ( x ) = x g(x) = x g(x)=x ),损失函数为均方误差(MSE):
L ( y ^ , y ) = 1 2 ( y ^ − y ) 2 L(\hat{y}, y) = \frac{1}{2} (\hat{y} - y)^2 L(y^,y)=21(y^−y)2
1. 前向传播:
h = W x + b h = Wx + b h=Wx+b
y ^ = V h + c \hat{y} = Vh + c y^=Vh+c
2. 计算损失:
L ( y ^ , y ) = 1 2 ( y ^ − y ) 2 L(\hat{y}, y) = \frac{1}{2} (\hat{y} - y)^2 L(y^,y)=21(y^−y)2
3. 反向传播:
为什么要求导?
求导(计算梯度)是为了直到损失函数L对每个参数的敏感度
。具体来说,梯度告诉我们如果稍微调整一个参数 θ \theta θ,损失L会如何变化。
通过知道这个变化的方向和大小,我们可以调整参数,使得损失函数变小,这也就是优化模型的过程。
对于神经网络来说,输出层的梯度计算是反向传播的起点,因为输出层直接影响损失函数。我们需要知道损失函数对输出层输出的影响,以便逐层传播回去,调整每一层的参数
Step 1: 计算输出层的梯度
对输出层的输出 y ^ \hat{y} y^ 求导:
∂ L ∂ y ^ = y ^ − y \frac{\partial L}{\partial \hat{y}} = \hat{y} - y ∂y^∂L=y^−y
对 V V V 和 c c c 求导:
∂ L ∂ V = ∂ L ∂ y ^ ⋅ ∂ y ^ ∂ V = ( y ^ − y ) ⋅ h \frac{\partial L}{\partial V} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial V} = (\hat{y} - y) \cdot h ∂V∂L=∂y^∂L⋅∂V∂y^=(y^−y)⋅h
∂ L ∂ c = ∂ L ∂ y ^ ⋅ ∂ y ^ ∂ c = ( y ^ − y ) ⋅ 1 = ( y ^ − y ) \frac{\partial L}{\partial c} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial c} = (\hat{y} - y) \cdot 1 = (\hat{y} - y) ∂c∂L=∂y^∂L⋅∂c∂y^=(y^−y)⋅1=(y^−y)
Step 2: 计算隐藏层的梯度
对隐藏层的输出 ( h ) 求导:
∂ L ∂ h = ∂ L ∂ y ^ ⋅ ∂ y ^ ∂ h = ( y ^ − y ) ⋅ V \frac{\partial L}{\partial h} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial h} = (\hat{y} - y) \cdot V ∂h∂L=∂y^∂L⋅∂h∂y^=(y^−y)⋅V
对 W W W 和 b b b 求导:
∂ L ∂ W = ∂ L ∂ h ⋅ ∂ h ∂ W = ( ( y ^ − y ) ⋅ V ) ⋅ x \frac{\partial L}{\partial W} = \frac{\partial L}{\partial h} \cdot \frac{\partial h}{\partial W} = ((\hat{y} - y) \cdot V) \cdot x ∂W∂L=∂h∂L⋅∂W∂h=((y^−y)⋅V)⋅x
∂ L ∂ b = ∂ L ∂ h ⋅ ∂ h ∂ b = ( y ^ − y ) ⋅ V \frac{\partial L}{\partial b} = \frac{\partial L}{\partial h} \cdot \frac{\partial h}{\partial b} = (\hat{y} - y) \cdot V ∂b∂L=∂h∂L⋅∂b∂h=(y^−y)⋅V
更新参数:
使用梯度下降法
更新参数:
W ← W − η ∂ L ∂ W W \leftarrow W - \eta \frac{\partial L}{\partial W} W←W−η∂W∂L
b ← b − η ∂ L ∂ b b \leftarrow b - \eta \frac{\partial L}{\partial b} b←b−η∂b∂L
V ← V − η ∂ L ∂ V V \leftarrow V - \eta \frac{\partial L}{\partial V} V←V−η∂V∂L
c ← c − η ∂ L ∂ c c \leftarrow c - \eta \frac{\partial L}{\partial c} c←c−η∂c∂L
其中, η \eta η 是学习率。
为什么可以使用梯度下降法更新?原理是什么?
梯度下降法是一种优化算法,用于最小化目标函数(在这里是损失函数)。它的基本思想是 沿着目标函数梯度的负方向更新参数 ,因为梯度指示了函数增大的最快方向,而我们希望减少损失函数的值。
具体来说,梯度下降法的更新规则是:
θ ← θ − η ∂ L ∂ θ \theta \leftarrow \theta - \eta \frac{\partial L}{\partial \theta} θ←θ−η∂θ∂L
其中:
- θ \theta θ 是需要更新的参数
- η \eta η 是学习率,控制每次更新的步长
- ∂ L ∂ θ \frac{\partial L}{\partial \theta} ∂θ∂L 是损失函数对参数 θ \theta θ 的梯度
梯度下降法的原理基于以下几点:
- 梯度的方向性:梯度指示了函数增大的方向。为了最小化损失函数,我们沿着梯度的负方向更新参数。
- 迭代更新:通过多次迭代更新参数,逐步逼近损失函数的局部最小值。
- 学习率控制:学习率决定了每次更新的步长。如果步长太大,可能会错过最优点;如果步长太小,收敛速度会很慢。
通过反向传播计算出每个参数的梯度后,我们使用梯度下降法来更新这些参数,使得损失函数逐步减小,从而训练出一个性能更好的模型。
如何理解“梯度指示了函数增大的方向”?
梯度是函数在某一点的导数向量
,表示该点在各个方向上的 变化率 。在一个多维空间中, 梯度向量的方向指向函数值增长最快的方向 。我们来举个简单的二维例子来帮助理解。
假设我们有一个二维函数 f ( x , y ) f(x, y) f(x,y) ,在某个点 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) ,函数值为 f ( x 0 , y 0 ) f(x_0, y_0) f(x0,y0) 。如果我们在该点计算梯度 ∇ f ( x 0 , y 0 ) \nabla f(x_0, y_0) ∇f(x0,y0) ,得到的梯度向量可能是 ( ∂ f / ∂ x , ∂ f / ∂ y ) (\partial f / \partial x, \partial f / \partial y) (∂f/∂x,∂f/∂y)。
这个梯度向量表示在 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 点,函数 f f f 在 x x x 和 y y y 方向上的变化率。梯度的方向就是函数值增加最快的方向,即如果我们沿着梯度的方向移动,函数值会迅速增大。
为了最小化函数值,我们需要沿着梯度的反方向(即梯度的负方向)移动,因为这会使函数值减小。这就是梯度下降法的基本原理。
为什么梯度的方向是函数值增加最快的方向?
1. 梯度的直观理解
我们先从二维空间中的一个简单例子开始,假设我们有一个函数 f ( x , y ) f(x, y) f(x,y) ,其图像是一个地形图,表示一个山的高度。梯度 ∇ f ( x , y ) \nabla f(x, y) ∇f(x,y) 在某点 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 处的方向和大小,表示在该点处函数值变化最快的方向和变化的速度。
2. 梯度的定义
在多维空间中,函数 f f f 的梯度 ∇ f \nabla f ∇f 是一个向量,其每个分量是函数在该方向上的偏导数
:
∇ f = ( ∂ f ∂ x 1 , ∂ f ∂ x 2 , … , ∂ f ∂ x n ) \nabla f = \left( \frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2}, \ldots, \frac{\partial f}{\partial x_n} \right) ∇f=(∂x1∂f,∂x2∂f,…,∂xn∂f)
这个向量在点 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 处的方向,就是 函数值增加最快的方向 。
3. 具体的例子
考虑一个简单的函数 f ( x , y ) = x 2 + y 2 f(x, y) = x^2 + y^2 f(x,y)=x2+y2 ,其梯度是:
∇ f ( x , y ) = ( ∂ f ∂ x , ∂ f ∂ y ) = ( 2 x , 2 y ) \nabla f(x, y) = \left( \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right) = (2x, 2y) ∇f(x,y)=(∂x∂f,∂y∂f)=(2x,2y)
4. 在点 (1, 1) 处的梯度
假设我们在点 ( (1, 1) ) 处,那么梯度就是:
∇ f ( 1 , 1 ) = ( 2 ⋅ 1 , 2 ⋅ 1 ) = ( 2 , 2 ) \nabla f(1, 1) = (2 \cdot 1, 2 \cdot 1) = (2, 2) ∇f(1,1)=(2⋅1,2⋅1)=(2,2)
这个梯度向量 ( 2 , 2 ) (2, 2) (2,2) 指向坐标轴的第一个象限,并且指示了函数 f ( x , y ) f(x, y) f(x,y) 在这个点处增加最快的方向。
5. 梯度的几何解释
如果我们在点 ( 1 , 1 ) (1, 1) (1,1) 沿着梯度方向 ( 2 , 2 ) (2, 2) (2,2) 移动,函数值会迅速增加。具体来说,如果我们沿着梯度的方向小步移动 Δ s \Delta s Δs ,新点的坐标为 ( 1 + Δ s ⋅ 2 , 1 + Δ s ⋅ 2 ) (1 + \Delta s \cdot 2, 1 + \Delta s \cdot 2) (1+Δs⋅2,1+Δs⋅2) 。
6. 数学证明
要证明梯度是函数值增加最快的方向,可以从以下角度考虑:
我们在 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 点沿着一个单位向量 u \mathbf{u} u 的方向移动一小步 Δ s \Delta s Δs ,那么函数值的变化量为:
Δ f = f ( x 0 + Δ s ⋅ u x , y 0 + Δ s ⋅ u y ) − f ( x 0 , y 0 ) \Delta f = f(x_0 + \Delta s \cdot u_x, y_0 + \Delta s \cdot u_y) - f(x_0, y_0) Δf=f(x0+Δs⋅ux,y0+Δs⋅uy)−f(x0,y0)
在 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 点附近,我们可以使用泰勒展开来近似表示函数 f ( x , y ) f(x, y) f(x,y) 的变化。泰勒展开的一阶近似形式为:
f ( x 0 + Δ x , y 0 + Δ y ) ≈ f ( x 0 , y 0 ) + ∂ f ∂ x Δ x + ∂ f ∂ y Δ y f(x_0 + \Delta x, y_0 + \Delta y) \approx f(x_0, y_0) + \frac{\partial f}{\partial x} \Delta x + \frac{\partial f}{\partial y} \Delta y f(x0+Δx,y0+Δy)≈f(x0,y0)+∂x∂fΔx+∂y∂fΔy
泰勒展开是一种用于近似表示函数在某点附近的值的方法。它将一个函数表示为无穷阶导数的级数。泰勒展开的一阶近似形式如下:
f ( x 0 + Δ x ) ≈ f ( x 0 ) + d f d x ( x 0 ) Δ x f(x_0 + \Delta x) \approx f(x_0) + \frac{df}{dx}(x_0) \Delta x f(x0+Δx)≈f(x0)+dxdf(x0)Δx其中, f ( x 0 ) f(x_0) f(x0) 是函数 f ( x ) f(x) f(x) 在点 x 0 x_0 x0 处的值, d f d x ( x 0 ) \frac{df}{dx}(x_0) dxdf(x0) 是函数 f ( x ) f(x) f(x) 在点 x 0 x_0 x0 处的导数。
对于二元函数 f ( x , y ) f(x, y) f(x,y),泰勒展开可以表示为:
f ( x 0 + Δ x , y 0 + Δ y ) ≈ f ( x 0 , y 0 ) + ∂ f ∂ x ( x 0 , y 0 ) Δ x + ∂ f ∂ y ( x 0 , y 0 ) Δ y f(x_0 + \Delta x, y_0 + \Delta y) \approx f(x_0, y_0) + \frac{\partial f}{\partial x}(x_0, y_0) \Delta x + \frac{\partial f}{\partial y}(x_0, y_0) \Delta y f(x0+Δx,y0+Δy)≈f(x0,y0)+∂x∂f(x0,y0)Δx+∂y∂f(x0,y0)Δy
这里, ∂ f ∂ x ( x 0 , y 0 ) \frac{\partial f}{\partial x}(x_0, y_0) ∂x∂f(x0,y0) 和 ∂ f ∂ y ( x 0 , y 0 ) \frac{\partial f}{\partial y}(x_0, y_0) ∂y∂f(x0,y0) 分别表示函数 f ( x , y ) f(x, y) f(x,y) 在点 ( x 0 , y 0 ) (x_0, y_0) (x0,y0) 处的偏导数。
对于给定的步长 Δ x \Delta x Δx 和 Δ y \Delta y Δy ,可以使用泰勒展开来近似计算函数值的变化 Δ f \Delta f Δf 。
将 Δ x = Δ s ⋅ u x \Delta x = \Delta s \cdot u_x Δx=Δs⋅ux 和 Δ y = Δ s ⋅ u y \Delta y = \Delta s \cdot u_y Δy=Δs⋅uy 代入上式,得到:
f ( x 0 + Δ s ⋅ u x , y 0 + Δ s ⋅ u y ) ≈ f ( x 0 , y 0 ) + ∂ f ∂ x ( Δ s ⋅ u x ) + ∂ f ∂ y ( Δ s ⋅ u y ) f(x_0 + \Delta s \cdot u_x, y_0 + \Delta s \cdot u_y) \approx f(x_0, y_0) + \frac{\partial f}{\partial x} (\Delta s \cdot u_x) + \frac{\partial f}{\partial y} (\Delta s \cdot u_y) f(x0+Δs⋅ux,y0+Δs⋅uy)≈f(x0,y0)+∂x∂f(Δs⋅ux)+∂y∂f(Δs⋅uy)
进一步整理可得:
f ( x 0 + Δ s ⋅ u x , y 0 + Δ s ⋅ u y ) ≈ f ( x 0 , y 0 ) + ∂ f ∂ x u x Δ s + ∂ f ∂ y u y Δ s f(x_0 + \Delta s \cdot u_x, y_0 + \Delta s \cdot u_y) \approx f(x_0, y_0) + \frac{\partial f}{\partial x} u_x \Delta s + \frac{\partial f}{\partial y} u_y \Delta s f(x0+Δs⋅ux,y0+Δs⋅uy)≈f(x0,y0)+∂x∂fuxΔs+∂y∂fuyΔs
由于 ∇ f = ( ∂ f ∂ x , ∂ f ∂ y ) \nabla f = \left( \frac{\partial f}{\partial x}, \frac{\partial f}{\partial y} \right) ∇f=(∂x∂f,∂y∂f) ,可以将上式改写为:
f ( x 0 + Δ s ⋅ u x , y 0 + Δ s ⋅ u y ) ≈ f ( x 0 , y 0 ) + ∇ f ⋅ u ⋅ Δ s f(x_0 + \Delta s \cdot u_x, y_0 + \Delta s \cdot u_y) \approx f(x_0, y_0) + \nabla f \cdot \mathbf{u} \cdot \Delta s f(x0+Δs⋅ux,y0+Δs⋅uy)≈f(x0,y0)+∇f⋅u⋅Δs
为了最大化 Δ f \Delta f Δf ,我们需要最大化 ∇ f ( x 0 , y 0 ) ⋅ u \nabla f(x_0, y_0) \cdot \mathbf{u} ∇f(x0,y0)⋅u 。由于 u \mathbf{u} u 是单位向量,其模为1,最大化点积意味着 u \mathbf{u} u 必须与 ∇ f ( x 0 , y 0 ) \nabla f(x_0, y_0) ∇f(x0,y0) 同向。因此,梯度的方向就是函数值增加最快的方向。
7. 反向传播和梯度的关系
在反向传播中,我们利用梯度信息来更新模型的参数。通过计算损失函数相对于每个参数的梯度,我们知道每个参数变化的方向和大小,从而调整参数使损失函数减小。具体步骤如下:
- 计算损失函数的梯度:反向传播计算每个参数的梯度。
- 沿梯度的反方向更新参数:为了最小化损失函数,我们沿梯度的反方向移动参数。
这样,我们就逐步调整模型,使其性能越来越好。