【问题标题】:Keras model evaluate() vs. predict_classes() gives different accuracy resultsKeras 模型 evaluate() 与 predict_classes() 给出不同的准确度结果
【发布时间】:2020-03-06 00:38:17
【问题描述】:

我最近一直在使用 TF2.0。我已经为图像的二进制分类训练了一个简单的 CNN 模型(使用 Keras Sequential API)。我使用 tf.data.Dataset 从磁盘加载图像。实际上模型得到了相当不错的准确率,train binary_accuracy: 0.9831 and validation binary_accuracy: 0.9494.

尝试使用 model.evaluate() 评估模型。它给出了 0.9460 的二进制精度。但是当我尝试使用 predict_classes() 手动计算二进制精度时,我得到了大约 0.384。我不知道是什么问题。请帮帮我。

我添加了用于编译和训练模型的代码。还有用于评估我的模型的代码。

train_data = tf.data.Dataset.from_tensor_slices((tf.constant(train_x),tf.constant(train_y)))
val_data = tf.data.Dataset.from_tensor_slices((tf.constant(val_x),tf.constant(val_y)))

train_data = train_data.map(preproc).shuffle(buffer_size=100).batch(BATCH_SIZE)
val_data = val_data.map(preproc).shuffle(buffer_size=100).batch(BATCH_SIZE)

model.compile(optimizer=Adam(learning_rate=0.0001),
              loss='binary_crossentropy',
              metrics=[tf.keras.metrics.BinaryAccuracy()])

checkpointer = ModelCheckpoint(filepath='weights.hdf5', verbose=1, save_best_only=True)

time1 = time.time()
history = model.fit(train_data.repeat(),
                    epochs=EPOCHS,
                    steps_per_epoch=STEPS_PER_EPOCH,
                    validation_data=val_data.repeat(),
                    validation_steps=VAL_STEPS,
                    callbacks=[checkpointer])

29/29 [==============================] - 116s 4s/step - loss: 0.0634 - binary_accuracy: 0.9826 - val_loss: 0.1559 - val_binary_accuracy: 0.9494

现在用看不见的数据进行测试

test_data = tf.data.Dataset.from_tensor_slices((tf.constant(unseen_faces),tf.constant(unseen_labels)))
test_data = test_data.map(preproc).batch(BATCH_SIZE)

model.evaluate(test_data)

9/9 [==============================] - 19s 2s/step - loss: 0.1689 - binary_accuracy: 0.9460

同一模型,当我尝试使用具有相同数据集的model.predict_classes 计算准确率时,预测结果与评估报告相差甚远。二进制准确率约为 38%。

编辑 1: 我在训练时使用的预处理函数

def preproc(file_path,label):
    img = tf.io.read_file(file_path)
    img = tf.image.decode_jpeg(img)
    img = (tf.cast(img, tf.float32)/127.5) - 1
    return tf.image.resize(img,(IMAGE_HEIGHT,IMAGE_WIDTH)),label

手动预测代码

from sklearn.metrics import classification_report

#Testing preprocessing function
def preproc_test(file_path):
    img = tf.io.read_file(file_path)
    img = tf.image.decode_jpeg(img)
    img = (tf.cast(img, tf.float32)/127.5) - 1
    return tf.image.resize(img,(IMAGE_HEIGHT,IMAGE_WIDTH))

unseen_faces = []
unseen_labels = []
for im_path in glob.glob('dataset/data/*'):
    unseen_faces.append(im_path)
    if 'real' in i:
        unseen_labels.append(0)
    else:
        unseen_labels.append(1)

unseen_faces = list(map(preproc_test,unseen_faces))
unseen_faces = tf.stack(unseen_faces)

predicted_labels = model.predict_classes(unseen_faces)

print(classification_report(unseen_labels,predicted_labels,[0,1]))

              precision    recall  f1-score   support

           0       0.54      0.41      0.47        34
           1       0.41      0.54      0.47        26

    accuracy                           0.47        60
   macro avg       0.48      0.48      0.47        60
weighted avg       0.48      0.47      0.47        60


【问题讨论】:

  • 请说明您使用predict_classes 计算准确度的准确程度。 preproc 是什么?
  • @desertnaut preproc 是一个预处理函数。代码请参考编辑1
  • 找到了答案。使用 Categorical_Crossentry 损失。见帖子here

标签: python tensorflow machine-learning keras


【解决方案1】:

在我的情况下,这是因为我的基本事实和预测结果的形状不同。我正在通过(x_train, y_train), (x_test, y_test) = cifar10.load_data() 加载数据,其中y_train 是形状为(50000,1) 的二维ndarray,但来自model.predict_classes 的预测形状为(50000,)。如果我直接通过np.mean(pred==y_train) 比较它们,我会得到0.1 的结果,这是不正确的。相反,np.mean(pred==np.squeeze(y_train)) 给出了正确的结果。

【讨论】:

    【解决方案2】:

    您的模型在trainingtesting 期间都表现良好。评估准确性是基于预测的,所以您在使用model.predict_classes() 时可能会犯一些逻辑错误。请在评估时检查您是否使用了经过训练的模型权重,而不是任何随机初始化的模型。

    evaluate:模型将分离这部分训练数据,不会对其进行训练,并将在每个 epoch 结束时评估损失和该数据上的任何模型指标。 model.evaluate() 用于评估您的训练模型。它的输出是准确性或损失,而不是对输入数据的预测。

    predict:为输入样本生成输出预测。 model.predict() 实际预测,其输出是目标值,根据您的输入数据预测。

    P.S.:对于二元分类问题的准确率

    【讨论】:

    • 嗨,请检查我在编辑 1 中添加的代码。我在这里遗漏了什么吗?
    • 我在您的代码中看不到任何问题。请查看您是否在训练和推理中使用相同的图像格式(BGR/RGB)和预处理。此外,请检查您是否在预测期间使用了经过训练的权重。
    猜你喜欢
    • 2017-08-08
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2019-02-03
    • 2019-07-19
    • 2020-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多