почему функция категориальных кросс-энтропийных потерь в обучении unet-модели для мультиклассовой семантической сегментации очень высока?

Я хочу выполнить семантическую сегментацию для набора данных изображений CMR с использованием модели Unet. Модель отлично работает для других изображений CMR, но при применении ее к новому набору данных ведет себя странно. Я использовал категориальную кросс-энтропию в качестве функции потерь для разделения масок на 4 класса, включая фон. Это модель Unet (я получил ее со страницы github, теперь я не помню адрес), которую я использую:

def down_block(x, filters, kernel_size=(3, 3), padding="same", strides=1):
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(x)
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(c)
    p = keras.layers.MaxPool2D((2, 2), (2, 2))(c)
    return c, p

def up_block(x, skip, filters, kernel_size=(3, 3), padding="same", strides=1):
    us = keras.layers.UpSampling2D((2, 2))(x)
    concat = keras.layers.Concatenate()([us, skip])
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(concat)
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(c)
    return c

def bottleneck(x, filters, kernel_size=(3, 3), padding="same", strides=1):
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(x)
    c = keras.layers.Conv2D(filters, kernel_size, padding=padding, strides=strides, activation="relu")(c)
    return c

def UNet(image_size, nclasses=4, filters=64):
    f = [16, 32, 64, 128, 256]
    inputs = keras.layers.Input((image_size, image_size,1))
    
    p0 = inputs
    c1, p1 = down_block(p0, f[0]) #128 -> 64 ##(do we aim to get 16 feature maps? isn't is by using different masks?)
    c2, p2 = down_block(p1, f[1]) #64 -> 32
    c3, p3 = down_block(p2, f[2]) #32 -> 16
    c4, p4 = down_block(p3, f[3]) #16->8
    
    bn = bottleneck(p4, f[4])
    
    u1 = up_block(bn, c4, f[3]) #8 -> 16
    u2 = up_block(u1, c3, f[2]) #16 -> 32
    u3 = up_block(u2, c2, f[1]) #32 -> 64
    u4 = up_block(u3, c1, f[0]) #64 -> 128
    
    outputs = keras.layers.Conv2D(nclasses, (1, 1), padding="same", activation="softmax")(u4)
    model = keras.models.Model(inputs, outputs)
    return model
image_size = 256
model = UNet(image_size)
optimizer = keras.optimizers.SGD(lr=0.0001, momentum=0.9)
model.compile(optimizer= optimizer, loss='sparse_categorical_crossentropy' , metrics=["accuracy"])

Я также использовал функцию to_categorical над маскирующими изображениями. проблема в том, что предсказанная маска - это пустое изображение, которое, возможно, потому, что оно предсказывает только фоновый класс из-за несбалансированного набора данных. Кроме того, значение потерь начинается с 1,4 и просто уменьшается до 1,3, что показывает, что модель очень мало усвоила. Буду признателен, если кто-нибудь объяснит мне решение, если оно есть ...

P.S. я должен сбалансировать кулак набора данных? если да, то как?


person Mahyar    schedule 11.07.2020    source источник


Ответы (1)


в вашем методе есть две проблемы: сначала вы сказали, что использовали функцию to_categorical, это не способ сделать с разреженными категориальными потерями кроссэнтропии.

Если вы хотите использовать функцию to_categorical для своих данных маски, вам нужно будет использовать Категорическую потерю кроссэнтропии.

Теперь, если вы хотите использовать данные маски RAW с такими метками, как 0,1,2,3, вы можете использовать потерю разреженной категориальной кросс-энтропии, но с From logits = True следующим образом:

model.compile(optimizer= optimizer, 
             loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
             metrics=["accuracy"])

И не используйте softmax в качестве активации на последнем уровне, он вернет вам границы ваших классов (в лучшем случае), а не их семантическую сегментацию (без использования функции активации добьется цели)

person Hicham Messaoudi    schedule 27.07.2020
comment
Спасибо за ваш ответ. да, вы правы, я ошибся насчет функции потерь, но проблема все еще существует и с категориальной кросс-энтропией. Я думаю, это потому, что машина не обучается через набор данных определенной моделью. Итак, я изменил архитектуру модели и проблема решена. - person Mahyar; 27.07.2020