Тонкая настройка Resnet Кераса либо недостаточная, либо избыточная: как я могу сбалансировать тренировку?

Я настраиваю Resnet Кераса, предварительно обученный на данных изображения в сети, для работы над определенной классификацией с другим набором данных изображений. Моя модель структурирована следующим образом: Resnet принимает входные данные, а поверх Resnet я добавил свой собственный классификатор. Во время всех экспериментов, которые я пробовал, модель либо переоснащалась, либо переоснащалась.

В основном я пробовал два подхода:

  • заблокировать определенное количество n слоев по направлению к входу, чтобы они не обновлялись во время обучения. В частности, Resnet имеет 175 слоев, и я пробовал с n = 0, 10, 30, 50, 80, 175. Во всех этих случаях модель не соответствует требованиям, получая точность по обучающему набору не более 0,75, и на проверка не более 0,51.

  • заблокировать все уровни пакетной нормализации, а также несколько n слоев в начале (как и раньше), с n = 0, 10, 30, 50. В этих случаях модель перекрывается, получая более 0,95 точности на обучающем наборе, но около 0,5 на валидации.

Обратите внимание, что при переходе с Resnet на InceptionV3 и блокировке 50 уровней я получаю более 0,95 точности как для проверочных, так и для тестовых наборов.

Вот основная часть моего кода:

inc_model = ResNet50(weights='imagenet',
                        include_top=False,
                        input_shape=(IMG_HEIGHT, IMG_WIDTH, 3))

print("number of layers:", len(inc_model.layers)) #175
#Adding custom Layers
x = inc_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation="relu")(x)
x = Dropout(0.5)(x)
x = Dense(512, activation="relu")(x)
predictions = Dense(2, activation="softmax")(x)

model_ = Model(inputs=inc_model.input, outputs=predictions)

# fine tuning 1
for layer in inc_model.layers[:30]:
        layer.trainable = False
# fine tuning 2
for layer in inc_model.layers:
    if 'bn' in layer.name:
        layer.trainable = False

# compile the model
model_.compile(optimizer=SGD(lr=0.0001, momentum=0.9)
                    , loss='categorical_crossentropy'
                    , metrics=['accuracy'])

checkpointer = ModelCheckpoint(filepath='weights.best.inc.male.resnet.hdf5', 
                               verbose=1, save_best_only=True)

hist = model_.fit_generator(train_generator
                     , validation_data = (x_valid, y_valid)
                      , steps_per_epoch= TRAINING_SAMPLES/BATCH_SIZE
                      , epochs= NUM_EPOCHS
                      , callbacks=[checkpointer]
                      , verbose=1
                    )

Может ли кто-нибудь подсказать, как найти стабильное решение, которое чему-то учится, но не переоснащается?

РЕДАКТИРОВАТЬ: результат этапа обучения выглядит примерно так:

Epoch 1/20
625/625 [==============================] - 2473s 4s/step - loss: 0.6048 - acc: 0.6691 - val_loss: 8.0590 - val_acc: 0.5000

Epoch 00001: val_loss improved from inf to 8.05905, saving model to weights.best.inc.male.resnet.hdf5
Epoch 2/20
625/625 [==============================] - 2432s 4s/step - loss: 0.4445 - acc: 0.7923 - val_loss: 8.0590 - val_acc: 0.5000

Epoch 00002: val_loss did not improve from 8.05905
Epoch 3/20
625/625 [==============================] - 2443s 4s/step - loss: 0.3730 - acc: 0.8407 - val_loss: 8.0590 - val_acc: 0.5000

Epoch 00003: val_loss did not improve from 8.05905

и так далее .. Каждый раз, когда проверка не улучшается


person Nicolò Pomini    schedule 17.04.2019    source источник


Ответы (1)


У вас есть много вариантов, но вы все же попробовали преждевременно остановиться? или можете попробовать сделать что-нибудь увеличение данных или протестируйте с более простой моделью.

person Wanderer    schedule 17.04.2019
comment
Я попытался преждевременно остановиться, но не улучшилось. Проблема в том, что эффективна только первая эпоха обучения, потому что после нее оценки валидации никогда не улучшаются. Я уже занимался увеличением данных. Какую более простую модель вы можете мне предложить? - person Nicolò Pomini; 28.04.2019
comment
@ NicolòPomini для начала, не могли бы вы опубликовать здесь свой результат? тогда вы пытались изменить скорость обучения или оптимизатор? хотя это не гарантируется, но попробуйте VGG16 или VGG19. - person Wanderer; 30.04.2019
comment
Я добавил результат фазы обучения в вопрос. До сих пор я пробовал с SGD, Adagrad и Adadelta - person Nicolò Pomini; 01.05.2019
comment
Хорошо, теперь я вижу, что ваши потери в обучении продолжают уменьшаться, в то время как ваши потери при проверке не меняются (тогда это означает, что сеть может переоснащаться). Вы можете попробовать увеличить коэффициент отсева до 0,7 или заблокировать / удалить некоторые слои (будьте осторожны с этим). Также кажется, что использование другой предварительно обученной сети решает проблему, не так ли? - person Wanderer; 02.05.2019
comment
Как ни странно, я получаю лучшие результаты, установив коэффициент отсева на 0,3 и заморозив первые 80 слоев, а также все слои пакетной нормализации: с этой настройкой конечная точность достигает 0,56, что все еще очень плохо. Да, с InceptionV3 модель работает отлично - person Nicolò Pomini; 05.05.2019