                      loss = self.flatten_outliers(loss)
                  iterations.add(len(loss))
                  raw["raw_{}".format(loss_name)] = loss
  
              self.iterations = 0 if not iterations else min(iterations)
              if len(iterations) > 1:
                  # Crop all losses to the same number of items
                  if self.iterations == 0:
                      raw = {lossname: list() for lossname in raw}
                  else:
 
</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                 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                     raw = {lossname: loss[:self.iterations] for lossname, loss in raw.items()}
 </s> add                     self.stats = {lossname: loss[:self._iterations]
                                  for lossname, loss in self.stats.items()} </s> remove                 if loss_name not in self.loss_keys:
 </s> add                 if loss_name not in self._loss_keys: </s> remove             data = self.calc_rate_total() if self.is_totals else self.calc_rate()
            if self.args["flatten_outliers"]:
                data = self.flatten_outliers(data)
            self.iterations = len(data)
            raw = {"raw_rate": data}
 </s> add             data = self._calc_rate_total() if self._is_totals else self._calc_rate()
            if self._args["flatten_outliers"]:
                data = self._flatten_outliers(data)
            self._iterations = data.shape[0]
            self.stats["raw_rate"] = data
                      loss = self.flatten_outliers(loss)
                  iterations.add(len(loss))
                  raw["raw_{}".format(loss_name)] = loss
  

              if len(iterations) > 1:
                  # Crop all losses to the same number of items
                  if self.iterations == 0:
                      raw = {lossname: list() for lossname in raw}
                  else:
keep keep keep keep 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