GradientChecking,我可以责怪浮点精度吗?

数据挖掘 机器学习 梯度下降 反向传播
2022-01-20 15:08:01

我正在尝试 GradientCheck 我的 c++ LSTM。结构如下:

输出向量(5D)

具有 softmax 的密集层(5 个神经元)

LSTM 层(5 个神经元)

输入向量(5D)

我的梯度检查使用这个公式

d=||(gn)||2||g||2+||n||2

密集层返回descrepancy = 2.843e-05,epsilon 为 5e-3

对于 5e-5 或更低,网络根本看不到成本的任何变化,任何大于 5e-2 的结果都会导致精度低。

这仅适用于顶层,我对所有内容都使用“浮点”32 位值


对于LSTM 层,我也使用 5e-3,但差异为 0.95


LSTM 似乎在任何任务上都收敛得相当快

0.95 困扰着我,所以我手动将 NumericalGradient 数组与 BackpropGradient 数组并排比较。所有的渐变都匹配符号,并且每个条目的大小不同。

例如:

numerical:    backpropped:

-0.015223     -0.000385
 0.000000      0.000000
-0.058794     -0.001509
-0.000381     -9.238e-06
 9.537e-05     2.473e-06
 0.000215      6.266e-0.6
-0.015223     -0.000385
 ...

如您所见,符号确实匹配,并且数值梯度始终大于后支撑梯度

你会说这是可以接受的,我可以责怪浮点精度吗?


编辑:

有点解决了, - 我只是忘记在我的 LSTM 的反向传播期间关闭“按时间步数平均初始梯度”。

这就是为什么我的梯度在“反向支撑”列中总是较小的原因。

我现在的 LSTM 的差异为 0.00025

编辑:将 epsilon 设置为 0.02 (lol) 似乎是一个最佳选择,因为它会导致 6.5e-05 的差异。任何更大或更小的东西都会使它偏离 6.5e-05,所以这似乎是一个数字问题......虽然只有 2 层深,奇怪的是

以前有人有这个精度吗?

1个回答

有一个甜蜜点的事实是数值微分中的一个常见问题。问题是使用高 epsilon 值会给你带来高误差,因为数值导数有误差O(ϵ)(或者O(ϵ2)如果您使用居中差异),并且使用非常低的 epsilon 将导致取消错误(请参阅灾难性取消问题),因为您要减去两个非常接近的数字。看起来ϵ=0.01在您的情况下,这是这两种极端情况之间的公平权衡。