gpt4 book ai didi

tensorflow - LSTM 'recurrent_dropout' 和 'relu' 产生 NaN

转载 作者:行者123 更新时间:2023-12-04 01:40:47 28 4
gpt4 key购买 nike

任何非零 recurrent_dropout产生 NaN 损失和权重;后者是 0 或 NaN。发生堆叠,浅,stateful , return_sequences = 任何,不包含 Bidirectional() , activation='relu' , loss='binary_crossentropy' . NaN 出现在几个批处理中。

任何修复?感谢帮助。


已尝试排除故障:

  • recurrent_dropout=0.2,0.1,0.01,1e-6
  • kernel_constraint=maxnorm(0.5,axis=0)
  • recurrent_constraint=maxnorm(0.5,axis=0)
  • clipnorm=50 (凭经验确定),那达慕优化器
  • activation='tanh' - 无 NaN,权重稳定,测试多达 10 批处理
  • lr=2e-6,2e-5 - 无 NaN,权重稳定,测试多达 10 批处理
  • lr=5e-5 - 没有 NaN,权重稳定,对于 3 个批处理 - 第 4 批处理为 NaN
  • batch_shape=(32,48,16) - 2 批损失较大,第 3 批为 NaN

注意:batch_shape=(32,672,16) , 17 次调用 train_on_batch每批处理


环境:

  • Keras 2.2.4(TensorFlow 后端)、Python 3.7、Spyder 3.3.7(通过 Anaconda)
  • GTX 1070 6GB,i7-7700HQ,12GB 内存,Win-10.0.17134 x64
  • CuDNN 10+,最新的 Nvidia 驱动器

附加信息:

模型分歧是自发的,在不同的训练更新时发生,即使使用固定种子 - Numpy、Random 和 TensorFlow 随机种子。此外,当第一次发散时,LSTM 层权重都是正常的 - 稍后才变为 NaN。

以下按顺序排列:(1) 输入 LSTM ; (2) LSTM产出; (3) Dense(1,'sigmoid')输出——这三个是连续的,有Dropout(0.5)每个之间。前面的 (1) 是 Conv1D层。右:LSTM 权重。 "BEFORE"= 之前有 1 次列车更新; "AFTER = 1 次列车更新之后

分歧之前: image

AT 分歧: image

## LSTM outputs, flattened, stats
(mean,std) = (inf,nan)
(min,max) = (0.00e+00,inf)
(abs_min,abs_max) = (0.00e+00,inf)

分歧之后: image

## Recurrent Gates Weights:
array([[nan, nan, nan, ..., nan, nan, nan],
[ 0., 0., -0., ..., -0., 0., 0.],
[ 0., -0., -0., ..., -0., 0., 0.],
...,
[nan, nan, nan, ..., nan, nan, nan],
[ 0., 0., -0., ..., -0., 0., -0.],
[ 0., 0., -0., ..., -0., 0., 0.]], dtype=float32)
## Dense Sigmoid Outputs:
array([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,
1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)


最小可重现示例:

from keras.layers import Input,Dense,LSTM,Dropout
from keras.models import Model
from keras.optimizers import Nadam
from keras.constraints import MaxNorm as maxnorm
import numpy as np
ipt = Input(batch_shape=(32,672,16))
x = LSTM(512, activation='relu', return_sequences=False,
recurrent_dropout=0.3,
kernel_constraint =maxnorm(0.5, axis=0),
recurrent_constraint=maxnorm(0.5, axis=0))(ipt)
out = Dense(1, activation='sigmoid')(x)

model = Model(ipt,out)
optimizer = Nadam(lr=4e-4, clipnorm=1)
model.compile(optimizer=optimizer,loss='binary_crossentropy')
for train_update,_ in enumerate(range(100)):
x = np.random.randn(32,672,16)
y = np.array([1]*5 + [0]*27)
np.random.shuffle(y)
loss = model.train_on_batch(x,y)
print(train_update+1,loss,np.sum(y))

观察:以下加速分歧:

  • 更高 units (LSTM)
  • 更高层数 (LSTM)
  • 更高 lr <<<=1e-4 时没有分歧, 测试了多达 400 列火车
  • '1'标签 <<y 没有分歧下面,即使有lr=1e-3 ;测试了多达 400 列火车

y = np.random.randint(0,2,32) # makes more '1' labels


更新:未在 TF2 中修复;也可使用 from tensorflow.keras 重现进口。

最佳答案

深入研究 LSTM 公式并深入挖掘源代码,一切都变得清晰起来。

结论:recurrent_dropout 与它无关;一件事情在没有人预料到的地方循环。


真正的罪魁祸首:activation 参数,现在是 'relu',应用于循环转换 -与几乎所有将其显示为无害的 'tanh' 的教程相反。

即,激活仅用于隐藏到输出的转换 - source code ;它直接在计算两种循环状态、细胞和隐藏层上运行:

c = f * c_tm1 + i * self.activation(x_c + K.dot(h_tm1_c, self.recurrent_kernel_c))
h = o * self.activation(c)

解决方案:

  • BatchNormalization 应用于 LSTM 的输入,尤其是如果前一层的输出是无界的(ReLU、ELU 等)
    • 如果前一层的激活有严格的界限(例如 tanh、sigmoid),则在 激活之前应用 BN(使用 activation=None,然后是 BN,然后是 Activation层)
  • 使用activation='selu';更稳定,但仍然可以发散
  • 使用较低的lr
  • 应用渐变剪裁
  • 使用更少的时间步

更多答案,对一些剩余问题:

  • 为什么 recurrent_dropout 被怀疑? 不严谨的测试设置;直到现在我才专注于在没有它的情况下强制发散。然而,它确实有时会加速发散——这可以通过它将非 relu 贡献归零来解释,否则会抵消乘法强化。
  • 为什么非零均值输入会加速发散? 加法对称性;非零均值分布是不对称的,以一个符号为主 - 促进大的预激活,因此大的 ReLU。
  • 为什么在低 lr 的情况下训练可以稳定进行数百次迭代?极端激活通过大误差引起大梯度;低 lr,这意味着调整权重以防止此类激活 - 而高 lr 跳得太远太快。
  • 为什么堆叠的 LSTM 发散得更快?除了为自身提供 ReLU 外,LSTM 还为下一个 LSTM 提供数据,后者随后为自身提供 ReLU 的 ReLU 的 --> 烟花。

2020 年 1 月 22 日更新:recurrent_dropout 实际上可能是一个促成因素,因为它利用倒置 dropout,在培训,在许多时间步上缓解不同的行为。关于此的 Git 问题 here

关于tensorflow - LSTM 'recurrent_dropout' 和 'relu' 产生 NaN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57516678/

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