          assert K.dtype(output) == "float32" and K.eval(output).shape == (2, )
      else:
          output = output.numpy()
          assert output.dtype == "float32" and not np.isnan(output)
  
  
  @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> 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             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) </s> remove         texts = ["{} ({})".format(titles[0], side),
                 "{0} > {0}".format(titles[0]),
                 "{} > {}".format(titles[0], titles[1])]
 </s> add         texts = [f"{titles[0]} ({side})",
                 f"{titles[0]} > {titles[0]}",
                 f"{titles[0]} > {titles[1]}"] </s> remove         m_t_indices = tf.gather(m_t, indices)
 </s> add         m_t_indices = tf.gather(m_t, indices)  # pylint:disable=no-value-for-parameter </s> remove         self.kernel_size = kernel_size
 </s> add         self.filter_size = filter_size
        self.filter_sigma = filter_sigma
          assert K.dtype(output) == "float32" and K.eval(output).shape == (2, )
      else:
          output = output.numpy()
          assert output.dtype == "float32" and not np.isnan(output)






































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
 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 
tests/lib/model/losses_test.py