Transfer Learning - Val_loss странное поведение
Я пытаюсь использовать обучение переносу на MobileNetV2 из keras.application в фитоне. Мои изображения принадлежат 4 классам с количеством 8000, 7000, 8000 и 8000 изображений в первом, втором, третьем и последнем классе. Мои изображения серого цвета и имеют размеры от 1024x1024 до 128x128.
Я удалил плотные слои классификации из MobileNetV2 и добавил свои собственные плотные слои:
global_average_pooling2d_1 (Glo Shape = (None, 1280) 0 Parameters
______________________________________________________________________________
dense_1 (Dense) Shape=(None, 4) 5124 Parameters
______________________________________________________________________________
dropout_1 (Dropout) Shape=(None, 4) 0 Parameters
________________________________________________________________
dense_2 (Dense) Shape=(None, 4) 20 Parameters
__________________________________________________________________________
dense_3 (Dense) Shape=(None, 4) 20 Parameters
Total params: 2,263,148
Trainable params: 5,164
Non-trainable params: 2,257,984
Как видите, я добавил 2 плотных слоя с выпадением в качестве регуляризатора. Furhtermore, я использовал следующее
opt = optimizers.SGD(lr=0.001, decay=4e-5, momentum=0.9)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
batch_size = 32
Мои результаты на тренировках очень странные...:
эпоха
1 потеря: 1,3378 - в соответствии с 0,3028; потеря в валу: 1,4629; потеря в валу: 0,2702
2 потери: 1,2807 - в соответствии с: 0,3351 - потери по величине: 1,3297 - значения по шкале: 0,3208
3 потери: 1,2641 - в соответствии с: 0,3486 - потери по величине: 1,4428 - значения по шкале: 0,3707
4 потери: 1,2178 - в соотв. 0,3916 - потери в долях: 1,4231 - валы: 0,3758
5 потерь: 1,2100 - в соответствии с: 0,3909 - потери по величине: 1,4009 - значения по величине: 0,3625
6 потерь: 1,1979 - в соответствии: 0,3976 - потери по стоимости: 1,5025 - значения по счету: 0,3116
7 проигрыша: 1,1943 - согласно: 0,3988 - val_loss: 1,4510 - val_acc: 0,2872
8 потери: 1,1926 - в соответствии с: 0,3965 - потери по стоимости: 1,5162 - значения по счету: 0,3072
9 потерь: 1,1888 - в соответствии с 0,4004 - потери по величине: 1,5659 - значения по счету: 0,3304
10 потерь: 1,1906 - в соответствии с: 0,3969 - потеря по величине: 1,5655 - допустимая ошибка: 0,3260
11 потерь: 1,1864 - в соответствии с: 0,3999 - потери по величине: 1,6286 - значения по счету: 0,2967
(...)
Подводя итог, потеря тренировок больше не уменьшается и все еще очень высока. Модель также подходит. Вы можете спросить, почему я добавил только 2 плотных слоя с 4 нейронами в каждом. В начале я пробовал разные конфигурации (например, 128 нейронов и 64 нейрона, а также разные регуляторы), затем переоснащение было огромной проблемой, то есть точность обучения была почти 1, а потери на тесте были еще далеки от 0.
Я немного запутался в происходящем, потому что здесь что-то невероятно не так.
Попытки тонкой настройки: различное количество нейронов в плотных слоях в части классификации, варьирующееся от 1024 до 4. Различные скорости обучения (0, 01, 0, 001, 0, 0001) Различные размеры партий (16,32, 64) Различные регуляторы L1 с 0, 001, 0, 0001
Результаты: всегда огромное переоснащение
base_model = MobileNetV2(input_shape=(128, 128, 3), weights='imagenet', include_top=False)
# define classificator
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(4, activation='relu')(x)
x = Dropout(0.8)(x)
x = Dense(4, activation='relu')(x)
preds = Dense(4, activation='softmax')(x) #final layer with softmax activation
model = Model(inputs=base_model.input, outputs=preds)
for layer in model.layers[:-4]:
layer.trainable = False
opt = optimizers.SGD(lr=0.001, decay=4e-5, momentum=0.9)
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
batch_size = 32
EPOCHS = int(trainY.size/batch_size)
H = model.fit(trainX, trainY, validation_data=(testX, testY), epochs=EPOCHS, batch_size=batch_size)
Результатом должно быть то, что нет переобучения и val_loss близко к 0. Я знаю, что из какой-то статьи, работающей над подобными наборами изображений.
ОБНОВЛЕНИЕ: Вот некоторые изображения val_loss, train_loss и точности: 2 плотных слоя с 16 и 8 нейронами, lr = 0, 001 с распадом 1e-6, размер пакета = 25
2 ответа
Это может быть результатом того, что у вас слишком высокий процент отсева. Вы не показываете свои генераторы данных, поэтому я не могу сказать, есть ли там проблема, но я подозреваю, что вам нужно скомпилировать, используя
loss='sparse_categorical_crossentropy'
Здесь вы использовалиx = Dropout(0.8)(x)
что означает падение на 80%, но я предполагаю, что вам нужно 20%, поэтому замените его на x = Dropout(0.2)(x)
Кроме того, при необходимости обратитесь к документации по этому продукту.
выписка из вышеуказанной документации
keras.layers.Dropout(rate, noise_shape=None, seed=None)
скорость: плавать между 0 и 1. Доля входных единиц, чтобы упасть.
Я не уверен, что ошибка была сверху, но я знаю, как это исправить. Я полностью обучил предварительно обученную сеть (а также один плотный слой с 4 нейронами и softmax). Результаты более чем удовлетворительные. Я также тестировал на VGG16, где я тренировал только плотный выходной слой, и он полностью работал.
Похоже, что MobileNetV2 изучает функции, которые нежелательны для моего набора данных. Мои наборы данных представляют собой радиолокационные изображения, которые выглядят очень искусственно (распределение сигналов LPI). С другой стороны, эти изображения очень просты (в основном они представляют собой просто грани в изображении в оттенках серого), поэтому мне до сих пор неизвестно, почему обучение переносу на основе моделей не работает для MobileNetV2).