и я не знаю, как добавить плотный слой для прогнозирования в сети.
аюсь реализовать U-Net с Keras с бэкэндом Tensorflow для задачи сегментации изображения. У меня есть изображения размером (128,96) в качестве входных данных для сети вместе с изображениями маски размера (12288,6), так как они сплющены. У меня есть 6 различных классов (0-5), которые дают вторую часть формы изображений маски. Они были закодированы в метки быстрого доступа с помощью функции to_categorical (). На данный момент я использую только одно входное изображение, а также то же самое, что и данные проверки и проверки.
Я хотел бы, чтобы U-Net выполнял сегментацию изображения, где класс 0 соответствует фону. Когда я сейчас тренирую свою сеть U-Net только в течение нескольких эпох (1–10), результирующее предсказанное изображение маски, кажется, просто дает случайные классы каждому пикселю. Когда я тренирую сеть дольше (более 50 эпох), все пиксели классифицируются как фон. Так как я тренируюсь и тестирую с использованием одного и того же изображения, я нахожу это очень странным, поскольку я ускорял работу сети. Как я могу решить эту проблему? Может ли быть что-то не так с тем, как я передаю в сеть изображения маски и реальные изображения?
Я пытался придать веса сети вручную, чтобы меньше внимания уделять фону, чем другие классы, и пробовал разные комбинации потерь, разные способы формирования изображения маски и многое другое, но ничего не дало хороших результатов.
Ниже приведен код моей сети. Он основан на U-Net, взятом изэтот репозиторий, Мне удалось подготовить его для случая с двумя классами с хорошими результатами, но я не знаю, как расширить его на большее количество классов сейчас.
def get_unet(self):
inputs = Input((128, 96,1))
#Input shape=(?,128,96,1)
conv1 = Conv2D(64, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal', input_shape=(None,128,96,6))(inputs)
#Conv1 shape=(?,128,96,64)
conv1 = Conv2D(64, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv1)
#Conv1 shape=(?,128,96,64)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
#pool1 shape=(?,64,48,64)
conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(pool1)
#Conv2 shape=(?,64,48,128)
conv2 = Conv2D(128, 3, activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv2)
#Conv2 shape=(?,64,48,128)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
#Pool2 shape=(?,32,24,128)
conv5 = Conv2D(256, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(pool2)
conv5 = Conv2D(256, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv5)
up8 = Conv2D(128, 2, activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv5))
merge8 = concatenate([conv2,up8], axis = 3)
conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(merge8)
conv8 = Conv2D(128, 3, activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv8)
up9 = Conv2D(64, (2,2), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(UpSampling2D(size = (2,2))(conv8))
merge9 = concatenate([conv1,up9], axis = 3)
conv9 = Conv2D(64, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(merge9)
conv9 = Conv2D(64, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv9)
conv9 = Conv2D(6, (3,3), activation = 'relu', padding = 'same',
kernel_initializer = 'he_normal')(conv9)
conv10 = Conv2D(6, (1,1), activation = 'sigmoid')(conv9)
conv10 = Reshape((128*96,6))(conv10)
model = Model(input = inputs, output = conv10)
model.compile(optimizer = Adam(lr = 1e-5), loss = 'binary_crossentropy',
metrics = ['accuracy'])
return model
Кто-нибудь может указать, что не так с моей моделью?