Search code examples
pythontensorflowloss-function

Gradient Difference Loss of two images in TensorFlow


How can I implement the Gradient Difference Loss of two images in TensorFlow (in sequential model), like that made using PyTorch (https://github.com/mmany/pytorch-GDL/blob/main/custom_loss_functions.py)? Thanks!


Solution

  • I found the solution in https://github.com/jonasrothfuss/DeepEpisodicMemory/blob/master/models/loss_functions.py

    def gradient_difference_loss(true, pred, alpha=2.0):
      """
      computes gradient difference loss of two images
      :param ground truth image: Tensor of shape (batch_size, frame_height, frame_width, num_channels)
      :param predicted image: Tensor of shape (batch_size, frame_height, frame_width, num_channels)
      :param alpha parameter of the used l-norm
      """
      #tf.assert_equal(tf.shape(true), tf.shape(pred))
      # vertical
      true_pred_diff_vert = tf.pow(tf.abs(difference_gradient(true, vertical=True) - difference_gradient(pred, vertical=True)), alpha)
      # horizontal
      true_pred_diff_hor = tf.pow(tf.abs(difference_gradient(true, vertical=False) - difference_gradient(pred, vertical=False)), alpha)
      # normalization over all dimensions
      return (tf.reduce_mean(true_pred_diff_vert) + tf.reduce_mean(true_pred_diff_hor)) / tf.to_float(2)
    
    
    def difference_gradient(image, vertical=True):
      """
      :param image: Tensor of shape (batch_size, frame_height, frame_width, num_channels)
      :param vertical: boolean that indicates whether vertical or horizontal pixel gradient shall be computed
      :return: difference_gradient -> Tenor of shape (:, frame_height-1, frame_width, :) if vertical and (:, frame_height, frame_width-1, :) else
      """
      s = tf.shape(image)
      if vertical:
        return tf.abs(image[:, 0:s[1] - 1, :, :] - image[:, 1:s[1], :, :])
      else:
        return tf.abs(image[:, :, 0:s[2]-1,:] - image[:, :, 1:s[2], :])
    

    I just had to adjust the original code line below:

    return (tf.reduce_mean(true_pred_diff_vert) + tf.reduce_mean(true_pred_diff_hor)) / tf.to_float(2)
    

    to:

    return (tf.reduce_mean(true_pred_diff_vert) + tf.reduce_mean(true_pred_diff_hor)) / tf.cast(2, tf.float32)
    

    due to the specific version of TensorFlow I'm using (based on help obtained from https://github.com/google/tangent/issues/95#issuecomment-562551139).