BaseModel

class pytorch_forecasting.models.base_model.BaseModel(log_interval: Union[int, float] = - 1, log_val_interval: Union[int, float] = None, learning_rate: Union[float, List[float]] = 0.001, log_gradient_flow: bool = False, loss: pytorch_forecasting.metrics.Metric = SMAPE(), logging_metrics: torch.nn.modules.container.ModuleList = ModuleList(), reduce_on_plateau_patience: int = 1000, weight_decay: float = 0.0, monotone_constaints: Dict[str, int] = {}, output_transformer: Callable = None, optimizer='ranger')[source]

Bases: pytorch_lightning.core.lightning.LightningModule

BaseModel from which new timeseries models should inherit from. The hparams of the created object will default to the parameters indicated in __init__().

The forward() method should return a dictionary with at least the entry prediction and target_scale that contains the network’s output.

The idea of the base model is that common methods do not have to be re-implemented for every new architecture. The class is a [LightningModule](https://pytorch-lightning.readthedocs.io/en/latest/lightning_module.html) and follows its conventions. However, there are important additions:

  • You need to specify a loss attribute that stores the function to calculate the MultiHorizonLoss for backpropagation.

  • The from_dataset() method can be used to initialize a network using the specifications of a dataset. Often, parameters such as the number of features can be easily deduced from the dataset. Further, the method will also store how to rescale normalized predictions into the unnormalized prediction space. Override it to pass additional arguments to the __init__ method of your network that depend on your dataset.

  • The transform_output() method rescales the network output using the target normalizer from thedataset.

  • The step() method takes care of calculating the loss, logging additional metrics defined in the logging_metrics attribute and plots of sample predictions. You can override this method to add custom interpretations or pass extra arguments to the networks forward method.

  • The epoch_end() method can be used to calculate summaries of each epoch such as statistics on the encoder length, etc.

  • The predict() method makes predictions using a dataloader or dataset. Override it if you need to pass additional arguments to forward by default.

To implement your own architecture, it is best to look at existing ones to understand what might be a good approach.

Example

class Network(BaseModel):

    def __init__(self, my_first_parameter: int=2, loss=SMAPE()):
        self.save_hyperparameters()
        super().__init__()
        self.loss = loss

    def forward(self, x):
        encoding_target = x["encoder_target"]
        return dict(prediction=..., target_scale=x["target_scale"])

BaseModel for timeseries forecasting from which to inherit from

Parameters
  • log_interval (Union[int, float], optional) – Batches after which predictions are logged. If < 1.0, will log multiple entries per batch. Defaults to -1.

  • log_val_interval (Union[int, float], optional) – batches after which predictions for validation are logged. Defaults to None/log_interval.

  • learning_rate (float, optional) – Learning rate. Defaults to 1e-3.

  • log_gradient_flow (bool) – If to log gradient flow, this takes time and should be only done to diagnose training failures. Defaults to False.

  • loss (Metric, optional) – metric to optimize. Defaults to SMAPE().

  • logging_metrics (nn.ModuleList[MultiHorizonMetric]) – list of metrics that are logged during training. Defaults to [].

  • reduce_on_plateau_patience (int) – patience after which learning rate is reduced by a factor of 10. Defaults to 1000

  • weight_decay (float) – weight decay. Defaults to 0.0.

  • monotone_constaints (Dict[str, int]) – dictionary of monotonicity constraints for continuous decoder variables mapping position (e.g. "0" for first position) to constraint (-1 for negative and +1 for positive, larger numbers add more weight to the constraint vs. the loss but are usually not necessary). This constraint significantly slows down training. Defaults to {}.

  • output_transformer (Callable) – transformer that takes network output and transforms it to prediction space. Defaults to None which is equivalent to lambda out: out["prediction"].

  • optimizer (str) – optimizer

Methods

configure_optimizers()

Configure optimizers.

epoch_end(outputs[, label])

Run at epoch end for training or validation.

forward(x)

Network forward pass.

from_dataset(dataset, **kwargs)

Create model from dataset, i.e. save dataset parameters in model.

log_interval(train)

Log interval depending if training or validating

on_after_backward()

Log gradient flow for debugging.

on_load_checkpoint(checkpoint)

Do something with the checkpoint.

on_save_checkpoint(checkpoint)

Give the model a chance to add something to the checkpoint.

plot_prediction(x, out[, idx, …])

Plot prediction of prediction vs actuals

predict(data[, mode, return_index, …])

predict dataloader

predict_dependency(data, variable, values[, …])

Predict partial dependency.

size()

get number of parameters in model

step(x, y, batch_idx[, label])

Run for each train/val step.

training_epoch_end(outputs)

Called at the end of the training epoch with the outputs of all training steps.

training_step(batch, batch_idx)

Train on batch.

transform_output(out)

validation_epoch_end(outputs)

Called at the end of the validation epoch with the outputs of all validation steps.

validation_step(batch, batch_idx)

Operates on a single batch of data from the validation set.

configure_optimizers()[source]

Configure optimizers.

Uses single Ranger optimizer. Depending if learning rate is a list or a single float, implement dynamic learning rate scheduler or deterministic version

Returns

first entry is list of optimizers and second is list of schedulers

Return type

Tuple[List]

epoch_end(outputs, label='train')[source]

Run at epoch end for training or validation. Can be overriden in models.

forward(x: Dict[str, torch.Tensor]) → Dict[str, torch.Tensor][source]

Network forward pass.

Parameters

x (Dict[str, torch.Tensor]) – network input

Returns

netowrk outputs

Return type

Dict[str, torch.Tensor]

classmethod from_dataset(dataset: pytorch_forecasting.data.timeseries.TimeSeriesDataSet, **kwargs) → pytorch_lightning.core.lightning.LightningModule[source]

Create model from dataset, i.e. save dataset parameters in model

This function should be called as super().from_dataset() in a derived models that implement it

Parameters

dataset (TimeSeriesDataSet) – timeseries dataset

Returns

Model that can be trained

Return type

BaseModel

log_interval(train: bool)[source]

Log interval depending if training or validating

on_after_backward()[source]

Log gradient flow for debugging.

on_load_checkpoint(checkpoint: Dict[str, Any]) → None[source]

Do something with the checkpoint. Gives model a chance to load something before state_dict is restored.

Parameters

checkpoint – A dictionary with variables from the checkpoint.

on_save_checkpoint(checkpoint: Dict[str, Any]) → None[source]

Give the model a chance to add something to the checkpoint. state_dict is already there.

Parameters

checkpoint – A dictionary in which you can save variables to save in a checkpoint. Contents need to be pickleable.

plot_prediction(x: Dict[str, torch.Tensor], out: Dict[str, torch.Tensor], idx: int = 0, add_loss_to_title: Union[pytorch_forecasting.metrics.Metric, torch.Tensor, bool] = False, show_future_observed: bool = True, ax=None) → matplotlib.figure.Figure[source]

Plot prediction of prediction vs actuals

Parameters
  • x – network input

  • out – network output

  • idx – index of prediction to plot

  • add_loss_to_title – if to add loss to title or loss function to calculate. Can be either metrics, bool indicating if to use loss metric or tensor which contains losses for all samples. Default to False.

  • show_future_observed – if to show actuals for future. Defaults to True.

  • ax – matplotlib axes to plot on

Returns

matplotlib figure

predict(data: Union[torch.utils.data.dataloader.DataLoader, pandas.core.frame.DataFrame, pytorch_forecasting.data.timeseries.TimeSeriesDataSet], mode: Union[str, Tuple[str, str]] = 'prediction', return_index: bool = False, return_decoder_lengths: bool = False, batch_size: int = 64, num_workers: int = 0, fast_dev_run: bool = False, show_progress_bar: bool = False, return_x: bool = False, **kwargs)[source]

predict dataloader

Parameters
  • dataloader – dataloader, dataframe or dataset

  • mode – one of “prediction”, “quantiles” or “raw”, or tuple ("raw", output_name) where output_name is a name in the dictionary returned by forward()

  • return_index – if to return the prediction index

  • return_decoder_lengths – if to return decoder_lengths

  • batch_size – batch size for dataloader - only used if data is not a dataloader is passed

  • num_workers – number of workers for dataloader - only used if data is not a dataloader is passed

  • fast_dev_run – if to only return results of first batch

  • show_progress_bar – if to show progress bar. Defaults to False.

  • return_x – if to return network inputs

  • **kwargs – additional arguments to network’s forward method

Returns

some elements might not be present depending on what is configured

to be returned

Return type

output, x, index, decoder_lengths

predict_dependency(data: Union[torch.utils.data.dataloader.DataLoader, pandas.core.frame.DataFrame, pytorch_forecasting.data.timeseries.TimeSeriesDataSet], variable: str, values: Iterable, mode: str = 'dataframe', target='decoder', show_progress_bar: bool = False, **kwargs) → Union[numpy.ndarray, torch.Tensor, pandas.core.series.Series, pandas.core.frame.DataFrame][source]

Predict partial dependency.

Parameters
  • data (Union[DataLoader, pd.DataFrame, TimeSeriesDataSet]) – data

  • variable (str) – variable which to modify

  • values (Iterable) – array of values to probe

  • mode (str, optional) –

    Output mode. Defaults to “dataframe”. Either

    • ”series”: values are average prediction and index are probed values

    • ”dataframe”: columns are as obtained by the dataset.x_to_index() method,

      prediction (which is the mean prediction over the time horizon), normalized_prediction (which are predictions devided by the prediction for the first probed value) the variable name for the probed values

    • ”raw”: outputs a tensor of shape len(values) x prediction_shape

  • target – Defines which values are overwritten for making a prediction. Same as in set_overwrite_values(). Defaults to “decoder”.

  • show_progress_bar – if to show progress bar. Defaults to False.

  • **kwargs – additional kwargs to predict() method

Returns

output

Return type

Union[np.ndarray, torch.Tensor, pd.Series, pd.DataFrame]

size() → int[source]

get number of parameters in model

step(x: Dict[str, torch.Tensor], y: torch.Tensor, batch_idx: int, label='train', **kwargs)[source]

Run for each train/val step.

training_epoch_end(outputs)[source]

Called at the end of the training epoch with the outputs of all training steps. Use this in case you need to do something with all the outputs for every training_step.

# the pseudocode for these calls
train_outs = []
for train_batch in train_data:
    out = training_step(train_batch)
    train_outs.append(out)
training_epoch_end(train_outs)
Parameters

outputs – List of outputs you defined in training_step(), or if there are multiple dataloaders, a list containing a list of outputs for each dataloader.

Returns

None

Note

If this method is not overridden, this won’t be called.

Example:

def training_epoch_end(self, training_step_outputs):
    # do something with all training_step outputs
    return result

With multiple dataloaders, outputs will be a list of lists. The outer list contains one entry per dataloader, while the inner list contains the individual outputs of each training step for that dataloader.

def training_epoch_end(self, training_step_outputs):
    for out in training_step_outputs:
        # do something here
training_step(batch, batch_idx)[source]

Train on batch.

validation_epoch_end(outputs)[source]

Called at the end of the validation epoch with the outputs of all validation steps.

# the pseudocode for these calls
val_outs = []
for val_batch in val_data:
    out = validation_step(val_batch)
    val_outs.append(out)
validation_epoch_end(val_outs)
Parameters

outputs – List of outputs you defined in validation_step(), or if there are multiple dataloaders, a list containing a list of outputs for each dataloader.

Returns

None

Note

If you didn’t define a validation_step(), this won’t be called.

Examples

With a single dataloader:

def validation_epoch_end(self, val_step_outputs):
    for out in val_step_outputs:
        # do something

With multiple dataloaders, outputs will be a list of lists. The outer list contains one entry per dataloader, while the inner list contains the individual outputs of each validation step for that dataloader.

def validation_epoch_end(self, outputs):
    for dataloader_output_result in outputs:
        dataloader_outs = dataloader_output_result.dataloader_i_outputs

    self.log('final_metric', final_value)
validation_step(batch, batch_idx)[source]

Operates on a single batch of data from the validation set. In this step you’d might generate examples or calculate anything of interest like accuracy.

# the pseudocode for these calls
val_outs = []
for val_batch in val_data:
    out = validation_step(train_batch)
    val_outs.append(out)
    validation_epoch_end(val_outs)
Parameters
  • batch (Tensor | (Tensor, …) | [Tensor, …]) – The output of your DataLoader. A tensor, tuple or list.

  • batch_idx (int) – The index of this batch

  • dataloader_idx (int) – The index of the dataloader that produced this batch (only if multiple val datasets used)

Returns

Any of.

  • Any object or value

  • None - Validation will skip to the next batch

# pseudocode of order
out = validation_step()
if defined('validation_step_end'):
    out = validation_step_end(out)
out = validation_epoch_end(out)
# if you have one val dataloader:
def validation_step(self, batch, batch_idx)

# if you have multiple val dataloaders:
def validation_step(self, batch, batch_idx, dataloader_idx)

Examples

# CASE 1: A single validation dataset
def validation_step(self, batch, batch_idx):
    x, y = batch

    # implement your own
    out = self(x)
    loss = self.loss(out, y)

    # log 6 example images
    # or generated text... or whatever
    sample_imgs = x[:6]
    grid = torchvision.utils.make_grid(sample_imgs)
    self.logger.experiment.add_image('example_images', grid, 0)

    # calculate acc
    labels_hat = torch.argmax(out, dim=1)
    val_acc = torch.sum(y == labels_hat).item() / (len(y) * 1.0)

    # log the outputs!
    self.log_dict({'val_loss': loss, 'val_acc': val_acc})

If you pass in multiple val datasets, validation_step will have an additional argument.

# CASE 2: multiple validation datasets
def validation_step(self, batch, batch_idx, dataloader_idx):
    # dataloader_idx tells you which dataset this is.

Note

If you don’t need to validate you don’t need to implement this method.

Note

When the validation_step() is called, the model has been put in eval mode and PyTorch gradients have been disabled. At the end of validation, the model goes back to training mode and gradients are enabled.