  
              if len(iterations) > 1:
                  # Crop all losses to the same number of items
                  if self._iterations == 0:
                      self.stats = {lossname: np.array(list(), dtype=loss.dtype)
                                    for lossname, loss in self.stats.items()}
                  else:
                      self.stats = {lossname: loss[:self._iterations]
                                    for lossname, loss in self.stats.items()}
  
 
</s> remove                 self.stats["raw_{}".format(loss_name)] = loss
 </s> add                 self.stats[f"raw_{loss_name}"] = loss </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         loss_keys = {sess_id: list(logs.keys())
                     for sess_id, logs in self._tb_logs.get_loss(session_id=session_id).items()}
 </s> add         if get_backend() == "amd":
            # We can't log the graph in Tensorboard logs for AMD so need to obtain from state file
            loss_keys = {int(sess_id): [name for name in session["loss_names"] if name != "total"]
                         for sess_id, session in self._state["sessions"].items()}
        else:
            loss_keys = {sess_id: list(logs.keys())
                         for sess_id, logs
                         in self._tb_logs.get_loss(session_id=session_id).items()}
 </s> remove         samples = list()
 </s> add         samples = [] </s> remove         times, loss = (np.array(times, dtype="float64"), np.array(loss, dtype="float32"))
 </s> add         if is_live and not all(len(val) == len(self._loss_labels) for val in loss):
            # TODO Many attempts have been made to fix this for live graph logging, and the issue
            # of non-consistent loss record sizes keeps coming up. In the meantime we shall swallow
            # any loss values that are of incorrect length so graph remains functional. This will,
            # most likely, lead to a mismatch on iteration count so a proper fix should be
            # implemented.

            # Timestamps and loss appears to remain consistent with each other, but sometimes loss
            # appears non-consistent. eg (lengths):
            # [2, 2, 2, 2, 2, 2, 2, 0] - last loss collection has zero length
            # [1, 2, 2, 2, 2, 2, 2, 2] - 1st loss collection has 1 length
            # [2, 2, 2, 3, 2, 2, 2] - 4th loss collection has 3 length

            logger.debug("Inconsistent loss found in collection: %s", loss)
            for idx in reversed(range(len(loss))):
                if len(loss[idx]) != len(self._loss_labels):
                    logger.debug("Removing loss/timestamps at position %s", idx)
                    del loss[idx]
                    del times[idx]
                    self.stats = {lossname: np.array([], dtype=loss.dtype)
  
              if len(iterations) > 1:
                  # Crop all losses to the same number of items
                  if self._iterations == 0:
                    self.stats = {lossname: np.array([], dtype=loss.dtype)
                                    for lossname, loss in self.stats.items()}
                  else:
                      self.stats = {lossname: loss[:self._iterations]
                                    for lossname, loss in self.stats.items()}
  
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/gui/analysis/stats.py