class_docstr: Base Recurrent
  
  Base class for all recurrent-based models. The forecasts are produced sequentially between
  windows.
  
  This class implements the basic functionality for all windows-based models, including:
  - PyTorch Lightning's methods training_step, validation_step, predict_step. <br>
  - fit and predict methods used by NeuralForecast.core class. <br>
  - sampling and wrangling methods to sequential windows. <br>
class_docstr_tok: ["Base","Recurrent","Base","class","for","all","recurrent-based","models",".","The","forecasts","are","produced","sequentially","between","windows",".","This","class","implements","the","basic","functionality","for","all","windows-based","models",",","including",":","-","PyTorch","Lightning","'s","methods","training_step",",","validation_step",",","predict_step",".","<","br",">","-","fit","and","predict","methods","used","by","NeuralForecast.core","class",".","<","br",">","-","sampling","and","wrangling","methods","to","sequential","windows",".","<","br",">"]
code: def __init__(
      self,
      h,
      input_size,
      inference_input_size,
      loss,
      valid_loss,
      learning_rate,
      max_steps,
      val_check_steps,
      batch_size,
      valid_batch_size,
      scaler_type="robust",
      num_lr_decays=0,
      early_stop_patience_steps=-1,
      futr_exog_list=None,
      hist_exog_list=None,
      stat_exog_list=None,
      num_workers_loader=0,
      drop_last_loader=False,
      random_seed=1,
      alias=None,
      **trainer_kwargs,
  ):
      super(BaseRecurrent, self).__init__()
  
      self.save_hyperparameters()  # Allows instantiation from a checkpoint from class
      self.random_seed = random_seed
      pl.seed_everything(self.random_seed, workers=True)
  
      # Padder to complete train windows,
      # example y=[1,2,3,4,5] h=3 -> last y_output = [5,0,0]
      self.h = h
      self.input_size = input_size
      self.inference_input_size = inference_input_size
      self.padder = nn.ConstantPad1d(padding=(0, self.h), value=0)
  
      # Loss
      self.loss = loss
      if valid_loss is None:
          self.valid_loss = loss
      else:
          self.valid_loss = valid_loss
      self.train_trajectories = []
      self.valid_trajectories = []
  
      if (
          str(type(self.loss))
          == "<class 'neuralforecast.losses.pytorch.DistributionLoss'>"
          and self.loss.distribution == "Bernoulli"
      ):
          raise Exception(
              "Temporal Classification not yet available for Recurrent-based models"
          )
  
      # Valid batch_size
      self.batch_size = batch_size
      if valid_batch_size is None:
          self.valid_batch_size = batch_size
      else:
          self.valid_batch_size = valid_batch_size
  
      # Optimization
      self.learning_rate = learning_rate
      self.max_steps = max_steps
      self.num_lr_decays = num_lr_decays
      self.lr_decay_steps = (
          max(max_steps // self.num_lr_decays, 1)
          if self.num_lr_decays > 0
          else 10e7
      )
      self.early_stop_patience_steps = early_stop_patience_steps
      self.val_check_steps = val_check_steps
  
      # Variables
      self.futr_exog_list = (
          list(futr_exog_list) if futr_exog_list is not None else []
      )
      self.hist_exog_list = (
          list(hist_exog_list) if hist_exog_list is not None else []
      )
      self.stat_exog_list = (
          list(stat_exog_list) if stat_exog_list is not None else []
      )
  
      # Scaler
      self.scaler = TemporalNorm(
          scaler_type=scaler_type,
          dim=-1,  # Time dimension is -1.
          num_features=1
          + len(self.hist_exog_list)
          + len(self.futr_exog_list),
      )
  
      # Fit arguments
      self.val_size = 0
      self.test_size = 0
  
      ## Trainer arguments ##
      # Max steps, validation steps and check_val_every_n_epoch
      trainer_kwargs = {**trainer_kwargs, **{"max_steps": max_steps}}
  
      if "max_epochs" in trainer_kwargs.keys():
          raise Exception(
              "max_epochs is deprecated, use max_steps instead."
          )
  
      # Callbacks
      if trainer_kwargs.get("callbacks", None) is None:
          callbacks = [TQDMProgressBar()]
          # Early stopping
          if self.early_stop_patience_steps > 0:
              callbacks += [
                  EarlyStopping(
                      monitor="ptl/val_loss",
                      patience=self.early_stop_patience_steps,
                  )
              ]
  
          trainer_kwargs["callbacks"] = callbacks
  
      # Add GPU accelerator if available
      if trainer_kwargs.get("accelerator", None) is None:
          if torch.cuda.is_available():
              trainer_kwargs["accelerator"] = "gpu"
      if trainer_kwargs.get("devices", None) is None:
          if torch.cuda.is_available():
              trainer_kwargs["devices"] = -1
  
      # Avoid saturating local memory, disabled fit model checkpoints
      if trainer_kwargs.get("enable_checkpointing", None) is None:
          trainer_kwargs["enable_checkpointing"] = False
  
      self.trainer_kwargs = trainer_kwargs
  
      # DataModule arguments
      self.num_workers_loader = num_workers_loader
      self.drop_last_loader = drop_last_loader
      # used by on_validation_epoch_end hook
      self.validation_step_outputs = []
      self.alias = alias
  
imports: import random
  import warnings
  import numpy
  import torch
  import torch.nn
  import pytorch_lightning
  from pytorch_lightning.callbacks import TQDMProgressBar
  from pytorch_lightning.callbacks.early_stopping import EarlyStopping
  from ._scalers import TemporalNorm
  from ..tsdataset import TimeSeriesDataModule
  from ..utils import get_indexer_raise_missing
label_desc: Use image node_id 1 to create a new BaseRecurrent object from inherited base classes: pl with example: obj = BaseRecurrent(h, input_size, inference_input_size, loss, valid_loss, learning_rate, max_steps, val_check_steps, batch_size, valid_batch_size, scaler_type, num_lr_decays, early_stop_patience_steps, futr_exog_list, hist_exog_list, stat_exog_list, num_workers_loader, drop_last_loader, random_seed, alias)