神经网络中的**正向传播**和**反向传播**

想象一下你在学习骑自行车:

  1. 正向传播: 就像是你根据当前的平衡感、速度、脚下的路面情况,以及当前你大脑里“应该怎么做”的感觉(这感觉是你之前练习形成的,可以看作是神经网络的参数/权重),来预测接下来车子会向左倒还是向右倒
  2. 反向传播与梯度下降: 就像是你实际摔倒了(计算出的损失/误差),然后你分析:车子为什么会倒?是因为我身体重心偏左了(某个参数错了)?还是因为车轮打滑了(另一个参数错了)?你根据这个分析,计算出调整重心和握车把力度对避免摔倒有多大的影响(计算梯度),然后根据这个“影响”(梯度)的方向和大小调整你身体的重心和握车把的力度(更新参数),以便下次骑车不容易摔倒。

1. 正向传播:计算输出

目标: 输入一些数据,经过神经网络,得到一个预测结果

核心思想: 正向传播是数据在神经网络中的单向流动。输入数据从输入层开始,经过隐藏层(可能有多个),最终到达输出层,计算出网络的预测结果。

过程:

  • 输入层: 把原始数据(图片像素、身高体重、文本向量等)送进去。假设输入是一个向量 X = [ x 1 , x 2 , … , x n ] T \mathbf{X} = [x_1, x_2, \ldots, x_n]^T X=[x1,x2,,xn]T
  • 隐藏层: 数据从一层流向另一层。以一个简单的两层网络(输入层 -> 隐藏层 -> 输出层)为例。
    • 连接与参数: 神经元之间通过连接线相连,每个连接都有一个权重 W W W 和一个偏置 b b b。这些 W W W b b b 是神经网络学习的参数,决定了信号如何传递。
    • 线性组合: 对于某一层(隐藏层或输出层)的第 j j j 个神经元,它接收到来自前一层所有神经元的信号。
      z j ( l ) = ∑ i = 1 n l − 1 W i j ( l − 1 → l ) x i ( l − 1 ) + b j ( l ) z_j^{(l)} = \sum_{i=1}^{n_{l-1}} W_{ij}^{(l-1 \rightarrow l)} x_i^{(l-1)} + b_j^{(l)} zj(l)=i=1nl1Wij(l1l)xi(l1)+bj(l)
      其中:
      • z j ( l ) z_j^{(l)} zj(l) 是第 l l l 层第 j j j 个神经元的输入总和(加权和)。
      • W i j ( l − 1 → l ) W_{ij}^{(l-1 \rightarrow l)} Wij(l1l) 是从第 l − 1 l-1 l1 层第 i i i 个神经元到第 l l l 层第 j j j 个神经元的权重
      • x i ( l − 1 ) x_i^{(l-1)} xi(l1) 是第 l − 1 l-1 l1 层第 i i i 个神经元的输出(上一层的激活值)。
      • b j ( l ) b_j^{(l)} bj(l) 是第 l l l 层第 j j j 个神经元的偏置
      • ( ⋅ ) ( l ) (·)^{(l)} ()(l) 表示第 l l l 层的变量。
      • n l − 1 n_{l-1} nl1 是第 l − 1 l-1 l1 层的神经元数量。
      • ( l − 1 → l ) (l-1 \rightarrow l) (l1l) 表示权重连接的方向和层号。
    • 激活函数: 计算完线性组合的总和 z j ( l ) z_j^{(l)} zj(l) 后,需要通过一个非线性激活函数 f f f 来得到神经元的输出(激活值)。激活值 a j ( l ) a_j^{(l)} aj(l) 是神经元的输出。
      a j ( l ) = f ( z j ( l ) ) = f ( ∑ i = 1 n l − 1 W i j ( l − 1 → l ) x i ( l − 1 ) + b j ( l ) ) a_j^{(l)} = f(z_j^{(l)}) = f\left(\sum_{i=1}^{n_{l-1}} W_{ij}^{(l-1 \rightarrow l)} x_i^{(l-1)} + b_j^{(l)}\right) aj(l)=f(zj(l))=f(i=1nl1Wij(l1l)xi(l1)+bj(l))
      常用的激活函数有:
      • Sigmoid: f ( z ) = 1 1 + e − z f(z) = \frac{1}{1 + e^{-z}} f(z)=1+ez1,输出范围 ( 0 , 1 ) (0, 1) (0,1)
      • ReLU: f ( z ) = max ⁡ ( 0 , z ) f(z) = \max(0, z) f(z)=max(0,z),输出范围 [ 0 , + ∞ ) [0, +\infty) [0,+)
      • Tanh: f ( z ) = e z − e − z e z + e − z f(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}} f(z)=ez+ezezez,输出范围 ( − 1 , 1 ) (-1, 1) (1,1)
    • 传递: 上一层的输出 a j ( l ) a_j^{(l)} aj(l) 成为下一层的输入 x j ( l + 1 ) x_j^{(l+1)} xj(l+1)。如此反复,直到:
  • 输出层: 数据流到最后一个隐藏层后,到达输出层。输出层的激活函数选择取决于任务(例如,分类问题常用 Softmax)。

