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 _inv_normalization(self, y_hat, temporal_cols, y_idx):
      # Receives window predictions [B, H, output]
      # Broadcasts outputs and inverts normalization
  
      # Add C dimension
      if y_hat.ndim == 2:
          remove_dimension = True
          y_hat = y_hat.unsqueeze(-1)
      else:
          remove_dimension = False
  
      y_scale = self.scaler.x_scale[:, :, [y_idx]]
      y_loc = self.scaler.x_shift[:, :, [y_idx]]
  
      y_scale = torch.repeat_interleave(
          y_scale, repeats=y_hat.shape[-1], dim=-1
      ).to(y_hat.device)
      y_loc = torch.repeat_interleave(
          y_loc, repeats=y_hat.shape[-1], dim=-1
      ).to(y_hat.device)
  
      y_hat = self.scaler.inverse_transform(
          z=y_hat, x_scale=y_scale, x_shift=y_loc
      )
      y_loc = y_loc.to(y_hat.device)
      y_scale = y_scale.to(y_hat.device)
  
      if remove_dimension:
          y_hat = y_hat.squeeze(-1)
          y_loc = y_loc.squeeze(-1)
          y_scale = y_scale.squeeze(-1)
  
      return y_hat, y_loc, y_scale
  
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 8 for calling the BaseWindows obj's underlying member method code with example usage: obj._inv_normalization(y_hat, temporal_cols, y_idx) and returns: y_hat,  y_loc,  y_scale