2

我有一个任务,我输入一个500x500x1图像并得到一个500x500x1二进制分割。500x500工作时,只应触发一小部分(小“目标”)。我在输出端使用 sigmoid 激活。由于希望这样一小部分是正的,因此训练往往会在所有输出为零或非常接近时停止。我已经编写了自己的损失函数来部分处理它,但如果可能的话,我想使用带有类权重的二元交叉熵。

我的问题分为两部分:

  1. 如果我天真地将binary_crossentropy损失应用于我的500x500x1输出,它会根据需要在每个像素的基础上应用吗?

  2. keras 有没有办法通过每个像素的单个 sigmoid 输出来应用类加权?

4

1 回答 1

5

回答你的问题。

  1. binary_cross_entropy的,只要您输入图像分割神经网络对的形式(500x500x1 图像(灰度图像)+ 500x500x1(对应于您的图像的掩码),就可以基于每个像素工作。

  2. 通过输入参数' class_weight'参数model.fit()

    假设您有 2 个类,分布率为 90%-10%。然后,当算法对代表性较差的类(在这种情况下为 10% 的类)犯错时,您可能希望对算法进行 9 倍的惩罚。假设您有 900 个类别 1 的示例和 100 个类别 2 的示例。

然后是你的类权重字典(有多种计算方法,重要的是为表现不佳的类分配更大的权重),

  class_weights = {0:1000/900,1:1000/100}

例子 :model.fit(X_train, Y_train, epochs = 30, batch_size=32, class_weight=class_weight)

注意:这仅适用于 2d 案例(class_weight)。对于 3D 或更高维空间,应使用“sample_weights”。出于分割目的,您宁愿使用sample_weightsparameter

  1. 您将获得的最大收益是通过其他损失函数。除了binary_crossentropy和之外,其他损失categorical_crossentropy本身在不平衡数据集上表现更好。Dice Loss就是这样一个损失函数。

Keras 实现:

    smooth = 1.

    def dice_coef(y_true, y_pred):
        y_true_f = K.flatten(y_true)
        y_pred_f = K.flatten(y_pred)
        intersection = K.sum(y_true_f * y_pred_f)
        return (2. * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)
    
    
    def dice_coef_loss(y_true, y_pred):
        return 1 - dice_coef(y_true, y_pred)
  1. binary_crossentropy 如果适合您,您还可以将总和和其他损失用作损失函数:即loss = dice_loss + bce
于 2019-05-07T10:57:04.627 回答