почему категориальная функция перекрестных потерь энтропии в обучающей модели unet для мультиклассовой семанти c сегментации очень высока? - PullRequest
0 голосов
/ 11 июля 2020

Я хочу выполнить семантическую c сегментацию для набора данных изображений 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, что показывает, что модель очень мало усвоила. Я был бы признателен, если бы кто-нибудь объяснил мне решение, если оно есть ...

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

Ответы [ 2 ]

1 голос
/ 27 июля 2020

в вашем методе есть две проблемы: сначала вы сказали, что использовали «функцию 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 в качестве активации на последнем слое, он вернет вам «края» ваших классов (в лучшем случае) а не их семанти c сегментация (без использования функции активации добьется цели)

0 голосов
/ 27 июля 2020

Приятно это слышать, я дам вам подсказку, возможно, сначала можно улучшить производительность вашей модели, используя функцию «to_categorical» для ваших масок:

mask_data =tf.round(mask_data) # helps getting integer values 
mask_data = tf.keras.utils.to_categorical(mask_data)  # one-hot encoding 

А затем для вашего последнего слоя (в вашей модели):

outputs = tfa.layers.Sparsemax(-1)(last_layer) # check tensorflow addons

Не забываем:

import tensorflow_addons as tfa

А потом:

model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer= optimizer, loss = tfa.losses.SparsemaxLoss(from_logits=True), 
          metrics=tf.keras.metrics.MeanIoU(4))

Не забываем убрать активацию "softmax" в последний слой.

Я надеюсь, что это поможет вам получить лучшие результаты, и если вы обнаружите, что обучение идет не так хорошо, попробуйте увеличить количество фильтров в каждом слое!

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