Непоследовательная оценка точности с использованием define_generator на керасе - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь решить проблему в моей модели CNN.Я использую набор данных, который структурирован следующим образом: Мои данные организованы следующим образом:

  • поезд
    • паразитирован
    • не заражен
  • тест
    • паразитированный
    • незараженный
  • проверка
    • паразитированный
    • незараженный

Мой набор данных слишком велик, и я использую ImageDataGenerator для предварительной обработки изображений, а также загружаю их в пакетном режиме (для уменьшения вычислительных затрат).Сначала я настроил ImageDataGenerator следующим образом:

from keras.preprocessing.image import ImageDataGenerator

#Define a ImageDataGenerator for each dataset. 
#This augmentation process is only to rescale each imagem to 1/255

datagen_train = ImageDataGenerator(rescale=1./255) #rescale=1./255
datagen_test = ImageDataGenerator(rescale=1./255)
datagen_valid = ImageDataGenerator(rescale=1./255)

#Define a batch_size parameter
batch_size=32

# Here .flow_from_directory is used to transform 
train_generator = datagen_train.flow_from_directory(
    'content/cell_images/train', #Train folder path 
    target_size=(150,150), #all images will be resized to 150x150
    batch_size=batch_size,
    class_mode='categorical') # We use categorical_crossentropy loss, 
                              # we need categorical labels


test_generator = datagen_test.flow_from_directory(
    'content/cell_images/test', #Test folder path
    target_size=(150,150), #all images will be resized to 150x150
    batch_size=batch_size,
    class_mode='categorical')         

valid_generator = datagen_valid.flow_from_directory(
    'content/cell_images/valid',
     target_size=(150,150),
     batch_size=32,
     class_mode='categorical') 

Для подгонки модели использовались fit_generator и контрольная точка для сохранения лучших весов на основе validation_accuracy:

from keras.callbacks import ModelCheckpoint

# Define epochs number
epochs = 10

# Create a checkpointer to save only the best params
checkpointer = ModelCheckpoint(filepath='cnn_model.weights.best.hdf5', 
                          verbose=1, save_best_only=True)

model.fit_generator(train_generator,
               steps_per_epoch=train_generator.samples//batch_size,
               epochs=epochs,
               callbacks=[checkpointer],
               validation_data=valid_generator,
               validation_steps=valid_generator.samples//batch_size)

Инаконец, лучшие веса были загружены в модель.Модель была оценена с использованием test_set:

# load the weights that yielded the best validation accuracy
model.load_weights('cnn_model.weights.best.hdf5')

#evaluate and print test accuracy
score = model.evaluate_generator(test_generator,
       test_generator.samples//batch_size)
print('\n', 'Test accuracy:', score[1])

Но вот моя проблема: каждый раз, когда я запускаю только model.evaluate_generator, не тренируя модель снова (т.е. сохраняя те же веса), она возвращает разные оценки точности.

Я искал решение, читал много постов, чтобы получить некоторую информацию, и недавно я получил некоторый прогресс.

Недавно я обнаружил, основываясь на этом посте что если я установлю Shuffle=True и batch_size=1 в test_generator:

test_generator = datagen_test.flow_from_directory(
    'content/cell_images/test', #Test folder path
    target_size=(150,150), #all images will be resized to 150x150
    batch_size=1,
    class_mode='categorical',
    shuffle=False)`

и steps = test_generator.samples in test_generator: score = model.evaluate_generator(test_generator, test_generator.samples)

значения больше не изменятся.

Я исследовал эффект от масштабирования 1./255 на основе этого поста .Для этого я использовал обратные вызовы с контрольной точкой, чтобы сохранить веса только для лучшей валидации.После этого я загрузил в модель лучшие веса и оценил их с помощью model.evaluate_generator, как упомянуто выше.Чтобы проверить согласованность баллов, я также использую балл валидации, чтобы проверить, совпадают ли значения, возвращаемые обратными вызовами для наилучших весов, с оценкой_генератором.Перед запуском метода define_generator с validation_set я использовал те же параметры набора тестов:

valid_generator = datagen_valid.flow_from_directory(
    'content/cell_images/valid',
    target_size=(150,150),
    batch_size=1,
    class_mode='categorical',
    shuffle=False)


#evaluate and print test accuracy
score = model.evaluate_generator(valid_generator, 
        valid_generator.samples)
print('\n', 'Valid accuracy:', score[1])

#evaluate and print test accuracy
score = model.evaluate_generator(test_generator, 
test_generator.samples)
print('\n', 'Test accuracy:', score[1])

Любопытно, что я заметил, что:

Когда я не использую масштабирование (1./ 255):

datagen_train = ImageDataGenerator()

datagen_test = ImageDataGenerator()

datagen_valid = ImageDataGenerator()

значение validation_score, отображаемое с помощью обратных вызовов (0,5), этоточно то же самое, полученное из model.evaluate_generator (0.5);Кроме того, тестовый набор возвращает оценку точности = 0,5.

Когда я использую масштабирование (1./255):

datagen_train = ImageDataGenerator(rescale=1./255)

datagen_test = ImageDataGenerator(rescale=1./255)

datagen_valid = ImageDataGenerator(rescale=1./255)

разница между значением validation_score, отображаемым обратными вызовами (0,9515):

Epoch 7/10
688/688 [==============================] - 67s 97ms/step - loss: 
0.2017 - acc: 0.9496 - val_loss: 0.1767 - val_acc: 0.9515

Epoch 00007: val_loss improved from 0.19304 to 0.17671, saving model 
to cnn_model.weights.best.hdf5

, и оценкой, полученной из model.evaluate_generator (Valid accuracy: 0.9466618287373004) он очень маленький;Использование набора тестов - Test accuracy: 0.9078374455732946

Исходя из этой небольшой разницы между оценочными показателями, могу ли я сделать вывод, чтоя оценка_генератора работает корректно?И могу ли я сделать вывод, что оценка точности на test_set также является правильной?Или есть другой подход к решению этой проблемы?

Я разочарован этой проблемой.Извините за длинный пост, я пытаюсь быть более дидактическим, я могу.

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...