相关技巧 ¶
约 1710 个字 预计阅读时间 7 分钟
参数更新方法 ¶
1. SGD(随机梯度下降)¶
核心思想:
每次从一个 mini-batch 计算梯度,然后沿着梯度的反方向更新参数。
优点 ¶
- 实现最简单,代码量少,容易理解。
- 每次更新开销小,占用内存少。
- 是很多优化方法的基础。
- 在一些任务中,最终泛化能力可能不错。
缺点 ¶
- 容易在不同方向尺度差异很大的地形中走“之”字形,收敛慢。
- 对学习率比较敏感,学习率过大容易震荡,过小又收敛很慢。
- 容易在鞍点、狭长谷底附近反复摆动。
- 不会根据参数历史自动调整更新策略。
适合场景 ¶
- 作为最基础的 baseline。
- 模型较简单、对速度要求不高时。
- 想先验证训练流程是否正确时。
2. Momentum(动量法)¶
核心思想:
在 SGD 的基础上引入“速度”变量,让参数更新保留一部分过去的方向信息。
可以理解为小球沿坡面滚动,既看当前梯度,也保留之前的惯性。
优点 ¶
- 能减小 SGD 的“之”字形震荡。
- 在方向一致的维度上会不断加速,收敛通常比 SGD 更快。
- 在狭长谷底中表现通常比 SGD 更好。
- 实现也不复杂,只比 SGD 多维护一个速度变量。
缺点 ¶
- 仍然依赖全局学习率,不能像自适应方法那样自动为不同参数调节步长。
- 需要额外保存一份速度参数,内存开销比 SGD 略大。
- 若学习率或动量系数设置不当,可能会冲过最优点,来回震荡。
- 对稀疏梯度问题不如 AdaGrad/Adam 灵活。
适合场景 ¶
- 想在 SGD 基础上提升收敛速度时。
- 损失曲面存在明显狭长区域、震荡较强时。
- 工程上常和 SGD 组合使用。
3. AdaGrad¶
核心思想:
为每个参数分别调整学习率。
历史梯度平方和越大,该参数后续的学习率就越小。
优点 ¶
- 能自动调整不同参数的学习率,不需要所有参数共用同一个更新幅度。
- 对稀疏特征特别友好,出现频率低的参数也能得到较大更新。
- 前期下降通常比较快。
- 在梯度尺度差异较大的问题上,通常比 SGD 更稳定。
缺点 ¶
- 会不断累积历史梯度平方和,导致学习率越来越小。
- 训练后期可能几乎不再更新,容易“学不动”。
- 对长期训练不太友好。
- 有时前期快,但后期难以继续逼近更优解。
适合场景 ¶
- 稀疏特征问题。
- 希望自动调节参数学习率时。
- 更适合作为理解“自适应学习率”思想的入门方法。
4. Adam¶
核心思想:
把 Momentum 的一阶动量思想和 AdaGrad 的自适应学习率思想结合起来。
既利用梯度方向的历史信息,又根据梯度大小动态调节步长。
优点 ¶
- 一般收敛速度快,训练初期效果通常很好。
- 既能减小震荡,又能自适应调节学习率。
- 对大多数问题比较“省心”,默认超参数往往就能跑起来。
- 对稀疏梯度和非平稳目标通常表现较好。
- 是深度学习中非常常用的默认优化器之一。
缺点 ¶
- 实现和原理比前几种更复杂。
- 需要维护更多状态量,内存开销更大。
- 超参数更多(如
beta1、 beta2) 。 - 在某些任务上,最终泛化能力不一定比 SGD/Momentum 更好。
- 有时收敛虽然快,但最后得到的解未必最优。
适合场景 ¶
- 作为深度学习训练的默认首选。
- 希望先快速得到一个能工作的结果时。
- 模型较深、参数较多、训练不稳定时。
总体对比 ¶
| 方法 | 主要特点 | 优点 | 缺点 |
|---|---|---|---|
| SGD | 最基础的梯度下降 | 简单、省内存、易实现 | 收敛慢、震荡明显、对学习率敏感 |
| Momentum | SGD + 惯性 | 更快、更平滑、减少摆动 | 仍依赖全局学习率,可能冲过头 |
| AdaGrad | 按参数自适应学习率 | 前期收敛快,适合稀疏特征 | 学习率会越来越小,后期容易停滞 |
| Adam | Momentum + 自适应学习率 | 通常收敛最快,鲁棒性强,默认好用 | 内存更大,超参数更多,泛化未必最好 |
一句话总结 ¶
- SGD:最朴素,简单但慢。
- Momentum:给 SGD 加上“惯性”,走得更稳更快。
- AdaGrad:会自动给不同参数分配不同学习率,但后期容易学不动。
- Adam:综合了动量和自适应学习率,通常最好用,也是最常见的默认选择。
实战建议 ¶
- 想要最简单、最基础:用 SGD
- 想要比 SGD 更快更稳:用 Momentum
- 遇到稀疏特征:可以考虑 AdaGrad
- 想要开箱即用、通常效果不错:优先试 Adam
一般来说,Adam 训练更快,但在某些任务上,SGD / Momentum 的最终泛化效果可能更好。
权重设置 ¶
sigmod 激活函数 ¶
与前一层有 n 个节点连接时,初始值使用标准差为 \(\frac{1}{\sqrt{n}}\) 的分布
w = np.random.randn(node_num, node_num)/np.sqrt(node_num)
ReLU 激活函数 ¶
与前一层有 n 个节点连接时,初始值使用标准差为 \(\sqrt{\frac{2}{n}}\) 的分布。2 倍是为了让其更有广度,ReLU 的负值区域的值为 0。
w = np.random.randn(node_num, node_num)*np.sqrt(2/node_num)
Batch Normal¶
Batch Norm 有以下优点 • 可以使学习快速进行(可以增大学习率)。 • 不那么依赖初始值(对于初始值不用那么神经质)。 • 抑制过拟合(降低Dropout等的必要性)。
为了使各层拥有适当的广度
, “强制性”地调整激活值的分布 , 要向神经网络中插入对数据分布进行正规化的层,即 Batch Normalization 层

定义: 以进行学习时的 mini-batch 为单位,按 mini batch 进行正规化。具体而言,就是进行使数据分布的均值为 0、方差为 1 的正规化。
其实就是求出均数,然后标准差,然后让所有值减去均数,然后除以标准差,为了防止标准差为 0 的情况,所以加上了一个 \(\varepsilon\) 微小值放置除 0。这样可以减小数据的偏向。
接着 Batch Norm 层还会对正规化后的数据进行缩放和平移变换。
这个 \(\gamma\) 和 \(\beta\) 一开始是 1 和 0,然后也会通过学习进行调整到合适的值。