1

背景:

我正在使用 LSTM(内置于 tensorflow.js)根据输入文本文件生成文本。我将文本文件拆分为样本,我最初使每个样本的长度为 10。然后我将它放大到 20,一切都很好。最后,我把它放大到 100,LSTM 的梯度爆炸了,损失变成了 NaN。

我尝试了梯度裁剪、梯度归一化、权重正则化、批量减小、更改模型的架构……没有任何效果。

唯一有帮助的是减小我的 LSTM 的大小(从 3 512 层到 3 64 层),但我希望我的模型保持其计算能力。

我的模型结构如下:

//chars.length is how many unique characters are in the training set.
const model = tf.sequential({
    layers: [
        tf.layers.lstm({ inputShape: [null, chars.length], units: 512, activation: "relu", returnSequences: true }),
        tf.layers.lstm({ units: 512, activation: "relu", returnSequences: true }),
        tf.layers.lstm({ units: 512, activation: "relu", returnSequences: false }),
        tf.layers.dense({ units: chars.length, activation: "softmax" }),
    ]
});

然后,我以以下方式编译我的模型:

model.compile({
    optimizer: "adam",
    loss: "categoricalCrossentropy",
    metrics: ["accuracy"],
    clipValue: 0.5,
    clipNorm: 1,
    learningRate: 0.001
})

我检查了我的训练数据,它都是有效的。

如果渐变被剪裁,为什么我的 LSTM 渐变仍然会爆炸?是否有其他原因导致 NaN 损失?关于如何解决它的任何想法?

(权重正则化、批量减小和梯度裁剪的传统方法不起作用。)

完整代码:https ://gist.github.com/N8python/22c42550ae1cf50236a4c63720cc3ee8

4

1 回答 1

1

您应该先尝试在较短的序列上进行训练,然后在逐渐变长的序列上以相同的权重训练相同的模型。如果您在长序列上使用随机初始化的权重启动模型,它往往会不稳定。因此,我们可以使用从较短序列上训练获得的合理权重开始模型,然后再转向较长序列。

于 2020-09-18T14:53:39.397 回答