簡體   English   中英

為什么多類語義分割訓練中的分類交叉熵損失 function model 非常高?

[英]why categorical cross entropy loss function in training unet model for multiclass semantic segmentation is very high?

我想使用 Unet model 對 CMR 圖像數據集進行語義分割。 model 非常適用於其他 CMR 圖像,但將其應用於新數據集時,它的行為很奇怪。 我使用分類交叉熵作為損失 function 將掩碼分割成 4 個類別,包括背景。 這是 Unet model (我從 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 function 覆蓋掩碼圖像。 問題是預測的掩碼是一個空白圖像,這可能是因為由於數據集不平衡,它只預測了背景 class。 此外,損失值從 1.4 左右開始下降到 1.3,這表明 model 學到的東西很少。 如果有人向我解釋解決方案(如果有的話),我將不勝感激......

PS我應該平衡數據集拳頭嗎? 如果是的話怎么辦?

你的方法有兩個問題,首先你說你使用了“to_categorical 函數”,這不是處理“稀疏分類交叉熵損失”的方法。

如果您想在掩碼數據上使用“to_categorical”function,則必須使用“CategoricalCrossEntropy”損失。

現在,如果您想使用帶有“0,1,2,3”之類的標簽的 RAW 掩碼數據,您可以使用“Sparse Categorical CrossEntropy loss”,但可以使用“From logits = True”:

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

並且不要在最后一層使用 softmax 作為激活,它會返回你的類的“邊緣”(在最好的情況下)而不是它們的語義分割(不使用激活 function 就可以了)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM