【问题标题】:Should I use evaluate_generator or evaluate to evaluate my CNN model我应该使用评估生成器还是评估来评估我的 CNN 模型
【发布时间】:2020-09-01 08:58:10
【问题描述】:

我正在使用 keras 实现一个 CNN 来执行图像分类,并且我使用 .fit_generator() 方法来训练模型,直到验证停止条件我使用了下一个代码:

history_3conv = cnn3.fit_generator(train_data,steps_per_epoch = train_data.n // 98, callbacks = [es,ckpt_3Conv], 
    validation_data = valid_data, validation_steps = valid_data.n // 98,epochs=50)

停止前的最后两个时期是下一个:

如图所示,最后一次训练的准确率为 0.91。然而,当我使用model.evaluate() 方法评估训练、测试和验证集时,我得到了下一个结果:

所以,我的问题是:为什么我得到两个不同的值?

我应该使用evaluate_generator() 吗?或者我应该在flow_from_directory() 中修复seed,知道要执行数据增强我使用了下一个代码:

trdata = ImageDataGenerator(rotation_range=90,horizontal_flip=True)
vldata = ImageDataGenerator()
train_data = trdata.flow(x_train,y_train,batch_size=98)
valid_data = vldata.flow(x_valid,y_valid,batch_size=98)

此外,我知道在 fit_generator 中设置 use_multiprocessing=False 会大大降低训练速度。那么你认为最好的解决方案是什么

【问题讨论】:

  • 你对提前停止有什么耐心?你是只保存最好的权重还是最后一个时期的权重?一般来说,如果你评估你的模型,你不应该对测试数据使用任何扩充。用于提前停止的验证数据也是如此。
  • 每次 val_loss 得到改善时,我只保存最好的权重:这是我的停止条件:monitor='val_loss',patience=7
  • 在这种情况下,您的验证损失/评估准确度应该等于您保存权重的时期的验证损失/准确度。注意:如果您在每个 epoch 中都增加了验证数据,则可能不再是这种情况了。
  • fit_generator 中提供的 train_data 是增强数据,因此通常我对每个 epoch 进行增强。另外,我想提一下,评估的验证损失/准确性不等于我保存权重的时代的验证损失/准确性
  • @baddy,根据 TF 文档,tensorflow.org/api_docs/python/tf/keras/Model#fit_generator、fit_generator 和 evaluate_generator 已弃用,您可以尝试使用 fit 和 evaluate 并检查它的进展情况吗?谢谢

标签: python tensorflow keras model-validation data-augmentation


【解决方案1】:

model.fit() 和 model.evaluate() 是不推荐使用的方式,因为 model.fit_generator 和 model.evaluate_generator 已弃用。

training 和 validation 数据是生成器生成的增强数据。因此,您的准确性会有所不同。如果您在fit_generator 的validation_data 以及model.evaluate() 或model.evaluate_generator 中使用了未增强的validation 或test 数据,那么准确性不会有任何变化。

下面是我运行了一个 epoch 的简单猫狗分类程序-

  1. 验证数据生成器仅具有重新缩放转换,没有其他增强技术。
  2. 在 epoch 结束后显示验证准确度。
  3. 使用val_data_gen.reset() 重置验证数据生成器。不过应该没有必要,因为我们还没有进行任何增强。
  4. 使用model.evaluate 和model.evaluate_generator 评估验证数据的准确性。

epoch 结束后计算的验证准确度与使用model.evaluate 和model.evaluate_generator 计算的准确度匹配。

代码:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.optimizers import Adam

import os
import numpy as np
import matplotlib.pyplot as plt

_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'

path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)

PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')

train_dir = os.path.join(PATH, 'train')
validation_dir = os.path.join(PATH, 'validation')

train_cats_dir = os.path.join(train_dir, 'cats')  # directory with our training cat pictures
train_dogs_dir = os.path.join(train_dir, 'dogs')  # directory with our training dog pictures
validation_cats_dir = os.path.join(validation_dir, 'cats')  # directory with our validation cat pictures
validation_dogs_dir = os.path.join(validation_dir, 'dogs')  # directory with our validation dog pictures

num_cats_tr = len(os.listdir(train_cats_dir))
num_dogs_tr = len(os.listdir(train_dogs_dir))

num_cats_val = len(os.listdir(validation_cats_dir))
num_dogs_val = len(os.listdir(validation_dogs_dir))

total_train = num_cats_tr + num_dogs_tr
total_val = num_cats_val + num_dogs_val

batch_size = 1
epochs = 1
IMG_HEIGHT = 150
IMG_WIDTH = 150

train_image_generator = ImageDataGenerator(rescale=1./255,brightness_range=[0.5,1.5]) # Generator for our training data
validation_image_generator = ImageDataGenerator(rescale=1./255) # Generator for our validation data

train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                           directory=train_dir,
                                                           shuffle=True,
                                                           target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                           class_mode='binary')

val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                              directory=validation_dir,
                                                              target_size=(IMG_HEIGHT, IMG_WIDTH),
                                                              class_mode='binary')

model = Sequential([
    Conv2D(16, 3, padding='same', activation='relu', input_shape=(IMG_HEIGHT, IMG_WIDTH ,3)),
    MaxPooling2D(),
    Conv2D(32, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Conv2D(64, 3, padding='same', activation='relu'),
    MaxPooling2D(),
    Flatten(),
    Dense(512, activation='relu'),
    Dense(1)
])

optimizer = 'SGD'

model.compile(optimizer=optimizer, 
          loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
          metrics=['accuracy'])

history = model.fit_generator(
          train_data_gen,
          steps_per_epoch=total_train // batch_size,
          epochs=epochs,
          validation_data=val_data_gen,
          validation_steps=total_val // batch_size)


from sklearn.metrics import confusion_matrix

# Reset 
val_data_gen.reset()

# Evaluate on Validation data
scores = model.evaluate(val_data_gen)
print("%s%s: %.2f%%" % ("evaluate ",model.metrics_names[1], scores[1]*100))

scores = model.evaluate_generator(val_data_gen)
print("%s%s: %.2f%%" % ("evaluate_generator ",model.metrics_names[1], scores[1]*100))

输出:

Found 2000 images belonging to 2 classes.
Found 1000 images belonging to 2 classes.
2000/2000 [==============================] - 74s 37ms/step - loss: 0.6932 - accuracy: 0.5025 - val_loss: 0.6815 - val_accuracy: 0.5000
1000/1000 [==============================] - 11s 11ms/step - loss: 0.6815 - accuracy: 0.5000
evaluate accuracy: 50.00%
evaluate_generator accuracy: 50.00%

【讨论】:

    猜你喜欢
    • 2017-03-24
    • 2016-08-19
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-06
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多