¿Cómo implementar la segmentación semántica multiclase?

Soy capaz de entrenar una red U con imágenes etiquetadas que tienen una clasificación binaria.

Pero me resulta difícil descubrir cómo configurar las capas finales en Keras / Theano para la clasificación de varias clases (4 clases).

Tengo 634 imágenes y 634 máscaras correspondientes que son unit8 y 64 x 64 píxeles.

Mis máscaras, en lugar de ser negro (0) y blanco (1), tienen objetos con tags de color en 3 categorías más fondo, de la siguiente manera:

  • negro (0), fondo
  • rojo (1), clase de objeto 1
  • verde (2), clase de objeto 2
  • amarillo (3), clase de objeto 3

Antes de que se ejecute el entrenamiento, la matriz que contiene máscaras se codifica de forma instantánea de la siguiente manera:

 mask_train = to_categorical(mask_train, 4) 

Esto hace que mask_train.shape pase de (634, 1, 64, 64) a (2596864, 4) .

Mi modelo sigue de cerca la architecture de Unet, sin embargo, las capas finales parecen problemáticas, ya que no puedo aplanar la estructura para que coincida con la matriz codificada.

 [...] up3 = concatenate([UpSampling2D(size=(2, 2))(conv7), conv2], axis=1) conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(up3) conv8 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv8) up4 = concatenate([UpSampling2D(size=(2, 2))(conv8), conv1], axis=1) conv9 = Conv2D(64, (3, 3), activation='relu', padding='same')(up4) conv10 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv9) # here I used number classes = number of filters and softmax although # not sure if a dense layer should be here instead conv11 = Conv2D(4, (1, 1), activation='softmax')(conv10) model = Model(inputs=[inputs], outputs=[conv11]) # here categorical cross entropy is being used but may not be correct model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy']) return model 

¿Tiene alguna sugerencia sobre cómo modificar las partes finales del modelo para que se entrene con éxito? Recibo una variedad de errores de desajuste de forma, y ​​las pocas veces que logré hacerlo funcionar, la pérdida no cambió a lo largo de las épocas.

Debería tener su objective como (634,4,64,64) si está usando channels_first.
O (634,64,64,4) si (634,64,64,4) .

Cada canal de su objective debe ser una clase. Cada canal es una imagen de 0 y 1, donde 1 significa que píxel es esa clase y 0 significa que píxel no es esa clase.

Luego, su objective son 634 grupos, cada grupo con cuatro imágenes, cada imagen con 64×64 píxeles, donde los píxeles 1 indican la presencia de la función deseada.

No estoy seguro de que el resultado se ordene correctamente, pero puedes intentarlo:

 mask_train = to_categorical(mask_train, 4) mask_train = mask_train.reshape((634,64,64,4)) #I chose channels last here because to_categorical is outputing your classes last: (2596864,4) #moving the channel: mask_train = np.moveaxis(mask_train,-1,1) 

Si el pedido no funciona correctamente, puede hacerlo manualmente:

 newMask = np.zeros((634,4,64,64)) for samp in range(len(mask_train)): im = mask_train[samp,0] for x in range(len(im)): row = im[x] for y in range(len(row)): y_val = row[y] newMask[samp,y_val,x,y] = 1 

Poco tarde pero deberías intentarlo

 mask_train = to_categorical(mask_train, num_classes=None) 

Eso resultará en (634, 4, 64, 64) para mask_train.shape y una máscara binaria para cada clase individual (codificado de una sola vez).

La última capa de convección, activación y pérdida se ve bien para la segmentación multiclase.