原理: 正向传播就是将输入数据 X \mathbf{X} X 通过一系列线性变换(加权求和 + 偏置)非线性变换(激活函数),层层传递,最终得到一个输出向量 Y \mathbf{Y} Y。这个 Y \mathbf{Y} Y 是网络对输入 X \mathbf{X} X 的“看法”或“预测”。整个网络可以看作一个复杂的函数 F ( X ; Θ ) F(\mathbf{X}; \Theta) F(X;Θ),其中 Θ \Theta Θ 是网络所有权重 W W W 和偏置 b b b 的集合。

损失函数:
得到预测输出 Y \mathbf{Y} Y 后,我们需要衡量它与真实标签 T \mathbf{T} T 之间的差距。这就是损失函数 L ( Y , T ) L(\mathbf{Y}, \mathbf{T}) L(Y,T)。例如,对于分类问题常用的二分类交叉熵损失
L = − [ y log ⁡ ( p ) + ( 1 − y ) log ⁡ ( 1 − p ) ] L = - \left[ y \log(p) + (1 - y) \log(1 - p) \right] L=[ylog(p)+(1y)log(1p)]
其中 y y y 是真实标签(0 或 1), p p p 是模型预测的正类概率。对于多个样本,我们通常计算平均损失 L L L
L = 1 N ∑ i = 1 N L i L = \frac{1}{N} \sum_{i=1}^{N} L_i L=N1i=1NLi
其中 N N N 是样本数, L i L_i Li 是第 i i i 个样本的损失。


2. 反向传播与梯度下降:让参数更精确

目标: 计算出每个参数 W W W b b b 对损失 L L L 的“影响度”(梯度),然后利用这个“影响度”来更新参数,使得下一次的预测损失 L L L 更小,即模型“更精确”。

核心思想: 参数是神经网络学习的基础。正向传播时,我们使用已知的参数来计算预测。反向传播和梯度下降的目标是找到最优的参数,使得模型在训练数据上的预测尽可能准确。

