背景:
我正在使用 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