                                   if layer["name"] == layer_name)["config"]
              layer_outputs = self._get_outputs(output_config)
              for output in layer_outputs:  # Drill into sub-model to get the actual output names
                  loss_name = output[0][0]
                  if not split_output:  # Rename losses to reflect the side's output
                      loss_name = f"{loss_name.replace('_both', '')}_{side}"
                  if loss_name not in self._loss_labels:
                      logger.debug("Adding loss name: '%s'", loss_name)
                      self._loss_labels.append(loss_name)
          logger.debug("Collated loss labels: %s", self._loss_labels)
  
 
</s> remove         output = ", ".join(["Loss {}: {:.5f}".format(side, side_loss)
 </s> add         output = ", ".join([f"Loss {side}: {side_loss:.5f}" </s> remove         images = dict()
 </s> add         images = {} </s> remove         output = "[{}] [#{:05d}] {}".format(timestamp, self._model.iterations, output)
        print("\r{}".format(output), end="")
 </s> add         output = f"[{timestamp}] [#{self._model.iterations:05d}] {output}"
        print(f"\r{output}", end="") </s> remove                     self.stats = {lossname: np.array(list(), dtype=loss.dtype)
 </s> add                     self.stats = {lossname: np.array([], dtype=loss.dtype)
                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
                                   if layer["name"] == layer_name)["config"]
              layer_outputs = self._get_outputs(output_config)
              for output in layer_outputs:  # Drill into sub-model to get the actual output names
                  loss_name = output[0][0]
                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
                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
                  if loss_name not in self._loss_labels:
                      logger.debug("Adding loss name: '%s'", loss_name)
                      self._loss_labels.append(loss_name)
          logger.debug("Collated loss labels: %s", self._loss_labels)
  
keep keep keep keep 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/gui/analysis/event_reader.py