Keras模型的验证损失与损失函数输出不匹配

时间:2020-06-17 10:00:44

标签: python keras deep-learning image-segmentation

我正在从事生物医学图像分割项目。我正在为工作使用U-net模型。问题是,当我训练模型时,验证损失似乎不切实际。

我将 dice_coef_loss 用作损失函数,以及 metric 中的损失函数。培训的结果如下图所示。该图清楚地表明验证损失未遵循我的损失函数,因为这两个图是可区分的。但是,火车损失确实遵循火车dice_coef_loss值。

(左侧的第一张图片是训练和验证损失,第三张是测色和验证 dice_coef_loss 作为度量标准)

The history graph of training

(对不起,我还没有资格嵌入图片,请检查链接)

这是我的模特

def unet(input_size=(256,256,1)):
    inputs = Input(input_size)

    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(inputs)
    conv1 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv1)
    pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(pool1)
    conv2 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv2)
    pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)

    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(pool2)
    conv3 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv3)
    pool3 = MaxPooling2D(pool_size=(2, 2))(conv3)

    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(pool3)
    conv4 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv4)
    pool4 = MaxPooling2D(pool_size=(2, 2))(conv4)

    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(pool4)
    conv5 = Conv2D(512, (3, 3), activation='relu', padding='same')(conv5)

    up6 = concatenate([Conv2DTranspose(256, (2, 2), strides=(2, 2), padding='same')(conv5), conv4], axis=3)
    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(up6)
    conv6 = Conv2D(256, (3, 3), activation='relu', padding='same')(conv6)

    up7 = concatenate([Conv2DTranspose(128, (2, 2), strides=(2, 2), padding='same')(conv6), conv3], axis=3)
    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(up7)
    conv7 = Conv2D(128, (3, 3), activation='relu', padding='same')(conv7)

    up8 = concatenate([Conv2DTranspose(64, (2, 2), strides=(2, 2), padding='same')(conv7), conv2], axis=3)
    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(up8)
    conv8 = Conv2D(64, (3, 3), activation='relu', padding='same')(conv8)

    up9 = concatenate([Conv2DTranspose(32, (2, 2), strides=(2, 2), padding='same')(conv8), conv1], axis=3)
    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(up9)
    conv9 = Conv2D(32, (3, 3), activation='relu', padding='same')(conv9)

    conv10 = Conv2D(1, (1, 1), activation='sigmoid')(conv9)

    return Model(inputs=[inputs], outputs=[conv10])

这是损失函数

import keras.backend as K
smooth=100

def dice_coef(y_true, y_pred):
    y_truef=K.flatten(y_true)
    y_predf=K.flatten(y_pred)
    And=K.sum(y_truef* y_predf)
    return((2* And + smooth) / (K.sum(y_truef) + K.sum(y_predf) + smooth))

def dice_coef_loss(y_true, y_pred):
    return -dice_coef(y_true, y_pred)

编译

model.compile(optimizer=Adam(lr=1e-5), loss=dice_coef_loss, metrics=["binary_accuracy", dice_coef_loss, iou])

注意

我尝试过:

  • 学习率调整
  • 调整批次大小
  • 数据扩充
  • 更改损失函数

如果有人想看这里的代码,那就是link to kaggle kernel

添加说明

为了使自己更清楚:

第一张和第二张图是使用相同的数据集(从火车或验证时间)通过相同的函数生成的,因此我希望第一张图的train_loss曲线等于第三张图的train_dice_coef_loss。第1个图的val_loss曲线等于第3个图的val_dice_coef_loss。

但是不幸的是,val_loss曲线与val_dice_coef_loss曲线不匹配。

P.S。我是新来的。任何建议,以改善我的问题表示赞赏。谢谢。

1 个答案:

答案 0 :(得分:0)

因为, ZabirAlNazi 表示这是所用库的问题。将导入从keras更改为tensorflow.keras解决了该问题。

from tensorflow.keras.models import Model, load_model, save_model
from tensorflow.keras.layers import Input, Activation, BatchNormalization, Dropout, Lambda, Dense, Conv2D