          self.kernel_size = kernel_size
          self.k_1 = k_1
          self.k_2 = k_2
          self.max_value = max_value
          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)
  
      def call(self, y_true, y_pred):
          """ Call the DSSIM Loss Function.
  
          Parameters
 
</s> remove         self.kernel_size = kernel_size
 </s> add         self.filter_size = filter_size
        self.filter_sigma = filter_sigma </s> remove     def call(self, y_true, y_pred):
 </s> add     @classmethod
    def call(cls, y_true, y_pred): </s> remove         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):
 </s> add         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 </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 
          self.kernel_size = kernel_size
          self.k_1 = k_1
          self.k_2 = k_2
          self.max_value = max_value



















  
      def call(self, y_true, y_pred):
          """ Call the DSSIM Loss Function.
  
          Parameters
keep keep keep keep 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