神经网络权重更新实战:从损失计算到反向传播的完整过程解析

1次阅读
没有评论

共计 2205 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

核心概念

在开始具体的计算之前,我们先简单回顾几个关键概念:

神经网络权重更新实战:从损失计算到反向传播的完整过程解析

  1. 神经网络:由输入层、隐藏层和输出层组成的网络结构,通过权重连接各层神经元
  2. 损失函数 :衡量网络预测值与真实值差异的函数,常见的有均方误差(MSE) 和交叉熵损失
  3. 反向传播:通过链式法则从输出层向输入层逐层计算梯度,用于更新权重

问题描述

假设我们有一个简单的 2 层神经网络:

  • 输入层:2 个节点,值分别为 x1=0.5,x2=0.3
  • 隐藏层:2 个节点
  • 输出层:1 个节点
  • 真实输出:y=0.7
  • 当前权重:
  • w1=0.1, w2=0.2 (输入到隐藏层 1)
  • w3=0.3, w4=0.4 (输入到隐藏层 2)
  • w5=0.5, w6=0.6 (隐藏层到输出)
  • 激活函数:Sigmoid
  • 损失函数:均方误差(MSE)

技术实现

1. 前向传播与损失计算

首先计算隐藏层和输出层的值:

  1. 隐藏层 1 的输入:
    $$ h1_{in} = w1x1 + w2x2 = 0.10.5 + 0.20.3 = 0.11 $$
    $$ h1_{out} = \sigma(0.11) = \frac{1}{1+e^{-0.11}} \approx 0.5275 $$

  2. 隐藏层 2 的输入:
    $$ h2_{in} = w3x1 + w4x2 = 0.30.5 + 0.40.3 = 0.27 $$
    $$ h2_{out} = \sigma(0.27) \approx 0.5671 $$

  3. 输出层的计算:
    $$ o_{in} = w5h1_{out} + w6h2_{out} = 0.50.5275 + 0.60.5671 \approx 0.6135 $$
    $$ o_{out} = \sigma(0.6135) \approx 0.6488 $$

  4. 计算损失(MSE):
    $$ L = \frac{1}{2}(o_{out} – y)^2 = \frac{1}{2}(0.6488 – 0.7)^2 \approx 0.001312 $$

2. 反向传播梯度计算

我们需要计算损失对各权重的偏导数。以 w5 为例:

  1. $$ \frac{\partial L}{\partial w5} = \frac{\partial L}{\partial o_{out}} * \frac{\partial o_{out}}{\partial o_{in}} * \frac{\partial o_{in}}{\partial w5} $$

  2. 计算各部分:

  3. $$ \frac{\partial L}{\partial o_{out}} = o_{out} – y = 0.6488 – 0.7 = -0.0512 $$
  4. $$ \frac{\partial o_{out}}{\partial o_{in}} = o_{out}(1-o_{out}) = 0.6488(1-0.6488) \approx 0.2278 $$
  5. $$ \frac{\partial o_{in}}{\partial w5} = h1_{out} = 0.5275 $$

  6. 组合起来:
    $$ \frac{\partial L}{\partial w5} = -0.0512 * 0.2278 * 0.5275 \approx -0.00615 $$

类似地可以计算其他权重的梯度。

3. 权重更新

假设学习率 η =0.1,更新 w5:

$$ w5_{new} = w5 – η * \frac{\partial L}{\partial w5} = 0.5 – 0.1*(-0.00615) \approx 0.500615 $$

其他权重的更新方式相同。

代码示例

import numpy as np

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# 输入和参数
x1, x2 = 0.5, 0.3
y_true = 0.7
w1, w2, w3, w4, w5, w6 = 0.1, 0.2, 0.3, 0.4, 0.5, 0.6
lr = 0.1

# 前向传播
h1_in = w1*x1 + w2*x2
h1_out = sigmoid(h1_in)

h2_in = w3*x1 + w4*x2
h2_out = sigmoid(h2_in)

o_in = w5*h1_out + w6*h2_out
o_out = sigmoid(o_in)

# 计算损失
loss = 0.5 * (o_out - y_true)**2
print(f"Current loss: {loss:.6f}")

# 反向传播
dL_do_out = o_out - y_true
do_out_do_in = o_out * (1 - o_out)

dL_do_in = dL_do_out * do_out_do_in

dL_dw5 = dL_do_in * h1_out
dL_dw6 = dL_do_in * h2_out

# 更新权重
w5 -= lr * dL_dw5
w6 -= lr * dL_dw6

print(f"Updated w5: {w5:.6f}, w6: {w6:.6f}")

注意事项

  1. 学习率选择
  2. 太大可能导致震荡甚至发散
  3. 太小会导致收敛速度过慢
  4. 建议从 0.01 或 0.001 开始尝试

  5. 常见错误

  6. 忘记对中间结果进行缓存,导致重复计算
  7. 梯度计算时链式法则应用错误
  8. 权重更新方向错误(应该是减而不是加)

  9. 调试技巧

  10. 打印中间变量的值和形状
  11. 使用小规模数据验证
  12. 对比数值梯度和解析梯度

总结与延伸

通过这个简单的例子,我们完整走了一遍神经网络权重更新的流程。关键步骤包括:

  1. 前向传播计算预测值和损失
  2. 反向传播计算各权重的梯度
  3. 根据梯度更新权重

为了加深理解,可以尝试:

  1. 手动计算其他权重的更新值
  2. 修改网络结构(如增加隐藏层)
  3. 尝试不同的激活函数和损失函数
  4. 实现完整的训练循环,观察损失下降曲线

这个过程虽然看起来复杂,但只要掌握了链式法则的基本原理,就能逐步推导出所有需要的梯度。在实践中,深度学习框架会自动帮我们完成这些计算,但理解背后的原理对于调试和改进模型至关重要。

正文完
 0
评论(没有评论)