我花了很多时间调试爆炸的渐变和类似的行为。您的答案将取决于损失函数,数据,体系结构等。有数百种原因。我列举几个。
- 取决于损耗。对数似然损失需要进行裁剪,如果不是,则可能会评估
log(0)
数据集中的不良预测/离群值,从而导致爆炸梯度。大多数程序包(torch,tensorflow等)默认会对其损失进行裁剪。
- 数据集中的异常值。
- 具有小批处理大小和大epsilon(超参数)的BatchNorm 。使用batchnorm为,然后使用较小的和可以得到高幅值ϵy=(x−u)/(s+ϵ)sϵy
- 如果数据集不能被batchsize整除,则时代中的最终批次可能很小。火炬数据加载器中有一个标志
drop_last
。小批量=高差异
现在,为什么您在Adam而不是SGD上看到它?显然,您与亚当的损失降低了。如前所述,如果99.9%的数据集在某一点除某个观察点之外具有最佳状态,则可能是观察点在随机选择一批时尖叫“ NO”并从局部最小值跳出。如果您在每个dataset_size//batch_size+1
步骤中都看到它,则可能是由于最终批处理量较小。我敢打赌,如果让它达到更低的损失,您也会看到SGD峰值。
奖励:动量优化器(Adam)的真正快速降低可能意味着某些层(输入层还是输出层?)的初始化超出了比例(以大/小权重)。