Моя сверточная нейронная сеть переоснащается - PullRequest
0 голосов
/ 31 января 2020

Недавно я построил простую сверточную нейронную сеть для распознавания жестов рук, используя вычитание фона, чтобы сделать руку белой фигурой на экране с черным фоном. Он был построен с использованием Keras Conv2D по большей части. В моем наборе данных 1000 изображений для обучения и 100 изображений для проверки и тестирования. Как ни странно, проблема возникает сразу после первой эпохи, когда потеря модели значительно снижается. Обычно оно уменьшается с некоторого большого числа, такого как 183, до 1 в начале второй эпохи. Все фотографии из набора данных с моей стороны, использующие cv2, но я проводил тестирование только своей рукой, так что проблем не должно быть. В случае, если с набором данных возникла проблема, я попытался взять 3 разных набора данных, один из которых использовал метод Canny cv2, который по существу отслеживает линию руки и делает оставшуюся часть пи c черным, чтобы увидеть, имеет ли это значение. Несмотря на это, то же самое продолжало происходить. Кроме того, я добавил несколько слоев Dropout в разных местах, чтобы увидеть эффект, и всегда происходит одно и то же, в котором потери резко уменьшаются, и это показывает признаки переоснащения. Я также реализовал EarlyStopping и несколько слоев, чтобы посмотреть, помогло ли это, но, похоже, всегда происходят одни и те же результаты.

model = Sequential()
model.add(Conv2D(32, (3,3), activation = 'relu',
    input_shape = (240, 215, 1)))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3,3), activation = 'relu'))
model.add(Conv2D(64, (3,3), activation = 'relu'))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(128, (3,3), activation = 'relu'))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.25))
model.add(Conv2D(256, (3,3), activation = 'relu'))
model.add(MaxPooling2D((2,2)))
model.add(Dropout(0.25))
 #model.add(Conv2D(256, (3,3), activation = 'relu'))
 #model.add(MaxPooling2D((2,2)))
 #model.add(Conv2D(128, (3,3), activation = 'relu'))
 #model.add(MaxPooling2D((2,2)))
 #model.add(Conv2D(64, (3,3), activation = 'relu'))
 #model.add(MaxPooling2D((2,2)))
model.add(Flatten())
model.add(Dense(150, activation = 'relu'))
 #model.add(Dropout(0.25))
 #model.add(Dense(1000, activation = 'relu'))
model.add(Dropout(0.75))
model.add(Dense(6, activation = 'softmax'))
model.summary()
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy',
        metrics = ['acc'])
callbacks_list = [EarlyStopping(monitor = 'val_loss', patience = 10),
        ModelCheckpoint(filepath = 'model.h6', monitor = 'val_loss',
        save_best_only = True),]

Комментируемые разделы кода - это изменения, которые я пытался реализовать. Я также сильно изменил значения Dropout и их позиции, и ничего существенного не изменилось. Может ли кто-нибудь дать совет, почему моя модель так быстро подходит?

Ответы [ 2 ]

0 голосов
/ 01 февраля 2020

Да, это явный случай переоснащения. Вот мои предложения:

  1. Попробуйте уменьшить количество скрытых слоев
  2. Увеличьте выпадение до 0,5
  3. Создайте больше синтетических c изображений или примените преобразования к необработанным изображения.
0 голосов
/ 31 января 2020

При работе с таким явлением массового переоснащения хорошей отправной точкой будет сокращение количества слоев.

Несмотря на то, что вы добавляете Dropout после многих максимальных пулов, вы все равно страдаете от переобучения Явление.

Ниже я представлю некоторые из моих рекомендаций:

  1. Убедитесь, что у вас есть полный набор данных с чистыми этикетками. Независимо от того, как мы можем настроить нейронную сеть, если набор данных не является чистым, мы не можем получить хорошие результаты.
  2. Добавить (для начала), максимум 3 стека свертки + max_pooling + выпадение. (32 + 64 + 128) будет хорошей отправной точкой.
  3. Используйте GlobalAveragePooling2D вместо Dense слоев. Последние не нужны в сверточной нейронной сети, за исключением последнего слоя с sigmoid или softmax.
  4. Попробуйте использовать SpatialDropout2D. По сравнению с типичным Dropout, который применяется к каждому элементу в карте объектов, SpatialDropout отбрасывает все карты объектов.
  5. Попробуйте использовать Data Augmentation. Таким образом, вы создаете более искусственные примеры, и ваша сеть будет менее склонна к переоснащению.
  6. Если ничего из этого не работает, убедитесь, что вы используете предварительно обученную сеть и применяете трансферное обучение к своей задаче. .
...