在keras中制作自定义丢失功能

Sub*_*jee 30 python machine-learning keras tensorflow

嗨,我一直在尝试在keras中为dice_error_coefficient创建自定义丢失函数.它有它的实现tensorboard,我尝试使用相同的功能与tensorflow keras但它一直返回NoneType当我用model.train_on_batchmodel.fit其中在模型中的指标使用时,它提供正确的价值观.可以请有人帮我解决我该怎么办?我曾经尝试过像ahundt这样的Keras-FCN这样的库,在那里他使用了自定义丢失函数,但似乎都没有.代码中的目标和输出分别是y_true和y_pred,如keras中的losses.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
Run Code Online (Sandbox Code Playgroud)

小智 75

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

  1. 实际上使用Keras后端而不是tensorflow直接用于简单的自定义丢失功能(如DICE)相当简洁.以下是以这种方式实现的系数示例:

    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)
    
    Run Code Online (Sandbox Code Playgroud)
  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
    
    Run Code Online (Sandbox Code Playgroud)

最后,您可以在Keras编译中使用它,如下所示.

# 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)
Run Code Online (Sandbox Code Playgroud)

  • 有人可以确认这是否有效吗?ypred 和 ytrue 是张量,所以 `ypred = ypred &gt; ytrue` 会失败。在我的情况下,对 ypred 和 ytrue 的任何计算都失败了。 (4认同)
  • 它的工作方式就像你说的那样.问题是输出不能以这种方式转换为1,0.所以它返回了一个无价值.删除该部分它完美地工作.谢谢你的帮助. (2认同)

feh*_*ich 2

此外,您可以通过继承来扩展现有的损失函数。例如屏蔽BinaryCrossEntropy

class MaskedBinaryCrossentropy(tf.keras.losses.BinaryCrossentropy):
    def call(self, y_true, y_pred):
        mask = y_true != -1
        y_true = y_true[mask]
        y_pred = y_pred[mask]
        return super().call(y_true, y_pred)
Run Code Online (Sandbox Code Playgroud)

指南是一个很好的起点custom loghttps ://www.tensorflow.org/guide/keras/train_and_evaluate#custom_losses