Keras 有状态 LSTM 为验证损失返回 NaN

数据挖掘 喀拉斯 lstm 多标签分类
2022-02-18 09:04:39

我在解释模型的训练和验证损失、敏感性和特异性中发生的事情时遇到了一些麻烦。我的验证敏感性和特异性以及损失是 NaN,我正在尝试诊断原因。

我的训练集有 50 个时间序列示例,每个示例有 24 个时间步长,以及 500 个二进制标签(形状:(50、24、500))。我的验证集具有形状 (12, 24, 500)。当然,我预计神经网络会大量过度拟合。

因为我对有状态 LSTM 感兴趣,所以我遵循了 philipperemy 的建议并使用model.train_on_batch了 batch_size = 1。我有多个输入:一个称为seq_model_in时间序列,一个称为feat_in不是时间序列(因此连接到模型在 LSTM 之后但在分类步骤之前)。

由于我的课程高度不平衡,我也使用了 Keras 的class_weights功能。为了使这个函数在多标签设置中工作,我将两列连接到我的响应的前面(一个全 0 和一个全 1),这样响应的最终形状是 (50, 502)。

 feat_in = Input(shape=(1,), batch_shape=(1, 500), name='feat_in')
 feat_dense = Dense(out_dim, name='feat_dense')(feat_in)
 seq_model_in = Input(shape=(1,), batch_shape=(1, 1, 500), name='seq_model_in')
 lstm_layer = LSTM(10, batch_input_shape=(1, 1, 500), stateful=stateful)(seq_model_in)
 merged_after_lstm = Concatenate(axis=-1)([lstm_layer, feat_dense])
 dense_merged = Dense(502, activation="sigmoid")(merged_after_lstm)

我已经在 Keras 中编写了这个模型用于时间序列预测(下一个时间步的多标签预测):

训练和验证指标以及损失不会在每个时期发生变化,这令人担忧(并且,我认为这是过度拟合的症状),但我也担心理解图表本身。

以下是 TensorBoard 图表:

训练损失 验证损失 训练灵敏度 验证灵敏度 训练特异性 验证特异性

每个时期的训练损失应该(大致)减少,验证损失也应该减少。训练的敏感性和特异性分别为 92% 和 97.5%(另一个可能的过度拟合迹象)。

我的问题是:

  • 我是否认为敏感性和特异性图都应该与 train_spec 图具有相同的一般形状?
  • 为什么训练敏感度图是这样的?
  • 为什么验证损失返回 NaN?
1个回答

不知道张量板的东西,但是 val loss 的 NAN 可能是由一个意想不到的非常大或非常小的数字引起的。由于您的训练数据集非常小,因此验证数据很有可能具有非常不同的基础分布。如果您的 NN 的潜在空间不是连续的,并且验证样本与训练样本的分布相距太远,则 NN 将无法很好地处理它们。在分类问题中,这将导致错误分类(很可能)。但是,当您生成预测时,这可能意味着 NN 创建的数字非常大或非常小。然后,在您的损失函数中,可能会得到除以零或无穷大的东西。

我建议查看您正在使用的损失函数,如果它有一个除法,分母可以为零吗?对此的一种解决方案是使用剪辑函数来确保您的预测张量在 0+epsilon 和 1 之间。

def clipped_squared_error_loss(y_true, y_pred):
    y_true = K.clip(y_true, K.epsilon(), 1)
    y_pred = K.clip(y_pred, K.epsilon(), 1)
    return K.sum(K.square(y_pred - y_true))

您可能还想研究 Kullback Leibler Divergence 作为使 NN 的潜在空间连续的一种方法。