【问题标题】:Generalized Dice Loss: None-gradient when implemented in keras广义骰子损失:在 keras 中实现时无梯度
【发布时间】:2018-05-31 16:34:10
【问题描述】:

我正在尝试在用 Keras(TF 后端)编写的不同卷积网络中实现 NiftyNet 中实现的广义骰子损失。

def generalised_dice_loss(prediction,
                      ground_truth,
                      weight_map=None,
                      type_weight='Square'):
"""
Function to calculate the Generalised Dice Loss defined in
    Sudre, C. et. al. (2017) Generalised Dice overlap as a deep learning
    loss function for highly unbalanced segmentations. DLMIA 2017

:param prediction: the logits
:param ground_truth: the segmentation ground truth
:param weight_map:
:param type_weight: type of weighting allowed between labels (choice
    between Square (square of inverse of volume),
    Simple (inverse of volume) and Uniform (no weighting))
:return: the loss
"""
prediction = tf.cast(prediction, tf.float32)
if len(ground_truth.shape) == len(prediction.shape):
    ground_truth = ground_truth[..., -1]
one_hot = labels_to_one_hot(ground_truth, tf.shape(prediction)[-1])

if weight_map is not None:
    n_classes = prediction.shape[1].value
    weight_map_nclasses = tf.reshape(
        tf.tile(weight_map, [n_classes]), prediction.get_shape())
    ref_vol = tf.sparse_reduce_sum(
        weight_map_nclasses * one_hot, reduction_axes=[0])

    intersect = tf.sparse_reduce_sum(
        weight_map_nclasses * one_hot * prediction, reduction_axes=[0])
    seg_vol = tf.reduce_sum(
        tf.multiply(weight_map_nclasses, prediction), 0)
else:
    ref_vol = tf.sparse_reduce_sum(one_hot, reduction_axes=[0])
    intersect = tf.sparse_reduce_sum(one_hot * prediction,
                                     reduction_axes=[0])
    seg_vol = tf.reduce_sum(prediction, 0)
if type_weight == 'Square':
    weights = tf.reciprocal(tf.square(ref_vol))
elif type_weight == 'Simple':
    weights = tf.reciprocal(ref_vol)
elif type_weight == 'Uniform':
    weights = tf.ones_like(ref_vol)
else:
    raise ValueError("The variable type_weight \"{}\""
                     "is not defined.".format(type_weight))
new_weights = tf.where(tf.is_inf(weights), tf.zeros_like(weights), weights)
weights = tf.where(tf.is_inf(weights), tf.ones_like(weights) *
                   tf.reduce_max(new_weights), weights)
generalised_dice_numerator = \
    2 * tf.reduce_sum(tf.multiply(weights, intersect))
generalised_dice_denominator = \
    tf.reduce_sum(tf.multiply(weights, seg_vol + ref_vol)) + 1e-6
generalised_dice_score = \
    generalised_dice_numerator / generalised_dice_denominator
return 1 - generalised_dice_score

但是,当我尝试使用此损失函数训练模型时,会出现以下错误:

ValueError:一个操作没有梯度。请确保您的所有操作都定义了渐变(即可微分)。无梯度的常用操作:K.argmax、K.round、K.eval。

我尝试实现的任何其他损失函数都不会发生这种情况。有人知道如何解决这个问题吗?据我所知,代码中没有不可微分的运算符。

【问题讨论】:

    标签: niftynet


    【解决方案1】:

    keras(自定义层和/或模型)的类似问题,解决方案是在 def init() 中构建层,然后在 call() 中使用它们

    self.lstm_custom_1 = keras.layers.LSTM(128,batch_input_shape=batch_input_shape, return_sequences=False,stateful=True)
    self.lstm_custom_1.build(batch_input_shape)
    
    self.dense_custom_1 = keras.layers.Dense(32,  activation = 'relu')
    self.dense_custom_1.build(input_shape=(batch_size, 128))
    

    【讨论】:

      猜你喜欢
      • 2018-08-07
      • 2019-12-25
      • 1970-01-01
      • 2019-11-04
      • 2021-03-15
      • 2021-03-11
      • 2021-07-24
      • 2021-02-24
      • 1970-01-01
      相关资源
      最近更新 更多