过程:

  1. 计算损失: 通过正向传播得到预测 Y \mathbf{Y} Y,并与真实标签 T \mathbf{T} T 比较,计算损失 L L L
  2. 链式法则与反向传播: 这是计算参数梯度的核心。
    • 链式法则: 微积分中的链式法则是计算复合函数导数的工具。神经网络的输出 Y \mathbf{Y} Y 是输入 X \mathbf{X} X 和参数 Θ \Theta Θ 的复杂函数,损失 L L L Y \mathbf{Y} Y 的函数。因此, L L L 对某个参数 θ \theta θ 的梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 可以通过链式法则计算:
      ∂ L ∂ θ = ∂ L ∂ Y ⋅ ∂ Y ∂ θ \frac{\partial L}{\partial \theta} = \frac{\partial L}{\partial \mathbf{Y}} \cdot \frac{\partial \mathbf{Y}}{\partial \theta} θL=YLθY
      或者更一般地,如果 L L L 依赖于 z z z z z z 依赖于 θ \theta θ,则:
      ∂ L ∂ θ = ∂ L ∂ z ⋅ ∂ z ∂ θ \frac{\partial L}{\partial \theta} = \frac{\partial L}{\partial z} \cdot \frac{\partial z}{\partial \theta} θL=zLθz
      这个规则可以推广到多层网络。
    • 反向传播: 从输出层开始,利用链式法则,从后向前计算损失 L L L 对于每个参数(权重 W W W 和偏置 b b b)的梯度 ∂ L ∂ W \frac{\partial L}{\partial W} WL ∂ L ∂ b \frac{\partial L}{\partial b} bL
      • 示例:Sigmoid 输出层与二分类交叉熵损失
        • 损失对输出层输入 z z z 的梯度:
          ∂ L ∂ z j ( L ) = ∂ L ∂ a j ( L ) ⋅ ∂ a j ( L ) ∂ z j ( L ) \frac{\partial L}{\partial z_j^{(L)}} = \frac{\partial L}{\partial a_j^{(L)}} \cdot \frac{\partial a_j^{(L)}}{\partial z_j^{(L)}} zj(L)L=aj(L)Lzj(L)aj(L)
          其中:
          • ∂ L ∂ a j ( L ) \frac{\partial L}{\partial a_j^{(L)}} aj(L)L:损失对输出层第 j j j 个神经元输出 a j ( L ) a_j^{(L)} aj(L) 的梯度。
          • ∂ a j ( L ) ∂ z j ( L ) = f ′ ( z j ( L ) ) \frac{\partial a_j^{(L)}}{\partial z_j^{(L)}} = f^{\prime}(z_j^{(L)}) zj(L)aj(L)=f(zj(L))激活函数 f f f 的导数(对于 Sigmoid, f ′ ( z ) = f ( z ) ⋅ ( 1 − f ( z ) ) f^{\prime}(z) = f(z) \cdot (1 - f(z)) f(z)=f(z)(1f(z)))。
          • ∂ L ∂ a j ( L ) \frac{\partial L}{\partial a_j^{(L)}} aj(L)L 又需要计算:
            ∂ L ∂ a j ( L ) = ∂ L ∂ p ⋅ ∂ p ∂ a j ( L ) \frac{\partial L}{\partial a_j^{(L)}} = \frac{\partial L}{\partial p} \cdot \frac{\partial p}{\partial a_j^{(L)}} aj(L)L=pLaj(L)p
            其中,对于二分类交叉熵损失 L = − [ y log ⁡ ( p ) + ( 1 − y ) log ⁡ ( 1 − p ) ] L = - \left[ y \log(p) + (1 - y) \log(1 - p) \right] L=[ylog(p)+(1y)log(1p)] p = a j ( L ) p = a_j^{(L)} p=aj(L),则:
            ∂ L ∂ p = − ( y p − 1 − y 1 − p ) \frac{\partial L}{\partial p} = - \left( \frac{y}{p} - \frac{1 - y}{1 - p} \right) pL=(py1p1y)
            ∂ p ∂ a j ( L ) = 1 \frac{\partial p}{\partial a_j^{(L)}} = 1 aj(L)p=1
        • 综合起来,损失对输出层输入 z j ( L ) z_j^{(L)} zj(L) 的梯度是:
          ∂ L ∂ z j ( L ) = [ − ( y p − 1 − y 1 − p ) ] ⋅ [ p ⋅ ( 1 − p ) ] \frac{\partial L}{\partial z_j^{(L)}} = \left[ - \left( \frac{y}{p} - \frac{1 - y}{1 - p} \right) \right] \cdot \left[ p \cdot (1 - p) \right] zj(L)L=[(py1p1y)][p(1p)]
      • 传递梯度: 将损失对当前层输出 a j ( l ) a_j^{(l)} aj(l) z j ( l ) z_j^{(l)} zj(l) 的梯度 ∂ L ∂ a j ( l ) \frac{\partial L}{\partial a_j^{(l)}} aj(l)L ∂ L ∂ z j ( l ) \frac{\partial L}{\partial z_j^{(l)}} zj(l)L 传递给前一层(即计算损失对前一层参数的梯度)。
        • 损失对上一层输入 z z z 的梯度:
          ∂ L ∂ z j ( l ) = ∑ k = 1 n l + 1 ( ∂ L ∂ a k ( l + 1 ) ⋅ ∂ a k ( l + 1 ) ∂ z j ( l ) ) \frac{\partial L}{\partial z_j^{(l)}} = \sum_{k=1}^{n_{l+1}} \left( \frac{\partial L}{\partial a_k^{(l+1)}} \cdot \frac{\partial a_k^{(l+1)}}{\partial z_j^{(l)}} \right) zj(l)L=k=1nl+1(ak(l+1)Lzj(l)ak(l+1))
          其中 ∂ a k ( l + 1 ) ∂ z j ( l ) \frac{\partial a_k^{(l+1)}}{\partial z_j^{(l)}} zj(l)ak(l+1) 通常只有当 k = j k = j k=j 时才非零(即只考虑当前神经元对下一层的影响)。
        • 损失对权重 W W W 的梯度:
          ∂ L ∂ W i j ( l ) = ∂ L ∂ z j ( l + 1 ) ⋅ ∂ z j ( l + 1 ) ∂ W i j ( l ) \frac{\partial L}{\partial W_{ij}^{(l)}} = \frac{\partial L}{\partial z_j^{(l+1)}} \cdot \frac{\partial z_j^{(l+1)}}{\partial W_{ij}^{(l)}} Wij(l)L=zj(l+1)LWij(l)zj(l+1)
          ∂ z j ( l + 1 ) ∂ W i j ( l ) = x i ( l ) \frac{\partial z_j^{(l+1)}}{\partial W_{ij}^{(l)}} = x_i^{(l)} Wij(l)zj(l+1)=xi(l)
        • 损失对偏置 b b b 的梯度:
          ∂ L ∂ b j ( l ) = ∂ L ∂ z j ( l + 1 ) ⋅ ∂ z j ( l + 1 ) ∂ b j ( l ) = ∂ L ∂ z j ( l + 1 ) ⋅ 1 \frac{\partial L}{\partial b_j^{(l)}} = \frac{\partial L}{\partial z_j^{(l+1)}} \cdot \frac{\partial z_j^{(l+1)}}{\partial b_j^{(l)}} = \frac{\partial L}{\partial z_j^{(l+1)}} \cdot 1 bj(l)L=zj(l+1)Lbj(l)zj(l+1)=zj(l+1)L1
    • 重复: 这个过程(计算 ∂ L ∂ z \frac{\partial L}{\partial z} zL,然后计算 ∂ L ∂ W \frac{\partial L}{\partial W} WL ∂ L ∂ b \frac{\partial L}{\partial b} bL)会从输出层一直反向传递,计算损失 L L L 对于网络所有参数 Θ \Theta Θ 的梯度。

