CNN предсказывает один и тот же класс для всех входных данных

1

Я пытаюсь воссоздать CNN в Keras для классификации данных облака точек. CNN описывается в этой статье.

Сетевой дизайн Изображение 174551

Это моя текущая реализация:

inputs = Input(shape=(None, 3))

x = Conv1D(filters=64, kernel_size=1, activation='relu')(inputs)
x = BatchNormalization()(x)
x = Conv1D(filters=64, kernel_size=1, activation='relu')(x)
x = BatchNormalization()(x)

y = Conv1D(filters=64, kernel_size=1, activation='relu')(x)
y = BatchNormalization()(y)
y = Conv1D(filters=128, kernel_size=1, activation='relu')(y)
y = BatchNormalization()(y)
y = Conv1D(filters=2048, kernel_size=1, activation='relu')(y)
y = MaxPooling1D(1)(y)

z = keras.layers.concatenate([x, y], axis=2)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Conv1D(filters=512, kernel_size=1, activation='relu')(z)
z = BatchNormalization()(z)
z = Dense(9, activation='softmax')(z)

model = Model(inputs=inputs, outputs=z)

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

Проблема в том, что сеть прогнозирует один и тот же класс для всех входных данных. Это может быть вызвано ошибкой в моей реализации сети, переполнением или недостаточной подготовкой данных. Может кто-то заметить ошибку в моей реализации?

  • 0
    Может быть, все веса инициализируются нулями?
Теги:
tensorflow
keras
conv-neural-network
neural-network

3 ответа

1
Лучший ответ

Тот же класс вывода обычно указывает на только что инициализированную сеть, что означает, что учебные веса не загружаются. Произошло ли это во время обучения такое же дело? Однако другая причина может быть плохой предварительной обработкой. Еще одна вещь, которую я заметил, заключается в том, что в документе говорится "1D-полностью сверточная сеть". Ваш плотный слой является сверточным в статье.

  • 0
    Последний слой действительно должен быть сверточным слоем. Спасибо!
1

Сеть фиксирована, так как она дает ожидаемые прогнозы. Спасибо за помощь!

Основываясь на ответах, я изменил следующие вещи:

  • Порядок активации и нормализация партии.
  • Последний слой от плотного до сверточного слоя.

Я также добавил параметр training=True для уровня нормализации партии

Код правильной реализации:

inputs = Input(shape=(None, 3))

x = Conv1D(filters=64, kernel_size=1, input_shape=(None, 4))(inputs)
x = BatchNormalization()(x, training=True)
x = Activation('relu')(x)
x = Conv1D(filters=64, kernel_size=1, use_bias=False)(x)
x = BatchNormalization()(x, training=True)
x = Activation('relu')(x)

y = Conv1D(filters=64, kernel_size=1)(x)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = Conv1D(filters=128, kernel_size=1)(y)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = Conv1D(filters=2048, kernel_size=1)(y)
y = BatchNormalization()(y, training=True)
y = Activation('relu')(y)
y = MaxPooling1D(1)(y)

z = keras.layers.concatenate([x, y], axis=2)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=512, kernel_size=1)(z)
z = BatchNormalization()(z, training=True)
z = Activation('relu')(z)
z = Conv1D(filters=2, kernel_size=1, activation='softmax')(z)

model = Model(inputs=inputs, outputs=z)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
1

Я считаю, что ошибка не в реализации. Скорее всего, проблема в том, что у вас недостаточно данных. Кроме того, если сеть прогнозирует один и тот же класс для всех входных данных, это обычно означает, что вам не хватает регуляризации. Попробуйте добавить несколько слоев Dropout с отсечением от 0.2 до 0.5 и посмотреть, улучшились ли результаты.

Кроме того, я не думаю, что

x = Conv1D(filters=64, kernel_size=1, activation='relu')(inputs)
x = BatchNormalization()(x)

такой же как

x = Conv1D(filters=64, kernel_size=1)(inputs)
x = BatchNormalization()(x)
x = ReLU(x)

и я думаю, что вам нужен последний.

Еще одна вещь для вас - LeakyReLU, поскольку она обычно дает лучшие результаты, чем обычный ReLU.

  • 0
    Правильный порядок действительно CONV - BN - ReLU, я изменяю свой код на основе вашего примера. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню