Keras - 验证损失和准确性停留在 0

Posted

技术标签:

【中文标题】Keras - 验证损失和准确性停留在 0【英文标题】:Keras - Validation Loss and Accuracy stuck at 0 【发布时间】:2020-08-25 15:02:16 【问题描述】:

我正在尝试在 Tensorflow keras 中为二进制分类训练一个简单的 2 层全连接神经网络。我已使用 sklearn 的 train_test_split() 将数据分成 80-20 的训练集和验证集。

当我调用 model.fit(X_train, y_train, validation_data=[X_val, y_val]) 时,它显示所有 epoch 的验证损失和准确率为 0,但它训练得很好。

另外,当我尝试在验证集上对其进行评估时,输出非零。

有人可以解释一下为什么我在验证时会遇到这个 0 loss 0 accuracy 错误。感谢您的帮助。

这是此错误的完整示例代码 (MCVE):https://colab.research.google.com/drive/1P8iCUlnD87vqtuS5YTdoePcDOVEKpBHr?usp=sharing

【问题讨论】:

别像我一样。当使用分类损失和准确率而不是回归时,在回归模型上遇到了这个问题。 【参考方案1】:

如果您使用 keras 而不是 tf.keras 一切正常。

使用tf.keras,我什至尝试过validation_data = [X_train, y_train],这也给出了零精度。

这是一个演示:

model.fit(X_train, y_train, validation_data=[X_train.to_numpy(), y_train.to_numpy()], 
epochs=10, batch_size=64)

Epoch 1/10
8/8 [==============================] - 0s 6ms/step - loss: 0.7898 - accuracy: 0.6087 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 2/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6710 - accuracy: 0.6500 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 3/10
8/8 [==============================] - 0s 5ms/step - loss: 0.6748 - accuracy: 0.6500 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 4/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6716 - accuracy: 0.6370 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 5/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6085 - accuracy: 0.6326 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 6/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6744 - accuracy: 0.6326 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 7/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6102 - accuracy: 0.6522 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 8/10
8/8 [==============================] - 0s 6ms/step - loss: 0.7032 - accuracy: 0.6109 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 9/10
8/8 [==============================] - 0s 5ms/step - loss: 0.6283 - accuracy: 0.6717 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
Epoch 10/10
8/8 [==============================] - 0s 5ms/step - loss: 0.6120 - accuracy: 0.6652 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00

所以,tensorflow 实现 fit 肯定存在一些问题。

我挖了源码,貌似是validation_data的负责人:

...
...
        # Run validation.
        if validation_data and self._should_eval(epoch, validation_freq):
          val_x, val_y, val_sample_weight = (
              data_adapter.unpack_x_y_sample_weight(validation_data))
          val_logs = self.evaluate(
              x=val_x,
              y=val_y,
              sample_weight=val_sample_weight,
              batch_size=validation_batch_size or batch_size,
              steps=validation_steps,
              callbacks=callbacks,
              max_queue_size=max_queue_size,
              workers=workers,
              use_multiprocessing=use_multiprocessing,
              return_dict=True)
          val_logs = 'val_' + name: val for name, val in val_logs.items()
          epoch_logs.update(val_logs)

内部调用model.evaluate,因为我们已经建立evaluate工作正常,我意识到唯一的罪魁祸首可能是unpack_x_y_sample_weight

所以,我研究了实现:

def unpack_x_y_sample_weight(data):
  """Unpacks user-provided data tuple."""
  if not isinstance(data, tuple):
    return (data, None, None)
  elif len(data) == 1:
    return (data[0], None, None)
  elif len(data) == 2:
    return (data[0], data[1], None)
  elif len(data) == 3:
    return (data[0], data[1], data[2])

  raise ValueError("Data not understood.")

这太疯狂了,但是如果你只是传递一个元组而不是一个列表,由于unpack_x_y_sample_weight 内部的检查,一切都会正常工作。 (在此步骤之后您的标签丢失了,并且不知何故数据在evaluate 中得到修复,因此您在没有合理标签的情况下进行训练,这似乎是一个错误,但文档明确指出要传递元组)

以下代码给出了正确的验证准确性和损失:

model.fit(X_train, y_train, validation_data=(X_train.to_numpy(), y_train.to_numpy()), 
epochs=10, batch_size=64)

Epoch 1/10
8/8 [==============================] - 0s 7ms/step - loss: 0.5832 - accuracy: 0.6696 - val_loss: 0.6892 - val_accuracy: 0.6674
Epoch 2/10
8/8 [==============================] - 0s 7ms/step - loss: 0.6385 - accuracy: 0.6804 - val_loss: 0.8984 - val_accuracy: 0.5565
Epoch 3/10
8/8 [==============================] - 0s 7ms/step - loss: 0.6822 - accuracy: 0.6391 - val_loss: 0.6556 - val_accuracy: 0.6739
Epoch 4/10
8/8 [==============================] - 0s 6ms/step - loss: 0.6276 - accuracy: 0.6609 - val_loss: 1.0691 - val_accuracy: 0.5630
Epoch 5/10
8/8 [==============================] - 0s 7ms/step - loss: 0.7048 - accuracy: 0.6239 - val_loss: 0.6474 - val_accuracy: 0.6326
Epoch 6/10
8/8 [==============================] - 0s 7ms/step - loss: 0.6545 - accuracy: 0.6500 - val_loss: 0.6659 - val_accuracy: 0.6043
Epoch 7/10
8/8 [==============================] - 0s 7ms/step - loss: 0.5796 - accuracy: 0.6913 - val_loss: 0.6891 - val_accuracy: 0.6435
Epoch 8/10
8/8 [==============================] - 0s 7ms/step - loss: 0.5915 - accuracy: 0.6891 - val_loss: 0.5307 - val_accuracy: 0.7152
Epoch 9/10
8/8 [==============================] - 0s 7ms/step - loss: 0.5571 - accuracy: 0.7000 - val_loss: 0.5465 - val_accuracy: 0.6957
Epoch 10/10
8/8 [==============================] - 0s 7ms/step - loss: 0.7133 - accuracy: 0.6283 - val_loss: 0.7046 - val_accuracy: 0.6413

因此,由于这似乎是一个错误,我刚刚在 Tensorflow Github 存储库中打开了一个相关问题:

https://github.com/tensorflow/tensorflow/issues/39370

【讨论】:

以上是关于Keras - 验证损失和准确性停留在 0的主要内容,如果未能解决你的问题,请参考以下文章

Keras DNN 预测模型准确率没有提高

从 history.history Keras 序列中绘制模型损失和模型准确性

培训减少,验证 - 增加。培训损失,验证损失减少

Keras cifar10 示例验证和测试损失低于训练损失

验证准确度为零,损失更高。使用 LSTM 进行意图分类

在 Keras 图像分类中不会减少的损失验证