class_docstr: Base Windows
  
  Base class for all windows-based models. The forecasts are produced separately
  for each window, which are randomly sampled during training.
  
  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 generate windows.
class_docstr_tok: ["Base","Windows","Base","class","for","all","windows-based","models",".","The","forecasts","are","produced","separately","for","each","window",",","which","are","randomly","sampled","during","training",".","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","generate","windows","."]
code: def __init__(
      self,
      h,
      input_size,
      loss,
      valid_loss,
      learning_rate,
      max_steps,
      val_check_steps,
      batch_size,
      valid_batch_size,
      windows_batch_size,
      inference_windows_batch_size,
      start_padding_enabled,
      step_size=1,
      num_lr_decays=0,
      early_stop_patience_steps=-1,
      scaler_type="identity",
      futr_exog_list=None,
      hist_exog_list=None,
      stat_exog_list=None,
      exclude_insample_y=False,
      num_workers_loader=0,
      drop_last_loader=False,
      random_seed=1,
      alias=None,
      **trainer_kwargs,
  ):
      super(BaseWindows, 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.start_padding_enabled = start_padding_enabled
      if start_padding_enabled:
          self.padder_train = nn.ConstantPad1d(
              padding=(self.input_size - 1, self.h), value=0
          )
      else:
          self.padder_train = 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 = []
  
      # Batch sizes
      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
      if inference_windows_batch_size is None:
          self.inference_windows_batch_size = windows_batch_size
      else:
          self.inference_windows_batch_size = (
              inference_windows_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
      self.windows_batch_size = windows_batch_size
      self.step_size = step_size
  
      # 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 []
      )
      self.exclude_insample_y = exclude_insample_y
  
      # 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
  
      # Model state
      self.decompose_forecast = False
  
      ## 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 BaseWindows object from inherited base classes: pl with example: obj = BaseWindows(h, input_size, loss, valid_loss, learning_rate, max_steps, val_check_steps, batch_size, valid_batch_size, windows_batch_size, inference_windows_batch_size, start_padding_enabled, step_size, num_lr_decays, early_stop_patience_steps, scaler_type, futr_exog_list, hist_exog_list, stat_exog_list, exclude_insample_y, num_workers_loader, drop_last_loader, random_seed, alias)