Python 在 keras 中制作自定义损失函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45961428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 17:23:13  来源:igfitidea点击:

Make a custom loss function in keras

pythonmachine-learningtensorflowkeras

提问by Subham Mukherjee

Hi I have been trying to make a custom loss function in keras for dice_error_coefficient. It has its implementations in tensorboardand I tried using the same function in keras with tensorflow but it keeps returning a NoneTypewhen I used model.train_on_batchor model.fitwhere as it gives proper values when used in metrics in the model. Can please someone help me out with what should i do? I have tried following libraries like Keras-FCN by ahundt where he has used custom loss functions but none of it seems to work. The target and output in the code are y_true and y_pred respectively as used in the losses.py file in keras.

嗨,我一直在尝试在 keras 中为 dice_error_coefficient 制作自定义损失函数。它有它的实现tensorboard,我尝试使用相同的功能与tensorflow keras但它一直返回NoneType当我用model.train_on_batchmodel.fit其中在模型中的指标使用时,它提供正确的价值观。请有人帮我解决我该怎么办?我曾尝试关注 ahundt 的 Keras-FCN 等库,他在其中使用了自定义损失函数,但似乎都不起作用。代码中的目标和输出分别是 y_true 和 y_pred,如 keras 中的 loss.py 文件中使用的那样。

def dice_hard_coe(target, output, threshold=0.5, axis=[1,2], smooth=1e-5):
    """References
    -----------
    - `Wiki-Dice <https://en.wikipedia.org/wiki/S?rensen–Dice_coefficient>`_
    """

    output = tf.cast(output > threshold, dtype=tf.float32)
    target = tf.cast(target > threshold, dtype=tf.float32)
    inse = tf.reduce_sum(tf.multiply(output, target), axis=axis)
    l = tf.reduce_sum(output, axis=axis)
    r = tf.reduce_sum(target, axis=axis)
    hard_dice = (2. * inse + smooth) / (l + r + smooth)
    hard_dice = tf.reduce_mean(hard_dice)
    return hard_dice

回答by T. Nair

There are two steps in implementing a parameterized custom loss function in Keras. First, writing a method for the coefficient/metric. Second, writing a wrapper function to format things the way Keras needs them to be.

在 Keras 中实现参数化的自定义损失函数有两个步骤。首先,编写系数/度量的方法。其次,编写一个包装函数来按照 Keras 需要的方式格式化事物。

  1. It's actually quite a bit cleaner to use the Keras backend instead of tensorflow directly for simple custom loss functions like DICE. Here's an example of the coefficient implemented that way:

    import keras.backend as K
    def dice_coef(y_true, y_pred, smooth, thresh):
        y_pred = y_pred > thresh
        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)
    
  2. Now for the tricky part. Keras loss functions must only take (y_true, y_pred) as parameters. So we need a separate function that returns another function.

    def dice_loss(smooth, thresh):
      def dice(y_true, y_pred)
        return -dice_coef(y_true, y_pred, smooth, thresh)
      return dice
    
  1. 对于像 DICE 这样的简单自定义损失函数,直接使用 Keras 后端而不是 tensorflow 实际上要干净一些。这是以这种方式实现的系数的示例:

    import keras.backend as K
    def dice_coef(y_true, y_pred, smooth, thresh):
        y_pred = y_pred > thresh
        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)
    
  2. 现在是棘手的部分。Keras 损失函数只能以 (y_true, y_pred) 作为参数。所以我们需要一个单独的函数来返回另一个函数。

    def dice_loss(smooth, thresh):
      def dice(y_true, y_pred)
        return -dice_coef(y_true, y_pred, smooth, thresh)
      return dice
    

Finally, you can use it as follows in Keras compile.

最后,您可以在 Keras compile 中按如下方式使用它。

# build model 
model = my_model()
# get the loss function
model_dice = dice_loss(smooth=1e-5, thresh=0.5)
# compile model
model.compile(loss=model_dice)