使用 Adam Optimizer 解释训练损失与迭代中的峰值

机器算法验证 神经网络 深度学习 亚当
2022-02-14 07:09:08

我正在使用 i) SGD 和 ii) Adam Optimizer 训练神经网络。使用普通 SGD 时,我得到了平滑的训练损失与迭代曲线,如下所示(红色曲线)。然而,当我使用 Adam Optimizer 时,训练损失曲线有一些尖峰。这些尖峰的解释是什么?

型号详情:

14 个输入节点 -> 2 个隐藏层(100 -> 40 个单元) -> 4 个输出单元

我正在使用 Adam beta_1 = 0.9beta_2 = 0.999epsilon = 1e-8a 的默认参数batch_size = 32

i) 与新元 ii) 与亚当新元 与亚当

2个回答

尖峰是 Adam ( batch_size=32) 中 Mini-Batch Gradient Descent 不可避免的结果。一些小批量“偶然”有用于优化的不幸数据,导致您使用 Adam 在成本函数中看到的那些峰值。如果您尝试随机梯度下降(与使用 相同batch_size=1),您会发现成本函数中有更多的尖峰。在(完整)批量 GD 中不会发生同样的情况,因为它在每个优化时期都使用所有训练数据(即批量大小等于训练集的基数)。正如在您的第一张图中,成本是单调平稳下降的,似乎标题 ( i) With SGD是错误的,并且您使用的是 (Full) Batch Gradient Descent 而不是 SGD。

Coursera 的深度学习课程中,Andrew Ng 使用下图详细解释了这一点:

成本函数

我花了很多时间调试爆炸梯度和类似的行为。您的答案将取决于损失函数、数据、架构等。有数百个原因。我会举几个。

  • 损失相关。对数似然损失需要被裁剪,如果没有,它可能会评估log(0)数据集中的不良预测/异常值,从而导致梯度爆炸。大多数包(torch、tensorflow 等)默认实现了对它们的损失的裁剪。
  • 数据集中的异常值。
  • 具有小批量和大 epsilon 的 BatchNormϵ(超参数)。使用批处理规范作为y=(xu)/(s+ϵ),然后用小sϵ你可以得到高幅度的y
  • 如果数据集不能被批次大小整除,则一个时期中的最终批次可能很小。在 torch dataloader 中有一个 flag drop_last小批量=高方差

现在,为什么您会看到 Adam 而不是 SGD?显然,您与 Adam 达成了较低的损失。如前所述,如果 99.9% 的数据集在某个点上存在最优值,除了一些观察值,这可能是当随机选择一个批次时,观察值尖叫“不”并从局部最小值跳出。如果您在每dataset_size//batch_size+1一步都看到它,那可能是由于最终的批量较小。我敢打赌,如果你让它达到更低的损失,你也会看到 SGD 飙升。

奖励:动量优化器(Adam)的真正快速下降可能意味着某些层(输入层?输出层?)被初始化为超出规模(到大/小权重)。