code: 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:
          num_classes = prediction.shape[1].value
          # weight_map_nclasses = tf.reshape(
          #     tf.tile(weight_map, [num_classes]), prediction.get_shape())
          weight_map_nclasses = tf.tile(
              tf.expand_dims(tf.reshape(weight_map, [-1]), 1),
              [1, num_classes],
          )
          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_denominator = tf.reduce_sum(
          tf.multiply(weights, tf.maximum(seg_vol + ref_vol, 1))
      )
      generalised_dice_score = (
          generalised_dice_numerator / generalised_dice_denominator
      )
      generalised_dice_score = tf.where(
          tf.is_nan(generalised_dice_score), 1.0, generalised_dice_score
      )
      return 1 - generalised_dice_score
  
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import tensorflow
  from niftynet.engine.application_factory import LossSegmentationFactory
  from niftynet.layer.base_layer import Layer
label_desc: Use image node_id 5 for calling a global function with example usage: generalised_dice_loss(prediction, ground_truth, weight_map, type_weight) and returns: unknown