code: def _preprocess(
      self,
      past_target: torch.Tensor,
      past_observed_values: torch.Tensor,
      past_feat_dynamic_real: torch.Tensor,
      past_feat_dynamic_cat: torch.Tensor,
      feat_dynamic_real: torch.Tensor,
      feat_dynamic_cat: torch.Tensor,
      feat_static_real: torch.Tensor,
      feat_static_cat: torch.Tensor,
  ):
      obs = past_target * past_observed_values
      count = past_observed_values.sum(dim=1, keepdim=True)
      offset = obs.sum(1, keepdim=True) / (count + self.normalize_eps)
      scale = torch.sum(obs**2, 1, keepdim=True) / (
          count + self.normalize_eps
      )
      scale = torch.sqrt(scale - offset**2)
  
      past_target = (past_target - offset) / (
          scale + self.normalize_eps
      )
      past_target = past_target.unsqueeze(-1)
  
      proj = self.target_proj(past_target)
  
      past_covariates = []
      future_covariates = []
      static_covariates: List[torch.Tensor] = []
  
      past_covariates.append(proj)
      if self.past_feat_dynamic_proj is not None:
          projs = self.past_feat_dynamic_proj(past_feat_dynamic_real)
          past_covariates.extend(projs)
      if self.past_feat_dynamic_embed is not None:
          embs = self.past_feat_dynamic_embed(past_feat_dynamic_cat)
          past_covariates.extend(embs)
      if self.feat_dynamic_proj is not None:
          projs = self.feat_dynamic_proj(feat_dynamic_real)
          for proj in projs:
              ctx_proj = proj[:, 0 : self.context_length, ...]
              tgt_proj = proj[:, self.context_length :, ...]
              past_covariates.append(ctx_proj)
              future_covariates.append(tgt_proj)
      if self.feat_dynamic_embed is not None:
          embs = self.feat_dynamic_embed(feat_dynamic_cat)
          for emb in embs:
              ctx_emb = emb[:, 0 : self.context_length, ...]
              tgt_emb = emb[:, self.context_length :, ...]
              past_covariates.append(ctx_emb)
              future_covariates.append(tgt_emb)
  
      if self.feat_static_proj is not None:
          projs = self.feat_static_proj(feat_static_real)
          static_covariates.extend(projs)
      if self.feat_static_embed is not None:
          embs = self.feat_static_embed(feat_static_cat)
          static_covariates.extend(embs)
  
      return (
          past_covariates,
          future_covariates,
          static_covariates,
          offset,
          scale,
      )
  
imports: from typing import List, Optional, Tuple, Union
  import numpy
  import torch
  import torch.nn
  from torch.distributions import Distribution
  from gluonts.core.component import validated
  from pts.model import weighted_average
  from .tft_modules import FeatureProjector, FeatureEmbedder, VariableSelectionNetwork, GatedResidualNetwork, TemporalFusionEncoder, TemporalFusionDecoder
  from .tft_output import QuantileOutput
label_desc: Use image node_id 2 for calling the TemporalFusionTransformerNetwork obj's underlying member method code with example usage: obj._preprocess(past_target, past_observed_values, past_feat_dynamic_real, past_feat_dynamic_cat, feat_dynamic_real, feat_dynamic_cat, feat_static_real, feat_static_cat) and returns: past_covariates,  future_covariates,  static_covariates,  offset,  scale