原理: 反向传播利用微积分中的链式法则,沿着计算图“反向追踪”,计算出损失函数对每个参数的敏感度,即梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL。这个梯度值告诉我们,如果稍微改变参数 θ \theta θ,损失 L L L 会如何变化。


3. 梯度下降:如何更新参数

目标: 利用计算出的梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL更新参数 θ \theta θ,使得损失 L L L 减小。

核心思想: 梯度是山坡最陡峭的方向。损失函数 L L L 可以想象成一个“山坡”,参数 θ \theta θ 是山坡上的一个点。我们希望找到损失 L L L 最小的点(“山脚”)。梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 指向损失增加最快的方向。因此,要减小损失,就需要沿着梯度的反方向更新参数。

过程:

  1. 选择学习率 α \alpha α 学习率 α \alpha α 控制着我们每次更新参数的步长。它是一个很小的正数。
  2. 参数更新: 对于网络中的每个参数 θ \theta θ(权重 W W W 或偏置 b b b),使用以下公式更新其值:
    θ : = θ − α ⋅ ∂ L ∂ θ \theta := \theta - \alpha \cdot \frac{\partial L}{\partial \theta} θ:=θαθL
    • θ \theta θ:是参数(例如某个 W W W b b b)。
    • ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL:是参数 θ \theta θ 对应的梯度。
    • α \alpha α:是学习率。
    • 符号 := 表示“被赋予”或“更新为”。

原理: 梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 告诉我们 θ \theta θ 变化对 L L L 的影响。如果 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是正数,说明 θ \theta θ 增大时 L L L 增大,因此我们需要减少 θ \theta θ;如果 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是负数,说明 θ \theta θ 增大时 L L L 减小,因此我们需要增加 θ \theta θ。在更新公式中,我们减去 α ⋅ ∂ L ∂ θ \alpha \cdot \frac{\partial L}{\partial \theta} αθL,就是朝着减小 L L L 的方向调整 θ \theta θ


总结:参数如何变得“更精确”?

  1. 正向传播: 使用已知的参数 Θ \Theta Θ 计算预测 Y \mathbf{Y} Y
  2. 计算损失: 比较预测 Y \mathbf{Y} Y 和真实标签 T \mathbf{T} T,得到误差(损失 L L L)。
  3. 反向传播: 利用链式法则,计算损失 L L L每个参数 θ \theta θ梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL。这个梯度表示参数 θ \theta θ 对损失 L L L影响程度
  4. 梯度下降: 根据计算出的梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL学习率 α \alpha α更新参数 θ \theta θ
    θ new = θ old − α ⋅ ∂ L ∂ θ \theta_{\text{new}} = \theta_{\text{old}} - \alpha \cdot \frac{\partial L}{\partial \theta} θnew=θoldαθL
    这个更新方向是沿着损失减小最快的方向。

