Keras 模型的验证损失与损失函数输出不匹配
Keras model's validation loss doesn't match the loss function output
我正在从事生物医学图像分割项目。我正在使用 U-net 模型来完成这项工作。问题是,当我训练模型时,验证损失似乎并不实用。
我使用 dice_coef_loss 作为损失函数,以及 指标 。训练结果如下图。该图清楚地表明验证损失不遵循我的损失函数,因为这两个图是可区分的。但是,train loss 确实遵循 train dice_coef_loss 值。
(左起第一个图像是训练和验证损失,第三个是tarining和验证dice_coef_loss作为度量)
The history graph of training
(抱歉,我还没有资格嵌入图片,请检查 link)
这是我的模型
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 来自第三个情节。第一个图的 val_loss 曲线等于第三个图的 val_dice_coef_loss。
但不幸的是 val_loss 曲线与 val_dice_coef_loss 曲线不匹配。
P.S。我刚来这地方。感谢任何改进我的问题的建议。谢谢。
因为,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
我正在从事生物医学图像分割项目。我正在使用 U-net 模型来完成这项工作。问题是,当我训练模型时,验证损失似乎并不实用。
我使用 dice_coef_loss 作为损失函数,以及 指标 。训练结果如下图。该图清楚地表明验证损失不遵循我的损失函数,因为这两个图是可区分的。但是,train loss 确实遵循 train dice_coef_loss 值。
(左起第一个图像是训练和验证损失,第三个是tarining和验证dice_coef_loss作为度量)
The history graph of training
(抱歉,我还没有资格嵌入图片,请检查 link)
这是我的模型
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 来自第三个情节。第一个图的 val_loss 曲线等于第三个图的 val_dice_coef_loss。
但不幸的是 val_loss 曲线与 val_dice_coef_loss 曲线不匹配。
P.S。我刚来这地方。感谢任何改进我的问题的建议。谢谢。
因为,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