第一个训练步骤后 Keras Nan 的准确性和损失

Posted

技术标签:

【中文标题】第一个训练步骤后 Keras Nan 的准确性和损失【英文标题】:Keras Nan accuracy and loss after first training step 【发布时间】:2021-09-04 22:15:56 【问题描述】:

我有一个关于时间数据的分类任务。从第一个 epoch 开始,我的训练损失为 0 或 Nan,准确率始终为 Nan,即使学习率非常小。

我的模特:

def FCN():
    """
    Keras fully convolutional model to predict lead inversion.

    Inspired by solution found here : https://github.com/Bsingstad/FYS-STK4155-oblig3
    """
    inputlayer = keras.layers.Input(shape=(N_MEASURES, N_LEADS))

    conv1 = keras.layers.Conv1D(filters=128, kernel_size=8, input_shape=(N_MEASURES, N_LEADS),
                                padding='same')(inputlayer)
    # conv1 = keras.layers.BatchNormalization()(conv1)
    conv1 = keras.layers.Activation(activation='relu')(conv1)

    conv2 = keras.layers.Conv1D(filters=256, kernel_size=5, padding='same')(conv1)
    # conv2 = keras.layers.BatchNormalization()(conv2)
    conv2 = keras.layers.Activation('relu')(conv2)

    conv3 = keras.layers.Conv1D(128, kernel_size=3, padding='same')(conv2)
    # conv3 = keras.layers.BatchNormalization()(conv3)
    conv3 = keras.layers.Activation('relu')(conv3)

    gap_layer = keras.layers.GlobalAveragePooling1D()(conv3)

    outputlayer = tf.squeeze(keras.layers.Dense(1, activation='sigmoid')(gap_layer), axis=-1)


    model = keras.Model(inputs=inputlayer, outputs=outputlayer)

    model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),
                  optimizer=tf.keras.optimizers.Adam(learning_rate=0.0000000000000000000001, clipnorm=1), 
                  metrics=[
                      tf.keras.metrics.BinaryAccuracy(name='accuracy', dtype=None, threshold=0.5),
                  ])

    return model

训练循环:

train_data_gen = ECGDataGenerator(train_input[train][0:4], train_output[train][0:4],
                                  batch_size=4,
                                  shuffle=True)
val_data_gen = train_data_gen

model = FCN()
for i, (x, y) in enumerate(train_data_gen):
    if i > 0:
        break
    y_pred = model.predict(x)
    print(x.shape)
    print(y)
    print(y_pred)
    print(y_pred.shape)
    loss = model.loss(y, y_pred)
    print(loss)

model.fit(x=train_data_gen,
          epochs=2,
          steps_per_epoch=2,
          # steps_per_epoch=train_data_gen.n_batches,
          validation_data=val_data_gen,
          verbose=1,
          validation_freq=1,
          #               callbacks=[reduce_lr,early_stop]
          )

for i, (x, y) in enumerate(train_data_gen):
    if i > 10:
        break
    y_pred = model.predict(x)
    print(x.shape)
    print(y)
    print(y_pred)
    print(y_pred.shape)
    loss = model.loss(y, y_pred)
    print(loss)

输出如下:

(4, 2500, 12)
[0. 0. 0. 1.]
[0.50108045 0.5034382  0.4999477  0.5007813 ]
(4,)
tf.Tensor(0.6949963, shape=(), dtype=float32)
Epoch 1/2
2/2 [==============================] - 3s 794ms/step - loss: nan - accuracy: nan - val_loss: nan - val_accuracy: nan
Epoch 2/2
2/2 [==============================] - 0s 283ms/step - loss: 0.0000e+00 - accuracy: nan - val_loss: nan - val_accuracy: nan
(4, 2500, 12)
[1. 0. 0. 1.]
[nan nan nan nan]
(4,)
tf.Tensor(nan, shape=(), dtype=float32)

如您所见,一个训练步骤后的训练损失和准确度为 0 或 Nan,但如果我们在训练前手动计算损失不是 Nan。

这里的批量大小是 4。

我尝试过的事情:

添加批量标准化没有帮助。 移除 GlobalAveragePooling1D 可解决 Nan 问题,但会导致形状问题。 降低/提高学习率也是如此。 输入和输出不包含 Nan 值

【问题讨论】:

那么极低的学习率?你试过用 0.01 作为 lr 吗? @EmilianoMartinez 是的,我有,它做同样的事情。低LR只是我试图确保它不会太高,以消除一种可能性。我也尝试了其他优化器,但没有更多成功 为什么在最后一层使用tf.squeeze() 【参考方案1】:

我的自定义数据生成器实际上是一个错误,它返回了数据条目的数量,而不是__len__() 上每个时期的批次数量

【讨论】:

以上是关于第一个训练步骤后 Keras Nan 的准确性和损失的主要内容,如果未能解决你的问题,请参考以下文章

来自 Keras 序列模型训练的 Nan 损失

Keras 模型在保存/加载后预测 NaN

Keras - 具有经常丢失的 GRU 层 - 损失:'nan',准确度:0

Keras 在训练分类 LSTM 序列到序列模型时给出 nan

使用Python,Keras和TensorFlow训练第一个CNN

使用Python,Keras和TensorFlow训练第一个CNN