gpt4 book ai didi

python - 如何避免 Theano 计算梯度趋向于 NaN

转载 作者:太空宇宙 更新时间:2023-11-03 11:22:21 25 4
gpt4 key购买 nike

我正在尝试使用 5 个卷积层的 CNN - 2 个隐藏层 - 1 个 Softmax。

架构是:

cv0->relu->cv1->relu-cv2->relu->cv3->relu->cv4->relu->cv5->hid1->relu->hid2->relu->logistic softmax

通过对图像中的 66 个补丁标记应用随机梯度。出于测试目的,训练仅应用于具有 20 个 epoch 的单张图像。

从网络中识别出错误在每次迭代中爆炸,因此梯度在第 4 轮的第 3 轮之后计算 nan。

  • epoch 1 学习成本:4.702012
  • epoch 2 学习成本:45338036.000000
  • epoch 3 学习成本:74726722389225987403008805175296.000000
  • epoch 4 学习成本:nan

正如您所见,在误差爆炸到非常高的值之后,梯度产生了 nan 并传播到所有网络中。

查看来自不同层权重值的单个节点以查看发生了什么:

第 8 层(softmax):

  • 初始值 [ 0.05436778 0.02379715]
  • 纪元 1 [ 0.28402206 -0.20585714]
  • 纪元 2 [ -5.27361184e-02 9.5203​​8541e-02]
  • 纪元 3 [-7330.04199219 7330.12011719]
  • 纪元 4 [nan nan]

layer6 (hid1):

  • 初始值 [-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309]
  • 纪元 1 [-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309]
  • 纪元 2 [-0.0254469 0.00760095 ..., -0.00587915 0.02619855 0.03809309
  • 纪元 3 [ -2.54468974e-02 1.79247314e+16 ..., -5.87915350e-03 2.61985492e-02 -2.06307964e+19]
  • 纪元 4 [nan nan ..., nan nan nan]

layer0 (cv0):

初始化是

[[-0.01704694 -0.01683052 -0.0894756 ]
[ 0.12275343 -0.05518051 -0.09202443]
[-0.11599202 -0.04718829 -0.04359322]]

而第 3 个纪元是

[[-24165.15234375 -26490.89257812 -24820.1484375 ]
[-27381.8203125 -26653.3359375 -24762.28710938]
[-23120.56835938 -21189.44921875 -24513.65039062]]

很明显,权重值正在爆炸式增长。

学习率为 0.01 所以为了解决这个问题,我将学习率改为 0.001,Nan 有时消失,网络收敛,有时不收敛,网络充满 NaN。再次尝试使用 0.0001 的较小学习率,但我还没有看到 NaN。从我每次重新运行代码时得到的结果来看,结果确实不同,我认为这首先与权重初始化有关。

所以我尝试了不同的权重初始化:

对于带有relu的Conv层

W_bound_6 = numpy.sqrt(6. / (fan_in + fan_out))
W_bound_2 = numpy.sqrt(2. / (fan_in + fan_out))
W_values = numpy.asarray(
numpy.random.randn(filter_shape[0], filter_shape[1], filter_shape[2], filter_shape[3]) * W_bound_2,
dtype=theano.config.floatX)

以及隐藏层和softamx层

W_bound_2 = numpy.sqrt(2. / (filter_shape[0] + filter_shape[1]))
W_values = numpy.asarray(
numpy.random.randn(filter_shape[0], filter_shape[1]) * W_bound_2,
dtype=theano.config.floatX
)

并将 b 全部归零。

差别不大,我仍然看不出结果有什么不同。

我在这里发布我的问题:

  • 讨论我在权重初始化方面所做的是否是正确编码
  • 为了看看我们是否可以避免使学习率变得非常小并至少在前几次迭代中将其保持在较高水平,因为在我的例子中它是在第 4 次迭代中传播 Nan。
  • 我想知道的是 L1、L2 正则化,因为我正在使用 Theano,我应该在哪里实现成本函数中的代码,或者我应该更改更新函数。

代价函数

-T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y])

更新函数

updates = [
(param_i, param_i - learning_rate * grad_i)
for param_i, grad_i in zip(classifier.params, grads)
]
  • 在我的结构中每一层之后而不是 softmax 中的 relu 实现是否正确?

最佳答案

我正在寻找不同的方法来避免这个问题,但正在寻找其他人提出的正式解决方案并阅读一些理论解决方案我会在这里写下我的答案,以帮助其他人遇到同样的问题。

这个问题背后的原因是使用了 softmax 和交叉熵。因此,当您计算梯度并跳入零或 inf 时,您会得到 nan,它正在传播反向词并抛出所有网络参数。

很少有人建议避免这个问题

  • 如果错误开始增加然后 NaN 出现:由于发散学习率过高
  • 如果 NaN 突然出现:饱和单元产生不可微分由于 log(0) 导致的梯度 NaN 计算
  • NaN 由于浮点问题(高权重)或激活输出 0/0, inf/inf, inf*weight...

解决方案:

  1. 降低学习率
  2. 更改权重初始化
  3. 使用 L2 范数
  4. Safe softmax(小值添加到 log(x))
  5. 渐变剪裁

在我的案例中,学习率解决了这个问题,但我仍在努力进一步优化它

关于python - 如何避免 Theano 计算梯度趋向于 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40405334/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com