          height = int(width / 4.5)
          total_width = width * 3
          logger.debug("height: %s, total_width: %s", height, total_width)
          font = cv2.FONT_HERSHEY_SIMPLEX
          texts = ["{} ({})".format(titles[0], side),
                   "{0} > {0}".format(titles[0]),
                   "{} > {}".format(titles[0], titles[1])]
          scaling = (width / 144) * 0.45
          text_sizes = [cv2.getTextSize(texts[idx], font, scaling, 1)[0]
                        for idx in range(len(texts))]
          text_y = int((height + text_sizes[0][1]) / 2)
          text_x = [int((width - text_sizes[idx][0]) / 2) + width * idx
 
</s> remove         rate = list()
 </s> add         rate = [] </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 
        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         samples = list()
 </s> add         samples = []
        texts = [f"{titles[0]} ({side})",
                 f"{titles[0]} > {titles[0]}",
                 f"{titles[0]} > {titles[1]}"]
          height = int(width / 4.5)
          total_width = width * 3
          logger.debug("height: %s, total_width: %s", height, total_width)
          font = cv2.FONT_HERSHEY_SIMPLEX
        texts = [f"{titles[0]} ({side})",
                 f"{titles[0]} > {titles[0]}",
                 f"{titles[0]} > {titles[1]}"]
        texts = [f"{titles[0]} ({side})",
                 f"{titles[0]} > {titles[0]}",
                 f"{titles[0]} > {titles[1]}"]
        texts = [f"{titles[0]} ({side})",
                 f"{titles[0]} > {titles[0]}",
                 f"{titles[0]} > {titles[1]}"]
          scaling = (width / 144) * 0.45
          text_sizes = [cv2.getTextSize(texts[idx], font, scaling, 1)[0]
                        for idx in range(len(texts))]
          text_y = int((height + text_sizes[0][1]) / 2)
          text_x = [int((width - text_sizes[idx][0]) / 2) + width * idx
keep keep keep keep 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 
plugins/train/trainer/_base.py