Keras CNN: точность проверки застряла на 70%, точность обучения достигла 100%

1

Я пытаюсь создать нейронную сеть, используя Python с Keras, с целью определения дверей и окон на фотографиях и видео. Вот моя архитектура:

img_width = 32
img_height = 32

model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(img_width, img_height, 3)))
model.add(BatchNormalization())
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(BatchNormalization())
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(BatchNormalization())
model.add(MaxPooling2D(pool_size=(2, 2)))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax'))

Я использую оптимизатор Адама с параметрами по умолчанию и категориальной функцией потери кроссентропии. У меня есть 3 класса входных данных, 685 изображений каждый, и я использую ImageDataGenerator на них. Я также умножил значения steps_per_epoch и validation_steps в fit_generator чтобы компенсировать небольшие наборы данных. Размер партии 32.

train_data_generator = ImageDataGenerator(
    rescale=1. / 255,
    width_shift_range=0.2,
    height_shift_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    validation_split=0.2)

train_generator = train_data_generator.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical',
    subset='training')

validation_generator = train_data_generator.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    class_mode='categorical',
    subset='validation')

early_stopping = EarlyStopping(monitor='val_loss',
                           min_delta=1e-3,
                           patience=10,
                           verbose=1,
                           mode='auto',
                           restore_best_weights=True)

history = model.fit_generator(
    train_generator,
    steps_per_epoch=8*nb_train_samples // batch_size,
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=8*nb_validation_samples // batch_size,
    callbacks=[tensor_board, model_checkpoint, early_stopping])

Теперь моя проблема в том, что моя точность проверки обычно застревает на ~ 70%, в то время как потери проверки начинают быстро расти. В то же время потери при тренировках приближаются к 0, а точность тренировок почти достигает 100%. До сих пор я пытался противостоять этому:

  • изменение размера партии на другие степени 2;
  • изменение скорости обучения Адама;
  • пробуем другой оптимизатор;
  • использование ReduceLROnPlateau или LearningRateScheduler;
  • изменение значения параметра Dropout на любое значение в диапазоне 0,2-0,95;
  • использование Dropouts вместо BatchNormalization;
  • изменение размера изображений.

И, конечно, различные комбинации этих. Я также изменил весь набор данных (до того, как он стал непоследовательным, изображения внутри классов сильно отличались, а классы имели разные размеры). Казалось, ничего не работает. Есть идеи, что я могу делать не так?

  • 0
    Это типичный признак переоснащения.
  • 0
    Да, понял это. Вопрос в том, как мне от этого избавиться? Есть что-то, что я не пробовал, что может сработать?
Показать ещё 2 комментария
Теги:
tensorflow
keras
conv-neural-network
neural-network

2 ответа

1

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

Поскольку у вас есть только пара сотен изображений, вы не можете ничего сделать. По крайней мере, вы должны использовать увеличение данных. Например, если вы берете изображение и переворачиваете его по вертикальной оси, вы получаете новое изображение. Вы также можете увеличить масштаб на разных уровнях или слегка повернуть (не слишком сильно).

BatchNormalization не является техникой регуляризации, поэтому "Dropout вместо BatchNorm" немного странный.

Еще одна вещь, которую вы можете попробовать - это трансферное обучение Получить гораздо больший набор изображений; не имеет значения, являются ли они окнами и дверями или просто чем-то другим. Тренируйте свою сеть для этой задачи. Затем, как только это будет сделано, выбросьте последний слой, замените его новым только для ваших конкретных 3 классов и снова потренируйтесь, но только с весами этого слоя. (Более подробную информацию и тонкости можно найти в литературе).

  • 0
    Я использую увеличение данных, это во втором фрагменте кода. Что касается использования BatchNorm вместо Dropout, я получил идею из этой статьи: vs.datascience.com/…
  • 0
    Миллигенри Не уверен, что мне нравится обоснование этой статьи. Возможно, я смотрю на это слишком наивно, но для меня BatchNorm не «упорядочивает». Это не так, как это уменьшает сложность модели. Но я согласен с идеей, что отсев не так хорош в сверточных слоях.
0

У меня очень похожая проблема, у меня также очень мало обучающих данных (500 изображений на класс, 4 класса), и для аналогичного (если не равного) проекта сети сеть также сильно перегружена, и я не могу получить точность выше 70-74%. Я пробовал гораздо более простую архитектуру CNN и тяжелую регуляризацию, но все еще та же проблема... Вы решили свою? Какова была лучшая точность, которую вы наконец достигли и как? Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню