python - 准确度表现良好,但图像分割中的 Dice 损失较差

标签 python tensorflow deep-learning conv-neural-network tf.keras

我正在使用类似 U-Net 的架构在 Tensorflow w/Keras 上进行图像分割,但我是深度学习领域的新手。
我得到了具有以下设置形状的数据集:

  • 火车:X:(175250, 30, 30, 6) Y:(175250, 30, 30)
  • 验证:X:(29200, 30, 30, 6) Y:(29200, 30, 30)
  • 测试:X:(29200, 30, 30, 6) Y:(29200, 30, 30)

下面有这些图像和每个 channel 的一些示例。

--> 每组中均等地包含 20% 的正例和 80% 的负例

我运行了一些系列,但为了获得最佳的过滤器组合 BCE 的绘图具有良好的准确性: enter image description here

自定义函数 Dice_Loss by Dice_Coeff 的绘图:

enter image description here

以及从使用测试图像训练的最佳模型生成的一些图像:

enter image description here

问题是,当我更改为骰子损失和系数时,没有像我们在图像图中看到的那样好的预测,而且现在它不在我们可能看到的图像预测中。 enter image description here

为什么它在骰子损失方面表现如此糟糕?您还推荐哪些其他功能?

我的骰子损失和系数函数:

def dice_coeff(y_true, y_pred, smooth=1):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    return (2. * intersection + smooth) / (K.sum(K.square(y_true),-1) + K.sum(K.square(y_pred),-1) + smooth)


def dice_loss(y_true, y_pred):
    return 1-dice_coeff(y_true, y_pred)

最佳答案

您尝试过使用软骰子吗?
计算机视觉领域的最新工作提出了软代理来减轻差异并通过松弛(soft-Dice、soft-Jaccard)直接优化所需的指标。

还有其他流行的图像分割损失函数:

图像分割任务中最常用的损失函数是像素级交叉熵损失。 这种损失单独检查每个像素,将类预测(深度像素向量)与我们的 one-hot 编码目标向量进行比较。

用于图像分割任务的另一个流行的损失函数是基于Dice系数(您已经尝试过),它本质上是两个样本之间重叠的度量。此度量范围从 0 到 1,其中 Dice 系数为 1 表示完美且完全重叠。

如果您想知道,计算 Dice 系数时分子中有一个 2,因为我们的分母“双重计算”了两个集合之间的公共(public)元素。为了制定一个可以最小化的损失函数,我们将简单地使用 1−Dice。

这个损失函数被称为软骰子损失,因为我们直接使用预测概率,而不是进行阈值并将其转换为二进制掩码。

分别计算每个类别的软骰子损失,然后进行平均以得出最终分数。下面提供了一个示例实现。

def soft_dice_loss(y_true, y_pred, epsilon=1e-6): 
    """Soft dice loss calculation for arbitrary batch size, number of classes, and number of spatial dimensions.
    Assumes the `channels_last` format.
  
    # Arguments
        y_true: b x X x Y( x Z...) x c One hot encoding of ground truth
        y_pred: b x X x Y( x Z...) x c Network output, must sum to 1 over c channel (such as after softmax) 
        epsilon: Used for numerical stability to avoid divide by zero errors
    """
   
    # skip the batch and class axis for calculating Dice score
    axes = tuple(range(1, len(y_pred.shape)-1)) 
    numerator = 2. * np.sum(y_pred * y_true, axes)
    denominator = np.sum(np.square(y_pred) + np.square(y_true), axes)
    
    return 1 - np.mean(numerator / (denominator + epsilon)) # average over classes and batch

您可以尝试此功能并找出最适合您的模型的功能。

关于python - 准确度表现良好,但图像分割中的 Dice 损失较差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60609585/

相关文章:

testing - 如何将深度学习应用于 UI 测试自动化?

python - RNN正则化:要正则化哪个组件?

python - 何时在 pytorch Lightning 中使用prepare_data 与 setup?

Python:如何将数组中的值从某个位置移动到另一个位置?

python - PyQt:在窗口上显示 QTextEdits

python PIL : How to FIll a Image with a copyright logo like this?

tensorflow - Keras问题下的反卷积

python - k 折叠交叉验证不会终止,卡在 cross_val_score

python - 如何捕获扭曲延迟回调中的异常?

python - 我如何使用 tensorflow 2 进行均衡学习率?