          elapsed = 0
          examples = 0
          iterations = 0
          batchset = set()
          total_summaries = len(sessions_stats)
          for idx, summary in enumerate(sessions_stats):
              if idx == 0:
                  starttime = summary["start"]
              if idx == total_summaries - 1:
                  endtime = summary["end"]
              elapsed += summary["elapsed"]
 
</s> remove                 if self.args["flatten_outliers"]:
                    loss = self.flatten_outliers(loss)
                iterations.add(len(loss))
                raw["raw_{}".format(loss_name)] = loss
 </s> add                 iterations.add(loss.shape[0])

                if self._limit > 0:
                    loss = loss[-self._limit:]

                if self._args["flatten_outliers"]:
                    loss = self._flatten_outliers(loss)

                self.stats["raw_{}".format(loss_name)] = loss

            self._iterations = 0 if not iterations else min(iterations)
            if self._limit > 1:
                self._start_iteration = max(0, self._iterations - self._limit)
                self._iterations = min(self._iterations, self._limit)
            else:
                self._start_iteration = 0 </s> remove     @property
    def sessions_stats(self):
        """ Return compiled stats """
        compiled = list()
        for sess_idx, ts_data in self.time_stats.items():
            logger.debug("Compiling session ID: %s", sess_idx)
            if self.session.state is None:
                logger.debug("Session state dict doesn't exist. Most likely task has been "
                             "terminated during compilation")
                return None
            iterations = self.session.get_iterations_for_session(sess_idx)
            elapsed = ts_data["end_time"] - ts_data["start_time"]
            batchsize = self.session.total_batchsize.get(sess_idx, 0)
            compiled.append(
                {"session": sess_idx,
                 "start": ts_data["start_time"],
                 "end": ts_data["end_time"],
                 "elapsed": elapsed,
                 "rate": ((batchsize * 2) * iterations) / elapsed if elapsed != 0 else 0,
                 "batch": batchsize,
                 "iterations": iterations})
        compiled = sorted(compiled, key=lambda k: k["session"])
        return compiled

    def compile_stats(self):
        """ Compile sessions stats with totals, format and return """
        logger.debug("Compiling sessions summary data")
        compiled_stats = self.sessions_stats
        if not compiled_stats:
            return compiled_stats
        logger.debug("sessions_stats: %s", compiled_stats)
        total_stats = self.total_stats(compiled_stats)
        compiled_stats.append(total_stats)
        compiled_stats = self.format_stats(compiled_stats)
        logger.debug("Final stats: %s", compiled_stats)
        return compiled_stats

    @staticmethod
    def total_stats(sessions_stats):
        """ Return total stats """
 </s> add     def _total_stats(self):
        """ Compile the Totals stats.
        Totals are fully calculated each time as they will change on the basis of the training
        session.

        Returns
        -------
        dict:
            The Session name, start time, end time, elapsed time, rate, batch size and number of
            iterations for all session ids within the loaded data.
        """ </s> remove             self.iterations = 0 if not iterations else min(iterations)
 </s> add  </s> remove                 if self.iterations == 0:
                    raw = {lossname: list() for lossname in raw}
 </s> add                 if self._iterations == 0:
                    self.stats = {lossname: np.array(list(), dtype=loss.dtype)
                                  for lossname, loss in self.stats.items()} </s> remove     @property
    def time_stats(self):
        """ Return session time stats """
        ts_data = self.session.tb_logs.get_timestamps()
        time_stats = {sess_id: {"start_time": min(timestamps) if timestamps else 0,
                                "end_time": max(timestamps) if timestamps else 0,
                                "datapoints": len(timestamps) if timestamps else 0}
                      for sess_id, timestamps in ts_data.items()}
        return time_stats
 </s> add         Returns
        -------
        dict
            The collated session summary statistics
        """
        timestamps = self._time_stats[session_id]
        elapsed = int(timestamps["end_time"] - timestamps["start_time"])
        batchsize = self._session.batch_sizes.get(session_id, 0)
        retval = dict(
            session=session_id,
            start=timestamps["start_time"],
            end=timestamps["end_time"],
            elapsed=elapsed,
            rate=(((batchsize * 2) * timestamps["iterations"]) / elapsed if elapsed != 0 else 0),
            batch=batchsize,
            iterations=timestamps["iterations"])
        logger.debug(retval)
        return retval
        total_summaries = len(self._per_session_stats)
        for idx, summary in enumerate(self._per_session_stats):
          elapsed = 0
          examples = 0
          iterations = 0
          batchset = set()
        total_summaries = len(self._per_session_stats)
        for idx, summary in enumerate(self._per_session_stats):
        total_summaries = len(self._per_session_stats)
        for idx, summary in enumerate(self._per_session_stats):
              if idx == 0:
                  starttime = summary["start"]
              if idx == total_summaries - 1:
                  endtime = summary["end"]
              elapsed += summary["elapsed"]
keep keep keep keep replace replace keep keep keep keep keep
 GUI - Stats optimization (#1067)

* Faster stat loading + caching

* Compress data in cache

* Optimize some calculations

* Vectorize smoothing

* stats.Calculations optimized

* Load latest training data from live iterator

* Add options to training graph 
lib/gui/stats.py