#python #tensorflow #keras #model-validation #data-augmentation
#питон #тензорный поток #keras #модель-проверка #увеличение данных
Вопрос:
Я реализую CNN, используя keras для выполнения классификации изображений, и я использовал метод .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()
? или я должен исправить seed
, flow_from_directory()
зная, что для выполнения увеличения данных я использовал следующий код:
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)
Кроме того, я знаю, что настройка use_multiprocessing=False
в fit_generator будет стоить мне значительного замедления тренировок. Итак, что, по вашему мнению, могло бы быть лучшим решением
Комментарии:
1. Каково ваше терпение для ранней остановки? Вы сохраняете только лучшие веса или веса самой последней эпохи? Как правило, если вы оцениваете свою модель, вам не следует использовать какие-либо дополнения к тестовым данным. То же самое касается данных проверки, используемых для ранней остановки.
2. Я сохраняю только лучшие веса каждый раз, когда val_loss улучшается: вот мои условия остановки: monitor=’val_loss’, терпение = 7
3. В этом случае ваши потери при проверке / точность оценки должны быть равны потере при проверке / точности за период, когда вы сохранили веса. Обратите внимание: если вы расширяли свои данные проверки в каждую эпоху, это может быть уже не так.
4. train_data, предоставленные в fit_generator, являются дополненными данными, поэтому обычно я выполнял увеличение для каждой эпохи. Кроме того, я хотел бы упомянуть, что потеря / точность проверки для оценки не равна потере / точности проверки с эпохи, когда я сохранил веса
5. @baddy, Согласно документации TF, tensorflow.org/api_docs/python/tf/keras/Model#fit_generator ,
fit_generator
иevaluate_generator
устарели, можете ли вы попробовать сfit
иevaluate
и проверить, как это работает? Спасибо
Ответ №1:
model.fit()
и model.evaluate()
— это правильный путь, поскольку model.fit_generator
и model.evaluate_generator
устарели.
Данные training
и validation
— это дополненные данные, создаваемые генератором. Таким образом, у вас будет небольшая разница в точности. Если вы использовали не дополненные данные validation
или test
в validation_data
of fit_generator
, а также для model.evaluate()
или model.evaluate_generator
, то точность не изменилась бы.
Ниже приведена простая программа классификации кошек и собак, которую я запускал для одной эпохи-
- Генератор данных проверки использует только масштабное преобразование и никаких других методов увеличения.
- Точность проверки отображается после окончания эпохи.
- Сбросьте генератор данных проверки с помощью
val_data_gen.reset()
. Не должно быть необходимости, поскольку мы не делали никаких дополнений. - Оцените точность данных проверки, используя
model.evaluate
и, а такжеmodel.evaluate_generator
.
Точность проверки, вычисленная после окончания эпохи, и точность, вычисленная с использованием 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%