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 _compute_valid_loss(
      self, outsample_y, output, outsample_mask, temporal_cols, y_idx
  ):
      if self.loss.is_distribution_output:
          _, y_loc, y_scale = self._inv_normalization(
              y_hat=outsample_y,
              temporal_cols=temporal_cols,
              y_idx=y_idx,
          )
          distr_args = self.loss.scale_decouple(
              output=output, loc=y_loc, scale=y_scale
          )
          _, sample_mean, quants = self.loss.sample(
              distr_args=distr_args
          )
  
          if str(type(self.valid_loss)) in [
              "<class 'neuralforecast.losses.pytorch.sCRPS'>",
              "<class 'neuralforecast.losses.pytorch.MQLoss'>",
          ]:
              output = quants
          elif str(type(self.valid_loss)) in [
              "<class 'neuralforecast.losses.pytorch.relMSE'>"
          ]:
              output = torch.unsqueeze(
                  sample_mean, dim=-1
              )  # [N,H,1] -> [N,H]
  
      # Validation Loss evaluation
      if self.valid_loss.is_distribution_output:
          valid_loss = self.valid_loss(
              y=outsample_y, distr_args=distr_args, mask=outsample_mask
          )
      else:
          output, _, _ = self._inv_normalization(
              y_hat=output, temporal_cols=temporal_cols, y_idx=y_idx
          )
          valid_loss = self.valid_loss(
              y=outsample_y, y_hat=output, mask=outsample_mask
          )
      return valid_loss
  
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 11 for calling the BaseWindows obj's underlying member method code with example usage: obj._compute_valid_loss(outsample_y, output, outsample_mask, temporal_cols, y_idx) and returns: valid_loss