【问题标题】:TensorFlow/Keras: How to get meaningful loss values from my generalized dice loss function?TensorFlow/Keras:如何从我的广义骰子损失函数中获得有意义的损失值?
【发布时间】:2019-11-04 00:21:25
【问题描述】:

我正在尝试使用generalized dice loss 函数在 TensorFlow 1.10 的 Keras API(使用 Python)中执行语义分割:

def generalized_dice_loss(onehots_true, logits):
    smooth = tf.constant(1e-17)
    onehots_true, logits = mask(onehots_true, logits) # Not all of my pixels contain ground truth, and I filter those pixels out, which results in shape [num_gt_pixels, num_classes]-shaped labels and logits.
    probabilities = tf.nn.softmax(logits)
    weights = 1.0 / (tf.reduce_sum(onehots_true, axis=0)**2)
    weights = tf.clip_by_value(weights, 1e-17, 1.0 - 1e-7) # Is this the correct way of dealing with inf values (the results of zero divisions)?
    numerator = tf.reduce_sum(onehots_true * probabilities, axis=0)
    numerator = tf.reduce_sum(weights * numerator)

    denominator = tf.reduce_sum(onehots_true + probabilities, axis=0)
    denominator = tf.reduce_sum(weights * denominator)

    loss = 1.0 - 2.0 * (numerator + smooth) / (denominator + smooth)
    return loss

但是,我正在努力获得任何有意义的损失,这并不总是 1。我在这里做错了什么?

在计算初始权重(每个类别一个)后,它们包含许多来自零分割的inf,因为通常样本图像中只有所有类别的一小部分。因此,我将权重剪辑到 [1e-17, 1-1e-17] 范围内(这是个好主意吗?),之后它们看起来像这样:

tf.Tensor(
[4.89021e-05 2.21410e-10 5.43187e-11 1.00000e+00 1.00000e+00 4.23855e-07
 5.87461e-09 3.13044e-09 2.95369e-07 1.00000e+00 1.00000e+00 2.22499e-05
 1.00000e+00 1.73611e-03 9.47212e-10 1.12608e-05 2.77563e-09 1.00926e-08
 7.74787e-10 1.00000e+00 1.34570e-07], shape=(21,), dtype=float32)

这对我来说似乎很好,虽然它们很小。分子(tf.reduce_sum(onehots_true * probabilities, axis=0),在加权之前)如下所示:

tf.Tensor(
[3.42069e+01 0.00000e+00 9.43506e+03 7.88478e+01 1.50554e-02 0.00000e+00
 1.22765e+01 4.36149e-01 1.75026e+02 0.00000e+00 2.33183e+02 1.81064e-01
 0.00000e+00 1.60128e+02 1.48867e+04 0.00000e+00 3.87697e+00 4.49753e+02
 5.87062e+01 0.00000e+00 0.00000e+00], shape=(21,), dtype=float32)
tf.Tensor(1.0, shape=(), dtype=float32)

这看起来也很合理,因为它们基本上是标签各自的大小乘以网络对它们的确定性(在训练开始时可能很低)。分母(tf.reduce_sum(onehots_true + probabilities, axis=0),在加权之前)看起来也不错:

tf.Tensor(
[ 14053.483   25004.557  250343.36    66548.234    6653.863    3470.502
   5318.3926 164206.19    19914.338    1951.0701   3559.3235   7248.4717
   5984.786    7902.9004 133984.66    41497.473   25010.273   22232.062
  26451.926   66250.39     6497.735 ], shape=(21,), dtype=float32)

这些很大,但这是意料之中的,因为像素总和为 1 的类概率,因此这些分母的总和应该或多或少等于具有基本事实的像素数量。

但是,将分子相加得到的总和非常小(~0.001,尽管有时它在一个数字范围内),而分母相加得到非常大的值。这导致我的最终损失完全是 1,或者非常接近。如何减轻这种影响并获得稳定的梯度?我几乎实现了确切的骰子损失公式。我在这里错过了什么?

【问题讨论】:

    标签: python tensorflow keras loss-function


    【解决方案1】:

    显然我需要省略权重,然后我得到一个可行的损失函数。不知道为什么我不能使用重量,如果可以的话它会添加什么。追问:https://stats.stackexchange.com/questions/414107/why-are-weights-being-used-in-generalized-dice-loss-and-why-cant-i

    【讨论】:

      猜你喜欢
      • 2019-12-25
      • 2018-08-07
      • 2018-10-28
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 2019-01-20
      • 2020-10-21
      • 1970-01-01
      相关资源
      最近更新 更多