上一篇:[[Train]] 下一篇:[[Least Squares Method]]
我们先通过一个详细数值例子来演示一个简单神经网络如何被训练,使用梯度下降法(Gradient Descent)。然后详细讲解 SGD 和 Adam 的区别与工作原理,并附上具体数值例子。
🧠 一、简单神经网络训练全过程(含数值与公式)
我们定义一个最简单的网络:
- 输入层:1 个神经元(输入特征 $x$)
- 输出层:1 个神经元(输出 $\hat{y}$)
- 无隐藏层
- 激活函数:恒等函数 $f(z) = z$
- 损失函数:MSE 均方误差 $L = \frac{1}{2}(\hat{y} - y)^2$
模型公式: $$ \hat{y} = w \cdot x + b $$
🌟 数据点:
假设我们只有一个训练样本:
- 输入 $x = 2$
- 标签 $y = 4$
初始参数:
- 权重 $w = 1.0$
- 偏置 $b = 0.0$
- 学习率 $\eta = 0.1$
第一步:正向传播(Forward Pass)
$$ z = w \cdot x + b = 1.0 \cdot 2 + 0 = 2 $$ $$ \hat{y} = z = 2 $$ $$ L = \frac{1}{2}(\hat{y} - y)^2 = \frac{1}{2}(2 - 4)^2 = \frac{1}{2} \cdot 4 = 2.0 $$
第二步:反向传播(计算梯度)
损失对输出的导数: $$ \frac{\partial L}{\partial \hat{y}} = \hat{y} - y = 2 - 4 = -2 $$
链式法则:
对权重 $w$ 的梯度: $$ \frac{\partial L}{\partial w} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial w} = -2 \cdot x = -2 \cdot 2 = -4 $$
对偏置 $b$ 的梯度: $$ \frac{\partial L}{\partial b} = \frac{\partial L}{\partial \hat{y}} \cdot \frac{\partial \hat{y}}{\partial b} = -2 \cdot 1 = -2 $$
第三步:参数更新(梯度下降)
$$ w := w - \eta \cdot \frac{\partial L}{\partial w} = 1.0 - 0.1 \cdot (-4) = 1.0 + 0.4 = 1.4 $$ $$ b := b - \eta \cdot \frac{\partial L}{\partial b} = 0.0 - 0.1 \cdot (-2) = 0.0 + 0.2 = 0.2 $$
✅ 完成一次迭代后的参数更新:
- $w = 1.4$,$b = 0.2$
- 新预测: $$ \hat{y} = 1.4 \cdot 2 + 0.2 = 2.8 + 0.2 = 3.0 $$
- 新损失: $$ L = \frac{1}{2}(3.0 - 4)^2 = \frac{1}{2} \cdot 1 = 0.5 $$
⚙️ 二、SGD 和 Adam 的详细机制 + 数值例子
✳️ SGD(随机梯度下降)
SGD 只是将梯度下降用于单一样本: $$ \theta := \theta - \eta \cdot \nabla_\theta L(\theta) $$ 例子同上,就是每次都基于一个样本更新,不保留历史信息。
✳️ Adam 优化器(Adaptive Moment Estimation)
Adam 同时使用了:
- 一阶矩估计(梯度的指数滑动平均): $$ m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_t $$
- 二阶矩估计(平方梯度的指数滑动平均): $$ v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2 $$
再进行偏差修正: $$ \hat{m}_t = \frac{m_t}{1 - \beta_1^t}, \quad \hat{v}_t = \frac{v_t}{1 - \beta_2^t} $$
更新参数: $$ \theta := \theta - \eta \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} $$
🧮 数值例子(基于刚才梯度 $g = -4$,Adam参数设为常用值)
- $\beta_1 = 0.9$, $\beta_2 = 0.999$, $\epsilon = 10^{-8}$
- 初始:$m_0 = 0, v_0 = 0$
- 第一步: $$ m_1 = 0.9 \cdot 0 + 0.1 \cdot (-4) = -0.4 $$ $$ v_1 = 0.999 \cdot 0 + 0.001 \cdot (-4)^2 = 0.016 $$ $$ \hat{m}_1 = \frac{-0.4}{1 - 0.9} = -4.0, \quad \hat{v}_1 = \frac{0.016}{1 - 0.999} = 16.0 $$ $$ \Delta w = 0.1 \cdot \frac{-4.0}{\sqrt{16.0} + 10^{-8}} \approx 0.1 \cdot \frac{-4.0}{4} = -0.1 $$ $$ w = 1.0 - (-0.1) = 1.1 $$
Adam 更新步长更平滑,适应性调整每个参数的学习率。
📊 对比总结
| 方法 | 记忆历史梯度 | 每步学习率 | 收敛速度 | 稳定性 |
|---|---|---|---|---|
| SGD | 否 | 固定 | 较慢 | 震荡 |
| Adam | 是(均值+方差) | 自适应 | 快 | 稳定 |
我们通过一个具体的例子,从损失函数的梯度计算开始,到Adam优化器的参数更新,详细说明其每一步计算过程。我们选用的例子是:最后一层是Softmax,损失函数是交叉熵(cross-entropy),优化器为Adam。
一、前提设定
模型输出层是 softmax:
假设输出层有 3 个类别,神经网络最后一层的输出(logits)为:
$$ z = [2.0, 1.0, 0.1] $$真实标签(one-hot 编码)为: $$ y = [1, 0, 0] $$
损失函数为交叉熵(Cross-Entropy): $$ L = -\sum_{i=1}^{3} y_i \log(\hat{y}_i) $$
二、计算 Softmax 输出
先计算 softmax 概率:
$$ \hat{y}i = \frac{e^{z_i}}{\sum{j} e^{z_j}} $$
计算:
$e^{2.0} \approx 7.389$ $e^{1.0} \approx 2.718$ $e^{0.1} \approx 1.105$
归一化:
$$ \hat{y} = \left[ \frac{7.389}{11.212}, \frac{2.718}{11.212}, \frac{1.105}{11.212} \right] \approx [0.659, 0.242, 0.099] $$
三、计算交叉熵损失
$$ L = -\log(0.659) \approx 0.417 $$
四、计算梯度
交叉熵 + softmax 的梯度(对 logits $z$)是: $$ \frac{\partial L}{\partial z_i} = \hat{y}_i - y_i $$
所以:
$$ \frac{\partial L}{\partial z} = [0.659 - 1, 0.242 - 0, 0.099 - 0] = [-0.341, 0.242, 0.099] $$
假设这些梯度是我们要求的参数梯度(例如 softmax 层前的权重某一行的梯度)。
五、Adam 优化器更新过程
Adam 是基于动量法 + RMSProp,它维护两个变量:
- 一阶矩估计(动量) $m_t$
- 二阶矩估计(梯度平方的指数滑动平均) $v_t$
超参数设定
- 学习率:$\alpha = 0.01$
- $\beta_1 = 0.9$
- $\beta_2 = 0.999$
- $\epsilon = 10^{-8}$
- 初始化:$m_0 = 0, v_0 = 0$
我们只看第一个时间步(t = 1):
当前梯度:
$$ g = [-0.341, 0.242, 0.099] $$
Step 1: 一阶矩估计(m_t)
$$ m_t = \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g $$ $$ m_1 = 0.9 \cdot 0 + 0.1 \cdot g = 0.1 \cdot g = [-0.0341, 0.0242, 0.0099] $$
Step 2: 二阶矩估计(v_t)
$$ v_t = \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g^2 $$
计算 $g^2 = [0.116, 0.0586, 0.0098]$(平方逐元素)
$$ v_1 = 0 + 0.001 \cdot g^2 = [0.000116, 0.0000586, 0.0000098] $$
Step 3: 偏差校正
$$ \hat{m}_1 = \frac{m_1}{1 - \beta_1} = \frac{m_1}{0.1} = [-0.341, 0.242, 0.099] $$
$$ \hat{v}_1 = \frac{v_1}{1 - \beta_2} = \frac{v_1}{0.001} = [0.116, 0.0586, 0.0098] $$
Step 4: 参数更新
参数更新公式: $$ \theta_{t+1} = \theta_t - \alpha \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon} $$
计算分母的平方根:
- $\sqrt{0.116} \approx 0.34$
- $\sqrt{0.0586} \approx 0.242$
- $\sqrt{0.0098} \approx 0.099$
注意这些恰好和 $\hat{m}_1$ 的值相等,因此:
$$ \frac{\hat{m}_1}{\sqrt{\hat{v}_1} + \epsilon} \approx [1.0029, 1.0004, 1.0000] $$
那么:
$$ \Delta \theta = -0.01 \cdot [1.0029, 1.0004, 1.0000] \approx [-0.01003, -0.01000, -0.01000] $$
六、Adam中各个参数的作用总结
| 参数 | 含义 | 作用 |
|---|---|---|
| $\alpha$ | 学习率 | 控制更新步长 |
| $\beta_1$ | 一阶动量衰减 | 控制历史梯度的“记忆”程度 |
| $\beta_2$ | 二阶动量衰减 | 控制平方梯度的平滑程度 |
| $\epsilon$ | 防止除零 | 确保数值稳定性 |
| $m_t$ | 梯度的一阶滑动平均 | 方向感(惯性) |
| $v_t$ | 梯度平方的滑动平均 | 缩放因子,防止剧烈振荡 |
| 偏差校正 | 修正初始化为0带来的偏差 | 提升早期更新精度 |
上一篇:[[Train]] 下一篇:[[Least Squares Method]]