def rmse(y_true, y_pred): m_factor = rmse_factor m = RootMeanSquaredError() m.update_state(inverse_transform(y_true, mmn), inverse_transform(y_pred, mmn)) # return denormalize(m.result().numpy(), mmn) * m_factor return m.result().numpy() * m_factor
def measure_rmse_tf(y_true, y_pred): """Calculate the RMSE score between y_true and y_pred and return it. Parameters ---------- y_true : np.ndarray Array of true values y_pred : np.ndarray Array of predicted values Returns ------- rmse : float The RMSE between the arrays y_true and y_pred """ m = RootMeanSquaredError() m.update_state(y_true, y_pred) rmse = m.result().numpy() return rmse
def measure_rmse_tf(y_true, y_pred): m = RootMeanSquaredError() m.update_state(y_true, y_pred) result = m.result().numpy() return result
def rmse(y_true, y_pred): m_factor = rmse_factor m = RootMeanSquaredError() m.update_state(y_true, y_pred) return denormalize(m.result().numpy(), mmn) * m_factor
def _training_loop( self, filepath: str, train_gen: train_ts_generator, # can name of function be type? val_gen: train_ts_generator, epochs: int = 100, steps_per_epoch: int = 50, early_stopping: int = True, stopping_patience: int = 5, stopping_delta: int = 1, ) -> typing.Tuple[tf.Tensor, int]: """ util function iterates over batches, updates gradients, records metrics, writes to tb, checkpoints, early stopping """ # set up metrics to track during training batch_loss_avg = Mean() epoch_loss_avg = Mean() eval_loss_avg = Mean() eval_mae = MeanAbsoluteError() eval_rmse = RootMeanSquaredError() # set up early stopping callback early_stopping_cb = EarlyStopping(patience=stopping_patience, active=early_stopping, delta=stopping_delta) # setup table for unscaling self._lookup_table = build_tf_lookup(self._ts_obj.target_means) # Iterate over epochs. best_metric = math.inf for epoch in range(epochs): logger.info(f"Start of epoch {epoch}") start_time = time.time() for batch, (x_batch_train, cat_labels, y_batch_train) in enumerate(train_gen): # compute loss with tf.GradientTape(persistent=True) as tape: mu, scale = self._model(x_batch_train, training=True) # softplus parameters scale = softplus(scale) if self._ts_obj.count_data: mu = softplus(mu) mu, scale = unscale(mu, scale, cat_labels, self._lookup_table) loss_value = self._loss_fn(y_batch_train, (mu, scale)) # sgd if self._tb: tf.summary.scalar("train_loss", loss_value, epoch * steps_per_epoch + batch) batch_loss_avg(loss_value) epoch_loss_avg(loss_value) grads = tape.gradient(loss_value, self._model.trainable_weights) self._optimizer.apply_gradients( zip(grads, self._model.trainable_weights)) # Log 5x per epoch. if batch % (steps_per_epoch // 5) == 0 and batch != 0: logger.info( f"Epoch {epoch}: Avg train loss over last {(steps_per_epoch // 5)} steps: {batch_loss_avg.result()}" ) batch_loss_avg.reset_states() # Run each epoch batches times epoch_loss_avg_result = epoch_loss_avg.result() if batch == steps_per_epoch: logger.info( f"Epoch {epoch} took {round(time.time() - start_time, 0)}s : Avg train loss: {epoch_loss_avg_result}" ) break # validation if val_gen is not None: logger.info(f"End of epoch {epoch}, validating...") start_time = time.time() for batch, (x_batch_val, cat_labels, y_batch_val) in enumerate(val_gen): # compute loss, doesn't need to be persistent bc not updating weights with tf.GradientTape() as tape: # treat as training -> reset lstm states inbetween each batch mu, scale = self._model(x_batch_val, training=True) # softplus parameters mu, scale = self._softplus(mu, scale) # unscale parameters mu, scale = unscale(mu, scale, cat_labels, self._lookup_table) # calculate loss loss_value = self._loss_fn(y_batch_val, (mu, scale)) # log validation metrics (avg loss, avg MAE, avg RMSE) eval_mae(y_batch_val, mu) eval_rmse(y_batch_val, mu) eval_loss_avg(loss_value) if batch == steps_per_epoch: break # logging eval_mae_result = eval_mae.result() logger.info( f"Validation took {round(time.time() - start_time, 0)}s") logger.info( f"Epoch {epoch}: Val loss on {steps_per_epoch} steps: {eval_loss_avg.result()}" ) logger.info( f"Epoch {epoch}: Val MAE: {eval_mae_result}, RMSE: {eval_rmse.result()}" ) if self._tb: tf.summary.scalar("val_loss", eval_loss_avg.result(), epoch) tf.summary.scalar("val_mae", eval_mae_result, epoch) tf.summary.scalar("val_rmse", eval_rmse.result(), epoch) new_metric = eval_mae_result # early stopping if early_stopping_cb(eval_mae_result): break # reset metric states eval_loss_avg.reset_states() eval_mae.reset_states() eval_rmse.reset_states() else: if early_stopping_cb(epoch_loss_avg_result): break new_metric = epoch_loss_avg_result # update best_metric and save new checkpoint if improvement if new_metric < best_metric: best_metric = new_metric if filepath is not None: self._checkpointer.save(file_prefix=filepath) else: self.save_weights("model_best_weights.h5") # reset epoch loss metric epoch_loss_avg.reset_states() # load in best weights before returning if not using checkpointer if filepath is None: self.load_weights("model_best_weights.h5") os.remove("model_best_weights.h5") return best_metric, epoch + 1