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
所有训练时期的损失都保持不变。
我不是深度学习和神经网络领域的专家,所以也许我遗漏了一些东西......
这是输入数据,其中data
和labels
是两个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 LSTM-VAE(变分自动编码器)
基于变分自动编码器(Variational Autoencoders)疾病预测系统实战:(Keras实现并可视化训练和验证误差最后给出topK准确率和召回率)