整个过程就是: 神经网络通过正向传播预测,通过反向传播计算参数的梯度(了解参数的“影响度”),然后利用梯度下降算法更新参数,不断迭代,最终让预测越来越准确,参数 Θ \Theta Θ 也就变得“更精确”(更接近能够完美拟合训练数据或泛化好)。

这个过程是自动化的,通过数学公式和算法(如反向传播算法、梯度下降算法)实现,让神经网络能够从数据中“学会”模式。

我们来用更直观的方式解释这句话:“更新方向是沿着损失减小最快的方向”。

这句话的意思是:梯度下降算法每次调整参数(权重和偏置)时,都是朝着能让“错误”(损失)立刻变小的方向去动。

来拆解一下:

  1. 损失函数是什么? 损失函数衡量的是你的预测结果 Y \mathbf{Y} Y 与真实结果 T \mathbf{T} T 之间的差距有多大。差距越大,损失 L L L 越大;差距越小,损失 L L L 越小。我们的目标就是让 L L L 变得尽可能小。

  2. 梯度是什么? 梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是一个向量,它包含了损失 L L L 相对于每个参数 θ \theta θ 的变化率信息。

    • 如果某个参数 θ \theta θ 的梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL正数,意味着增加这个 θ \theta θ 会让 L L L 变得更大(或者说,保持其他参数不变,只增加 θ \theta θ,损失会增加)。
    • 如果某个参数 θ \theta θ 的梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL负数,意味着增加这个 θ \theta θ 会让 L L L 变得更小(或者说,保持其他参数不变,只增加 θ \theta θ,损失会减少)。
  3. “减小最快的方向”指的是什么?

    • 想象一下,损失函数 L L L 的值可以看作一个“山峰”或“山谷”。参数 θ \theta θ 就是山上的一个点。
    • 梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 指向的是损失 L L L 增加最快的方向,就像山的最陡峭的上坡方向。
    • 反方向,也就是 − ∂ L ∂ θ -\frac{\partial L}{\partial \theta} θL,就是损失 L L L 减小最快的方向,就像山最陡峭的下坡方向。
  4. 更新公式 θ := θ - α * (∂L/∂θ) 是怎么体现“减小最快”的?

    • ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是梯度,表示 θ \theta θ 变化对 L L L影响方向
    • α 是学习率,控制你每次下坡走多远。它是一个很小的正数。
    • α * (∂L/∂θ) 计算的是沿着梯度方向(上坡方向)走一小步的长度。
    • 关键操作 θ := θ - ...:这个减号 是核心!它表示你要往梯度的反方向走
      • 如果 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是正数(上坡方向),那么 −α * (∂L/∂θ) 就是负数,意味着你要减少 θ \theta θ,朝着损失减小的方向走。
      • 如果 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 是负数(下坡方向本身),那么 −α * (∂L/∂θ) 就是正数,意味着你要增加 θ \theta θ,朝着损失减小的方向走。
        因为如果比值为 0才是最好的结果,现在大于 0 就减,小于 0 就加。
    • 所以,无论梯度是正是负,这个公式 θ := θ - α * (∂L/∂θ) 总是让你朝着损失减小的方向调整 θ \theta θ

简单来说:

  • 梯度告诉你“往哪个方向调参数会让损失变大”。
  • 梯度下降就是“往反方向调一点”,让损失变小一点。
  • 梯度下降的目标就是不断往损失减小最快的方向调整参数,最终找到一个损失相对较小的“位置”(虽然不一定是全局最小,但通常是局部最小)。

比喻:

  • 调音量: 想把音量从 50 调到 30。梯度 ∂ L ∂ θ \frac{\partial L}{\partial \theta} θL 可能告诉你调 “降低旋钮” 会减少音量(梯度负)。梯度下降就是按 “降低旋钮” 调一点,朝着目标方向前进。
  • 下山: 想尽快下山。梯度告诉你最陡峭的上坡方向。梯度下降就是往最陡峭的下坡方向走一小步,每次都走最陡峭的下坡,效率最高。

希望这个解释能让你理解“更新方向是沿着损失减小最快的方向”这句话的含义。

你可能感兴趣的:(#,数据结构与算法,神经网络,人工智能,深度学习)