  
          # Use depth-wise convolution to calculate edge maps per channel.
          # Output tensor has shape [batch_size, h, w, d * num_kernels].
          pad_sizes = [[0, 0], [2, 2], [2, 2], [0, 0]]
          padded = tf.pad(image, pad_sizes, mode='REFLECT')
          output = K.depthwise_conv2d(padded, kernels)
  
          if not magnitude:  # direction of edges
              # Reshape to [batch_size, h, w, d, num_kernels].
              shape = K.concatenate([image_shape, num_kernels], axis=0)
 
</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         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 

@pytest.mark.parametrize('dummy', [None], ids=[get_backend().upper()])
def test_dssim_channels_last(dummy):  # pylint:disable=unused-argument
    """ Basic test for DSSIM Loss """
    prev_data = K.image_data_format()
    K.set_image_data_format('channels_last')
    for input_dim, kernel_size in zip([32, 33], [2, 3]):
        input_shape = [input_dim, input_dim, 3]
        var_x = np.random.random_sample(4 * input_dim * input_dim * 3)
        var_x = var_x.reshape([4] + input_shape)
        var_y = np.random.random_sample(4 * input_dim * input_dim * 3)
        var_y = var_y.reshape([4] + input_shape)

        model = Sequential()
        model.add(Conv2D(32, (3, 3), padding='same', input_shape=input_shape,
                         activation='relu'))
        model.add(Conv2D(3, (3, 3), padding='same', input_shape=input_shape,
                         activation='relu'))
        adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
        model.compile(loss=losses.DSSIMObjective(kernel_size=kernel_size),
                      metrics=['mse'],
                      optimizer=adam)
        model.fit(var_x, var_y, batch_size=2, epochs=1, shuffle='batch')

        # Test same
        x_1 = K.constant(var_x, 'float32')
        x_2 = K.constant(var_x, 'float32')
        dssim = losses.DSSIMObjective(kernel_size=kernel_size)
        assert_allclose(0.0, K.eval(dssim(x_1, x_2)), atol=1e-4)

        # Test opposite
        x_1 = K.zeros([4] + input_shape)
        x_2 = K.ones([4] + input_shape)
        dssim = losses.DSSIMObjective(kernel_size=kernel_size)
        assert_allclose(0.5, K.eval(dssim(x_1, x_2)), atol=1e-4)

    K.set_image_data_format(prev_data)
 </s> add  </s> remove                 if not split_output:  # Rename losses to reflect the side's output
                    loss_name = f"{loss_name.replace('_both', '')}_{side}"
 </s> add                 if loss_name[-2:] not in ("_a", "_b"):  # Rename losses to reflect the side output
                    new_name = f"{loss_name.replace('_both', '')}_{side}"
                    logger.debug("Renaming loss output from '%s' to '%s'", loss_name, new_name)
                    loss_name = new_name </s> remove             partial_x, _ = tf.split(inputs,
                                    [partial_size, layer_size - partial_size],
                                    axis=self.axis)
 </s> add             partial_x, _ = tf.split(  # pylint:disable=redundant-keyword-arg,no-value-for-parameter
                inputs,
                [partial_size, layer_size - partial_size],
                axis=self.axis)
        padded = tf.pad(image,  # pylint:disable=unexpected-keyword-arg,no-value-for-parameter
                        pad_sizes,
                        mode='REFLECT')
  
          # Use depth-wise convolution to calculate edge maps per channel.
          # Output tensor has shape [batch_size, h, w, d * num_kernels].
          pad_sizes = [[0, 0], [2, 2], [2, 2], [0, 0]]
        padded = tf.pad(image,  # pylint:disable=unexpected-keyword-arg,no-value-for-parameter
                        pad_sizes,
                        mode='REFLECT')
          output = K.depthwise_conv2d(padded, kernels)
  
          if not magnitude:  # direction of edges
              # Reshape to [batch_size, h, w, d, num_kernels].
              shape = K.concatenate([image_shape, num_kernels], axis=0)
keep keep keep keep 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