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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #5
0
    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