单神经元梯度下降实验
背景
最近在着手学习深度学习相关的知识。准备用C语言实现一个 MLP 网络实现手写数字的识别。在学习梯度下降的过程中,遇到了梯度爆炸的问题。于是写篇博客记录一下。
模型与推导
考虑如下这样一个十分简单的函数:
我们假设训练集只有这样的一个样本:
损失用均方误差(MSE):
用链式法则求梯度(中间变量为误差
更新规则(学习率
实验
我们考虑一下三组实验:
、学习率 ,迭代 10 次:
| 0 | 2.400000 | 36.000000 |
| 1 | 2.880000 | 1.440000 |
| 2 | 2.976000 | 0.057600 |
| 3 | 2.995200 | 0.002304 |
| 4 | 2.999040 | 0.000092 |
| 5 | 2.999808 | 0.000004 |
| 6 | 2.999962 | 0.000000 |
| 7 | 2.999992 | 0.000000 |
| 8 | 2.999999 | 0.000000 |
| 9 | 3.000000 | 0.000000 |
损失函数值顺利地从 36 一路降到 0,
2.把数据改成
| 0 | 24000.000000 | 360000.000000 |
| 1 | -191952000.000000 | 23034240958464.000000 |
| 2 | 1535424069632.000000 | 1473822681305364561920.000000 |
| 3 | -12281858414870528.000000 | 94301087412151397100942262272.000000 |
| 4 | 98242586598715686912.000000 | 6033761425490425962899905671893876736.000000 |
| 5 | -785842538524696815599616.000000 | inf |
| 6 | 6285955011855612635475083264.000000 | inf |
| 7 | -50281352547214949123377342709760.000000 | inf |
| 8 | 402200578581225195828561960721448960.000000 | inf |
| 9 | -inf | inf |
不难发现,inf。这就是典型的发散震荡:步长超过谷底宽度,第一步就冲过最低点,之后每次矫枉过正、越震越大。
不难发现,在梯度公式中:
3.保持
再把
| iter | w | L |
|---|---|---|
| 0 | 2.400000 | 360000.000000 |
| 1 | 2.880000 | 14400.007812 |
| 2 | 2.976000 | 576.000000 |
| 3 | 2.995200 | 23.040468 |
| 4 | 2.999040 | 0.921642 |
| 5 | 2.999808 | 0.036870 |
| 6 | 2.999962 | 0.001474 |
| 7 | 2.999992 | 0.000059 |
| 8 | 2.999999 | 0.000002 |
| 9 | 3.000000 | 0.000000 |
总结
收敛速度由
记当前权重为
更新后误差也随之变化:
、 : 、 :
两个实验的收敛因子相同,所以
这次实验也说明了为什么训练前数据要归一化。MNIST手写数字识别的 MLP 有 784 个像素输入,每个像素的量级各不相同,不可能为每个输入单独配学习率。归一化把输入统一缩到 0~1,让所有输入的梯度量级一致,一个 η 即可稳定训练。
实验代码(C)
1 | int main(void) |
- 标题: 单神经元梯度下降实验
- 作者: Guo Xiaosheng
- 创建于 : 2026-08-06 10:00:00
- 更新于 : 2026-08-06 17:14:34
- 链接: https://serendipityb612.com/2026/08/06/2026-08-06-gradient-descent-experiment/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。