class_docstr: Base Multivariate
  
  Base class for all multivariate models. The forecasts for all time-series are produced simultaneously
  within 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 multivariate windows.
class_docstr_tok: ["Base","Multivariate","Base","class","for","all","multivariate","models",".","The","forecasts","for","all","time-series","are","produced","simultaneously","within","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","multivariate","windows","."]
code: def _inv_normalization(self, y_hat, temporal_cols, y_idx):
      # Receives window predictions [Ws, H, n_series]
      # 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], :].squeeze(1)
      y_loc = self.scaler.x_shift[:, [y_idx], :].squeeze(1)
  
      # y_scale = torch.repeat_interleave(y_scale, repeats=y_hat.shape[-1], dim=-1)
      # y_loc = torch.repeat_interleave(y_loc, repeats=y_hat.shape[-1], dim=-1)
  
      y_hat = self.scaler.inverse_transform(
          z=y_hat, x_scale=y_scale, x_shift=y_loc
      )
  
      # 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 BaseMultivariate 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