Keras evaluate() 和 predict() 结果太离谱了

Posted

技术标签:

【中文标题】Keras evaluate() 和 predict() 结果太离谱了【英文标题】:Keras evaluate() and predict() results are way too off 【发布时间】:2019-07-15 13:49:25 【问题描述】:

我正在使用 keras 研究二进制分类模型。请参阅下面设置的数据

print(train_x.shape) --(79520,)
print(test_x.shape) --(26507,)
print(train_y.shape) --(79520,)
print(test_y.shape) --(26507,)

我使用 LSTM,激活是“sigmoid”,“binary_crossentrophy”是我的损失函数。

input_layer = layers.Input((100,))
embedding_layer = layers.Embedding(20001, 100)(input_layer)
lstm_layer = layers.Bidirectional(CuDNNLSTM(64,return_sequences=True))(embedding_layer)
pooling_layer = layers.GlobalMaxPool1D()(lstm_layer)
op_layer = layers.Dense(50, activation='relu')(pooling_layer)
op_layer = layers.Dropout(0.5)(op_layer)
op_layer = layers.Dense(1, activation = 'sigmoid')(op_layer)
model = models.Model(inputs=input_layer, outputs=op_layer)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()

Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 100)               0         
_________________________________________________________________
embedding_1 (Embedding)      (None, 100, 100)          2000100   
_________________________________________________________________
bidirectional_1 (Bidirection (None, 100, 128)          84992     
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 128)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 50)                6450      
_________________________________________________________________
dropout_1 (Dropout)          (None, 50)                0         
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 51        
=================================================================
Total params: 2,091,593
Trainable params: 2,091,593
Non-trainable params: 0
_________________________________________________________________

在 10 个 epoch 结束时,训练准确度为 0.97,验证准确度约为 0.72。

model.fit(train_x, train_y, epochs=10, batch_size=10, validation_split = 0.1)

 Train on 71568 samples, validate on 7952 samples
Epoch 1/10
71568/71568 [==============================] - 114s 2ms/step - loss: 0.6014 - acc: 0.6603 - val_loss: 0.5556 - val_acc: 0.7006
Epoch 2/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.4921 - acc: 0.7573 - val_loss: 0.5449 - val_acc: 0.7194
Epoch 3/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.3918 - acc: 0.8179 - val_loss: 0.5924 - val_acc: 0.7211
Epoch 4/10
71568/71568 [==============================] - 107s 2ms/step - loss: 0.3026 - acc: 0.8667 - val_loss: 0.6642 - val_acc: 0.7248
Epoch 5/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.2363 - acc: 0.8963 - val_loss: 0.7322 - val_acc: 0.7271
Epoch 6/10
71568/71568 [==============================] - 107s 2ms/step - loss: 0.1939 - acc: 0.9155 - val_loss: 0.8349 - val_acc: 0.7150
Epoch 7/10
71568/71568 [==============================] - 107s 2ms/step - loss: 0.1621 - acc: 0.9292 - val_loss: 1.0337 - val_acc: 0.7226
Epoch 8/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.1417 - acc: 0.9375 - val_loss: 0.9998 - val_acc: 0.7221
Epoch 9/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.1273 - acc: 0.9433 - val_loss: 1.1732 - val_acc: 0.7197
Epoch 10/10
71568/71568 [==============================] - 107s 1ms/step - loss: 0.1138 - acc: 0.9481 - val_loss: 1.1462 - val_acc: 0.7222

scores = model.evaluate(test_x,test_y, verbose=1)
print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))

26507/26507 [==============================] - 5s 183us/step
acc: 72.45%

到目前为止,一切似乎都很好,当我在测试数据上运行 predict() 函数时,它会向南走

pred=model.predict(test_x)
pred=pred.argmax(axis=-1)
print(accuracy_score(pred,test_y)*100)

43.48285358584525

from sklearn.metrics import confusion_matrix
confusion_matrix(test_y, pred)

array([[11526,     0],
       [14981,     0]])

我无法理解为什么 evaluate() 和 predict() 结果太离谱了。你能指出什么问题吗?我在 GPU EC2 实例上运行它。软件版本如下。

Keras 2.2.4 TensorFlow 1.12.0

如果需要有关模型的任何其他详细信息,请告诉我。谢谢

【问题讨论】:

【参考方案1】:

您的accval_acc 相距甚远,这表明您的模型严重过度训练。一般来说,您希望有一个模型,其中accval_acc 都彼此接近。更糟糕的是,lossval_loss 之间的差异是巨大的,val_loss 是不稳定的,并且随着实验的逐个时代的进行而增加。这是您在训练模型时想要寻找的类型。值得花时间了解一下过度训练和训练不足以及如何处理这些情况。

此外,准确性通常是二元分类任务的一个弱指标,因此它可能不是训练模型的良好基础。最好改用 f1-score 之类的东西,除非你的真假标签接近 50/50。您可以找到 Keras here 的召回率、精度和 f1。

【讨论】:

感谢您的意见,我会在这里做我的研究和更新

以上是关于Keras evaluate() 和 predict() 结果太离谱了的主要内容,如果未能解决你的问题,请参考以下文章

Keras evaluate()和predict()结果太过分了

Keras evaluate() 和 predict() 结果太离谱了

Keras 张量有一个额外的维度并导致 net.evaluate() 的错误结果

Keras:训练和验证集上的 model.evaluate() 与上次训练时期后的 acc 和 val_acc 不同

为啥在 Keras 中 fit_generator 的准确度、evaluate_generator 的准确度和自定义准确度不同?

keras训练完模型,为啥对训练集进行evaluate和训练时的loss完全不一样?白训练了吗?