Keras - 变分自动编码器 NaN 损失

Posted

技术标签:

【中文标题】Keras - 变分自动编码器 NaN 损失【英文标题】:Keras - Variational Autoencoder NaN loss 【发布时间】:2018-09-13 00:58:17 【问题描述】:

我正在尝试使用我在 Keras 示例中找到的变分自动编码器的实现 (https://github.com/keras-team/keras/blob/master/examples/variational_autoencoder.py)。

我刚刚重构了代码,以便在 Jupyter 笔记本中更轻松地使用它(我的代码:https://github.com/matbell/Autoencoders/blob/master/models/vae.py)。

但是,当我尝试根据我的数据拟合模型时,我得到以下输出:

Autoencoders/models/vae.py:69: UserWarning: Output "dense_5" missing from loss dictionary. We assume this was done on purpose, and we will not be expecting any data to be passed to "dense_5" during training.
self.vae.compile(optimizer='rmsprop')

Train on 15474 samples, validate on 3869 samples
Epoch 1/50
15474/15474 [==============================] - 1s 76us/step - loss: nan - val_loss: nan
Epoch 2/50
15474/15474 [==============================] - 1s 65us/step - loss: nan - val_loss: nan
Epoch 3/50
15474/15474 [==============================] - 1s 69us/step - loss: nan - val_loss: nan
Epoch 4/50
15474/15474 [==============================] - 1s 62us/step - loss: nan - val_loss: nan

所有训练时期的损失都保持不变。

我不是深度学习和神经网络领域的专家,所以也许我遗漏了一些东西......

这是输入数据,其中datalabels 是两个pandas.DataFrame

In: data.shape
Out: (19343, 87)

In: label.shape
Out: (19343, 1)

这就是我在 Jupyter 笔记本中使用 Vae 类(来自我的代码)的方式:

INPUT_SIZE = len(data.columns)
X_train, X_test, y_train, y_test = train_test_split(data, labels, test_size = 0.2)

vae = Vae(INPUT_SIZE, intermediate_dim=32)
vae.fit(X_train, X_test)

感谢您的帮助!

【问题讨论】:

您能否将您所做的更改添加到原始代码中,以便我们可以更轻松地跟踪您可能会犯的错误? @ShashiTunga 我报告了原始代码和我的“修改”的链接。如您所见,我没有对代码进行任何更改,我只是将其重新格式化为一个 Python 类,其中包含三个主要方法:init()fit()encode() 你用的是哪个版本的 Keras? 【参考方案1】:

您可能希望将 log_var 密集层初始化为零。我自己也遇到了问题(代码略有不同,但实际上是这样做的),结果表明,无论初始化的变化权重多么小,它们都会在几轮 SGD 中爆炸。

epsilon ~N(0,1) 和重建误差之间的随机相关性足以将权重轻轻地带入非零值。

编辑 - 另外,包裹变化的指数确实有助于爆炸梯度。由于指数的原因,将权重的初始值设置为零会给出一个初始变化。将其初始化为较低的负值,同时释放初始接近于零的变化,使梯度在第一次运行时变得巨大。零给了我最好的结果。

【讨论】:

在增加潜在维度时,我一直在努力解决 NAN 损失,设置方差层的初始权重解决了这个问题(nan 错误过去发生在 ~1000 步,现在训练已经超过 400k 步) .列出可以在此处为未来读者完成的其他潜在事情:在存在日志的损失函数中添加 epsilon、渐变裁剪、在各个位置添加 nan 错误检查以进行调试(例如tf.verify_tensor_all_finite)。 您是否知道围绕log_var 变量的权重初始化主题的任何更广泛的讨论?我还发现 Zeros 的行为更好,但除了这篇文章之外,在文献或在线讨论中找不到任何东西。 对不起,我真的不知道关于这个话题的任何讨论,这是我通过反复试验发现的。 @Monstah 你能写下你的解决方案的工作代码吗?【参考方案2】:

如果以上都没有帮助到你。确保您的输入在 [0, 1] 之间标准化。使用 MNIST 的一种简单方法是

X_train = X_train.astype('float32') / 255.0
X_test = X_test.astype('float32') / 255.0

【讨论】:

【参考方案3】:

您的输入由 NaN 值组成,这就是您在输出中看到 Nan 的原因。您可以使用以下方法在 numpy 数组中计算 NaN:

np.count_nonzero(np.isnan(data))

如果 NAN 不相关,只需将它们从您的训练数据中删除或将它们映射到一个特定的常量(如 0 或 -1),这将解决您的问题

【讨论】:

【参考方案4】:

我遇到了类似的问题,因为有包含 NaN 的输入。如果其中只有几个带有 NaN 的示例,那么所有的权重和损失也将是 NaN。再次检查数据内容!

【讨论】:

是的,我也使用了错误的输入。我们应该先检查输入。【参考方案5】:

您不正确地拟合模型。您的健康电话意味着: vae.fit(X = X_train, y = X_test),虽然应该是:

vae.fit(X_train,X_train , validation_data = X_test)

【讨论】:

以上是关于Keras - 变分自动编码器 NaN 损失的主要内容,如果未能解决你的问题,请参考以下文章

变分自动编码器:Keras 中的实现预热

用于时间序列异常检测的 Keras LSTM-VAE(变分自动编码器)

变分自动编码器:MSE 与 BCE

基于变分自动编码器(Variational Autoencoders)疾病预测系统实战:(Keras实现并可视化训练和验证误差最后给出topK准确率和召回率)

使用预训练 vgg19 tensorflow,Keras 在 CNN 自动编码器中定义自定义损失(感知损失)

用于可变长度序列的 LSTM 变分自动编码器