【问题标题】:Why do Keras's evaluate_generator and evaluate report different accuracies on the same data?为什么 Keras 的 evaluate_generator 和评估在相同数据上报告不同的准确度?
【发布时间】:2020-05-14 11:16:11
【问题描述】:

我正在使用 Keras 的 ImageDataGeneratorflow_from_directory 来训练神经网络。我遇到的问题是evaluate_generatorevaluate 报告相同数据的不同准确性。这是一个minimal example,它报告evaluate_generator 的准确度为0.24,但evaluate 的准确度为0.44:

import os
import numpy as np
import cv2
import keras
import tensorflow as tf

np.random.seed(1)
tf.set_random_seed(1)

test_data_path = os.path.join("data", "test")

def load_data_from_image_files(base_data_path):
    X = []
    y = []
    for data_folder in os.listdir(base_data_path):
        data_folder_path = os.path.join(base_data_path, data_folder)
        if os.path.isdir(data_folder_path):
            for filename in os.listdir(data_folder_path):
                if filename.endswith(".jpg"):
                    X.append(cv2.imread(os.path.join(data_folder_path, filename)))
                    if data_folder == "null":
                        y.append([0])
                    else:
                        y.append([1])
    return np.array(X).astype("float32") / 255.0, np.array(y)

with open("model.json", "r") as json_file:
    model = keras.models.model_from_json(json_file.read())
model.load_weights("model.h5")
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])

X_test, y_test = load_data_from_image_files(test_data_path)
test_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
    test_data_path,
    target_size=(96, 96),
    batch_size=1,
    shuffle=False,
    class_mode="binary")
_, generator_test_accuracy = model.evaluate_generator(generator=test_generator, steps=test_generator.samples)
_, test_accuracy = model.evaluate(X_test, y_test)
print("evaluate_generator: %.3f, evaluate: %.3f" % (generator_test_accuracy, test_accuracy))

(这是来自 keras-generator-minimal-example 存储库的 test.py。)此脚本加载的预训练模型定义如下:

model = keras.models.Sequential()
model.add(keras.layers.Flatten(input_shape=(96, 96, 3)))
model.add(keras.layers.Dense(4, activation="relu"))
model.add(keras.layers.BatchNormalization())
model.add(keras.layers.Dense(1, activation="sigmoid"))
model.compile(loss="binary_crossentropy", optimizer="adam", metrics=["accuracy"])

设置和训练模型的完整脚本是here

我的问题是,上述示例中的model.evaluate_generatormodel.evaluate 是否应该报告相同的准确性,还是我搞砸了?如果我只是缺少一个参数或其他东西,我将不胜感激朝着正确的方向轻推。


旁注:this Github issue 似乎可能相关,尽管该问题的 cmets 中提出的各种修复并没有为我解决问题。设置shuffle=Falseworkers=1 和/或max_queue_size=1 不会改变任何东西,设置use_multiprocessing=True 会导致我的终端中出现一系列以下错误并且脚本挂起:

/home/jack/.local/lib/python3.6/site-packages/keras/utils/data_utils.py:616: UserWarning: The input 0 could not be retrieved. It could be because a worker has died.
  UserWarning)

由于我无法解决这个次要问题,我不知道在evaluate_generator 中设置use_multiprocessing=True 是否可以解决我遇到的精度不匹配的问题。

【问题讨论】:

    标签: python tensorflow machine-learning image-processing keras


    【解决方案1】:

    事实证明,差异是由 OpenCV 的 imread 使用 BGR 格式引起的,而 Keras 的 flow_from_directory expects RGB by default。将通道反转为 RGB 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2022-01-15
      • 2019-08-29
      • 2019-09-16
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      相关资源
      最近更新 更多