          ------
          ValueError
              If `padding` is invalid.
          """
          if padding == 'same':
              padding = 'SAME'
          elif padding == 'valid':
              padding = 'VALID'
          else:
              raise ValueError('Invalid padding:', padding)
          return padding
  
      def extract_image_patches(self, input_tensor, k_sizes, s_sizes,
                                padding='same', data_format='channels_last'):
          """ Extract the patches from an image.
  
          Parameters
          ----------
          input_tensor: tensor
              The input image
          k_sizes: tuple
              2-d tuple with the kernel size
          s_sizes: tuple
              2-d tuple with the strides size
          padding: str, optional
              `"same"` or `"valid"`. Default: `"same"`
          data_format: str, optional.
              `"channels_last"` or `"channels_first"`. Default: `"channels_last"`
  
          Returns
          -------
          The (k_w, k_h) patches extracted
              Tensorflow ==> (batch_size, w, h, k_w, k_h, c)
              Theano ==> (batch_size, w, h, c, k_w, k_h)
          """
          kernel = [1, k_sizes[0], k_sizes[1], 1]
          strides = [1, s_sizes[0], s_sizes[1], 1]
          padding = self._preprocess_padding(padding)
          if data_format == 'channels_first':
              input_tensor = K.permute_dimensions(input_tensor, (0, 2, 3, 1))
          patches = tf.image.extract_patches(input_tensor, kernel, strides, [1, 1, 1, 1], padding)
          return patches
  
  
  class GeneralizedLoss(tf.keras.losses.Loss):
      """  Generalized function used to return a large variety of mathematical loss functions.
  
      The primary benefit is a smooth, differentiable version of L1 loss.
  
      References
 
</s> remove 
        Notes
        -----
        There are additional parameters for this function. some of the 'modes' for edge behavior
        do not yet have a gradient definition in the Theano tree and cannot be used for learning
        """

        kernel = [self.kernel_size, self.kernel_size]
        y_true = K.reshape(y_true, [-1] + list(self._int_shape(y_pred)[1:]))
        y_pred = K.reshape(y_pred, [-1] + list(self._int_shape(y_pred)[1:]))
        patches_pred = self.extract_image_patches(y_pred,
                                                  kernel,
                                                  kernel,
                                                  'valid',
                                                  self.dim_ordering)
        patches_true = self.extract_image_patches(y_true,
                                                  kernel,
                                                  kernel,
                                                  'valid',
                                                  self.dim_ordering)

        # Get mean
        u_true = K.mean(patches_true, axis=-1)
        u_pred = K.mean(patches_pred, axis=-1)
        # Get variance
        var_true = K.var(patches_true, axis=-1)
        var_pred = K.var(patches_pred, axis=-1)
        # Get standard deviation
        covar_true_pred = K.mean(
            patches_true * patches_pred, axis=-1) - u_true * u_pred

        ssim = (2 * u_true * u_pred + self.c_1) * (
            2 * covar_true_pred + self.c_2)
        denom = (K.square(u_true) + K.square(u_pred) + self.c_1) * (
            var_pred + var_true + self.c_2)
        ssim /= denom  # no need for clipping, c_1 + c_2 make the denorm non-zero
        return (1.0 - ssim) / 2.0

    @staticmethod
    def _preprocess_padding(padding):
        """Convert keras padding to tensorflow padding.

        Parameters
        ----------
        padding: string,
            `"same"` or `"valid"`.

        Returns
        -------
        str
            `"SAME"` or `"VALID"`.

        Raises
        ------
        ValueError
            If `padding` is invalid.
 </s> add  </s> remove         self.c_1 = (self.k_1 * self.max_value) ** 2
        self.c_2 = (self.k_2 * self.max_value) ** 2
        self.dim_ordering = K.image_data_format()

    @staticmethod
    def _int_shape(input_tensor):
        """ Returns the shape of tensor or variable as a tuple of int or None entries.

        Parameters
        ----------
        input_tensor: tensor or variable
            The input to return the shape for

        Returns
        -------
        tuple
            A tuple of integers (or None entries)
        """
        return K.int_shape(input_tensor)
 </s> add  </s> remove         padded = tf.pad(image, pad_sizes, mode='REFLECT')
 </s> add         padded = tf.pad(image,  # pylint:disable=unexpected-keyword-arg,no-value-for-parameter
                        pad_sizes,
                        mode='REFLECT') </s> remove class GradientLoss(tf.keras.losses.Loss):
 </s> add class GradientLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
          ------
          ValueError
              If `padding` is invalid.
          """
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
        ssim = tf.image.ssim(y_true,
                             y_pred,
                             self.max_value,
                             filter_size=self.filter_size,
                             filter_sigma=self.filter_sigma,
                             k1=self.k_1,
                             k2=self.k_2)
        dssim_loss = 1. - ssim
        return dssim_loss


class GeneralizedLoss(tf.keras.losses.Loss):  # pylint:disable=too-few-public-methods
      """  Generalized function used to return a large variety of mathematical loss functions.
  
      The primary benefit is a smooth, differentiable version of L1 loss.
  
      References
keep keep keep keep replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace replace keep keep keep keep keep
 Update code to support Tensorflow versions up to 2.8 (#1213)

* Update maximum tf version in setup + requirements

* - bump max version of tf version in launcher
- standardise tf version check

* update keras get_custom_objects  for tf>2.6

* bugfix: force black text in GUI file dialogs (linux)

* dssim loss - Move to stock tf.ssim function

* Update optimizer imports for compatibility

* fix logging for tf2.8

* Fix GUI graphing for TF2.8

* update tests

* bump requirements.txt versions

* Remove limit on nvidia-ml-py

* Graphing bugfixes
  - Prevent live graph from displaying if data not yet available

* bugfix: Live graph. Collect loss labels correctly

* fix: live graph - swallow inconsistent loss errors

* Bugfix: Prevent live graph from clearing during training

* Fix graphing for AMD 
lib/model/losses_tf.py