Потеря функции распознавания при замене встроенного датчика с предварительно встроенным датчиком - PullRequest
0 голосов
/ 27 марта 2020

Я хочу обучить сегментации семанти c для набора данных A2D2 . Я построил себе фреймворк для разработки и тестирования различных модельных архитектур. Проблема, с которой я сталкиваюсь, как только я пытаюсь реализовать встроенный кодировщик (например, Keras ResNet50V2), заключается в том, что качество сегментации страдает. В конце обучения модель часто предсказывает сгустки классов с почти постоянной формой для каждого входного изображения.

Я уменьшил количество изображений с 40К до 1К для целей тестирования. Я пытался тренироваться с изображениями 10 тыс., Но это не улучшило качество прогноза. В своих испытаниях я также пытался уменьшить количество классов до 38 и 14, что также не улучшило качество.

У кого-нибудь есть идеи, в чем проблема? Подробнее см. Ниже.

Настройки, которые я использовал для создания модели:

  • input_shape: (720, 1280, 3)
  • kernel_size: (3, 3)
  • пул: макс.
  • пул_размер: (2, 2)
  • заполнение: те же
  • шаги: (1, 1)
  • активация : relu
  • bn_axis: 3

Настройки, которые я использовал для обучения:

  • Эпохи: 20
  • Размер партии: 3
  • Оптимизатор:
Adam(learning_rate=0.01, beta_1=0.9, beta_2=0.999, amsgrad=False)
  • Расписание обучения:
def lr_schedule(epoch):
    learning_rate = 0.01
    if epoch > 10:
        learning_rate = 0.001
    if epoch > 15:
        learning_rate = 0.0001

    return learning_rate

lr_scheduler = LearningRateScheduler(lr_schedule)
  • Предварительная обработка для изображений:
def preprocess_input(self, x):
    return x / 255.
  • Предварительная обработка для этикеток
label = to_categorical(label, num_classes=num_classes)

Сравнение результатов

Метка истинности заземления против прогноза

Собственная сборка модель ( FCN_3D_2U_BN_Adam_RLS ) enter image description here

Хотя в некоторых случаях присвоение класса является правильным, модель распознает такие признаки, как дорожный знак на правая сторона.

Готовая модель ( ResNe t50_2U_BN_Adam_RLS ) enter image description here

Здесь вы уже можете увидеть потерю распознанных функций. Ниже приведены более экстремальные случаи.

Модель: "FCN_3D_2U_BN_Adam_RLS"

Код

input_node = Input(shape=self.input_shape)

# Conv Block 1
x = mutils.Conv2dBn(filters=32, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(input_node)
x = mutils.Conv2dBn(filters=32, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(x)
x = MaxPooling2D(pool_size=self.pool_size, padding=self.padding)(x)

# Conv Block 2
x = mutils.Conv2dBn(filters=64, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(x)
x = mutils.Conv2dBn(filters=64, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(x)
x = MaxPooling2D(pool_size=self.pool_size, padding=self.padding)(x)

# Conv Block 3
x = mutils.Conv2dBn(filters=256, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(x)
x = mutils.Conv2dBn(filters=256, kernel_size=self.kernel_size, strides=self.strides, padding=self.padding,
                    activation=self.activation, use_batchnorm=True)(x)
x = MaxPooling2D(pool_size=self.pool_size, padding=self.padding)(x)

# Upsample
x = Conv2DTranspose(filters=128, kernel_size=(4, 4), strides=(2, 2), padding='same', activation=None)(x)
x = BatchNormalization(axis=self.bn_axis)(x)
x = Activation(activation=self.activation)(x)

# Upsampling to image shape
x = Conv2DTranspose(self.num_classes, kernel_size=(8, 8), strides=(4, 4), padding='same', activation=None)(x)
x = BatchNormalization(axis=self.bn_axis)(x)
output_node = Activation('softmax')(x)

# Create model
model = Model(input_node, output_node, name=self.model_name)

Слой Conv2dBn скопирован из qubvel / segmentation_models .

Метри c Результаты

  • Точность: 0,53
  • Категориальная_кросентропия: 1,87

Результаты COCO

|           |   Mean IOU |   FW IOU |   Mean accuracy |   Pixel accuracy |
|:----------|-----------:|---------:|----------------:|-----------------:|
| leaves    |     0.0451 |   0.4278 |          0.0668 |           0.6181 |

Модель: "ResNet50_2U_BN_Adam_RLS"

Код

input_node = Input(shape=self.input_shape)

encoder_resnet = ResNet50V2(include_top=False, weights=None, input_tensor=input_node, pooling=self.pooling,
                            classes=self.num_classes)

encoder_output = encoder_resnet.get_layer('conv4_block6_1_relu').output

# Upsample
x = Conv2DTranspose(filters=128, kernel_size=(8, 8), strides=(4, 4), padding='same', activation=None)(
    encoder_output)
x = BatchNormalization(axis=self.bn_axis)(x)
x = Activation(activation=self.activation)(x)

# Upsampling to image shape
x = Conv2DTranspose(self.num_classes, kernel_size=(8, 8), strides=(4, 4), padding='same', activation=None)(x)
x = BatchNormalization(axis=self.bn_axis)(x)
output_node = Activation('softmax')(x)

# Create model
model = Model(input_node, output_node, name=self.model_name)

Единственное изменение в части декодера - увеличение шагов от (2 , 2) - (4, 4) для первого слоя Conv2DTranspose, чтобы получить правильную выходную форму.

Метри c Результаты

  • Точность: 0,50
  • Категориальная_кросентропия: 1,81

Результаты COCO

|           |   Mean IOU |   FW IOU |   Mean accuracy |   Pixel accuracy |
|:----------|-----------:|---------:|----------------:|-----------------:|
| leaves    |     0.0444 |   0.4204 |          0.0669 |           0.6165 |

Приложение

Несколько более экстремальных случаев с BLOB-объектами

Я тренировался со многими различными сетями и настройками декодера. Одним из них был PS PNet из segmentation_models с Adam, ReduceLROnPlateau, функцией взвешенных потерь, предварительно обученными весами и замороженным кодером для 20% эпох.

enter image description here enter image description here enter image description here

Для большего набора данных и большего количества эпох ResNet50_2U_BN_Adam_RLS будет в конечном итоге достичь тех же пятен, что и выше. Однако для этой модели у меня нет такого прекрасно сопоставимого примера. Тем не менее, я думаю, что капли сегментации модели Re sNet уже видны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...