Это модель, которую я использовал. Он берет предварительно обученную модель InceptionV3 и добавляет несколько полностью связанных слоев поверх нее. Все это сделано обучаемым (включая предварительно подготовленные слои InceptionV3).
with tf.device('/cpu:0'):
pretrained_model = InceptionV3(weights='imagenet', include_top=False)
x = pretrained_model.output
x = GlobalAveragePooling2D(name='gap_final')(x)
x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
x = Dropout(0.2)(x)
x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
x = Dropout(0.2)(x)
x = Dense(512, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)
x = Dropout(0.2)(x)
preds = Dense(len(config.classes),activation='softmax')(x)
model = Model(inputs=pretrained_model.input, outputs=preds)
parallel_model = multi_gpu_model(model, gpus=16)
parallel_model.compile(optimizer=Adam(lr=0.0005), loss='categorical_crossentropy', metrics=['accuracy'])
Я пробовал тренировать его с различными конфигурациями увеличения изображения, и независимо от того, что я делаю, результаты всегда похожи на приведенные ниже:
Epoch 1/20
181/181 [====] - 1372s 8s/step - loss: 19.2332 - acc: 0.3330 - val_loss: 8.7765 - val_acc: 0.4747
Epoch 2/20
181/181 [====] - 1379s 8s/step - loss: 4.9885 - acc: 0.5474 - val_loss: 3.5256 - val_acc: 0.4084
Epoch 3/20
181/181 [====] - 1354s 7s/step - loss: 2.0334 - acc: 0.6469 - val_loss: 2.5382 - val_acc: 0.4275
Epoch 4/20
181/181 [====] - 1361s 8s/step - loss: 1.3522 - acc: 0.7117 - val_loss: 2.2028 - val_acc: 0.4741
Epoch 5/20
181/181 [====] - 1356s 7s/step - loss: 1.0838 - acc: 0.7599 - val_loss: 2.3402 - val_acc: 0.4738
С этого момента (эпоха 5/20), если я позволю модельному поезду навсегда, потеря обучения / a cc продолжит улучшаться, в то время как потеря проверки / a cc продолжит оставаться на уровне эти значения.
Это проблема классификации с 28 различными классами, поэтому точность проверки 0,47 не равна , что плохо при заданной случайности даст точность 0,035, однако я не понимаю как обучающий набор может быть идеально подобран, в то время как проверочный набор оставляет желать лучшего.
Полный набор данных состоит из 32 000 довольно хорошо помеченных изображений, все в одной конфигурации (подумайте о проблеме классификации лиц) , Обучение занимает примерно 27 000 и увеличивает их путем горизонтального переворачивания и градации серого (давая в общей сложности 93 000 обучающих изображений), в то время как проверочные изображения не увеличиваются. С визуальной точки зрения обучающие и проверочные изображения выглядят очень похоже, и я не замечаю поразительных различий между этими двумя наборами (очевидно, до увеличения тренировочного набора).
Классы немного несбалансированы, но не так сильно: самые большие класс имеет 2600 изображений, а самое маленькое - 610 (распределение размера класса является линейным между этими двумя крайностями).
Обратите внимание на несколько вещей, которые я пробовал, и не изменяйте результаты:
- отсева: небольшое влияние, если я поиграюсь с коэффициентами отсева
- регуляризация: использование L1 или L2 с разными значениями не сильно изменяет результаты
- нормализация партии: с или без, то же самое
- количество полностью подключенных слоев: один, два или даже три (как указано выше), небольшая разница
- тип предварительно обученной сети: я пытался использовать VGG16 с похожими результатами
Независимо от того, что я делаю, показатели обучения всегда значительно улучшаются, в то время как валидация застаивается.
Это только проблема "получения большего количества данных" с 32 000 изображений, которых просто "недостаточно" для 28 классов, особенно для небольших классов (например, класса, в котором в настоящее время 610 изображений), или я что-то не так делаю? Должен ли я использовать меньшую скорость обучения, хотя используемая в настоящее время уже довольно мала?
Неправильно ли увеличивать изображения из обучающего набора, а не из проверочного набора? Я читал, что это стандартная практика, и, кажется, также имеет смысл это делать ...
Наконец, следует ли ограничивать обучаемые слои? Например, я должен сделать обучаемыми только последние 10 или 20 слоев вместо полной сети InceptionV3? Хотя выбрать обучаемые слои довольно просто при использовании модели VGGxx (будучи чисто последовательной), для Inception она выглядит несколько сложнее. Любая рекомендация по этому поводу будет приветствоваться.