code: def create_transformation(self) -> Transformation:
      transforms = []
      if self.use_feat_dynamic_real:
          transforms.append(
              AsNumpyArray(
                  field=FieldName.FEAT_DYNAMIC_REAL,
                  expected_ndim=2,
              )
          )
      else:
          transforms.extend(
              [
                  SetField(
                      output_field=FieldName.FEAT_DYNAMIC_REAL,
                      value=[[]]
                      * (self.context_length + self.prediction_length),
                  ),
                  AsNumpyArray(
                      field=FieldName.FEAT_DYNAMIC_REAL,
                      expected_ndim=2,
                  ),
                  # SwapAxes(input_fields=
                  # [FieldName.FEAT_DYNAMIC_REAL], axes=(0,1)),
              ]
          )
      if self.use_feat_dynamic_cat:
          transforms.append(
              AsNumpyArray(
                  field=FieldName.FEAT_DYNAMIC_CAT,
                  expected_ndim=2,
              )
          )
      else:
          # Manually set dummy dynamic categorical features and split by time
          # Unknown issue in dataloader if leave splitting to
          # InstanceSplitter
          transforms.extend(
              [
                  SetField(
                      output_field="past_" + FieldName.FEAT_DYNAMIC_CAT,
                      value=[[]] * self.context_length,
                  ),
                  AsNumpyArray(
                      field="past_" + FieldName.FEAT_DYNAMIC_CAT,
                      expected_ndim=2,
                  ),
                  SetField(
                      output_field="future_"
                      + FieldName.FEAT_DYNAMIC_CAT,
                      value=[[]] * self.prediction_length,
                  ),
                  AsNumpyArray(
                      field="future_" + FieldName.FEAT_DYNAMIC_CAT,
                      expected_ndim=2,
                  ),
              ]
          )
      if self.use_feat_static_real:
          transforms.append(
              AsNumpyArray(
                  field=FieldName.FEAT_STATIC_REAL,
                  expected_ndim=1,
              )
          )
      else:
          transforms.extend(
              [
                  SetField(
                      output_field=FieldName.FEAT_STATIC_REAL,
                      value=[],
                  ),
                  AsNumpyArray(
                      field=FieldName.FEAT_STATIC_REAL,
                      expected_ndim=1,
                  ),
              ]
          )
      if self.use_feat_static_cat:
          transforms.append(
              AsNumpyArray(
                  field=FieldName.FEAT_STATIC_CAT,
                  expected_ndim=1,
              )
          )
  
      transforms.extend(
          [
              AsNumpyArray(field=FieldName.TARGET, expected_ndim=1),
              AddObservedValuesIndicator(
                  target_field=FieldName.TARGET,
                  output_field=FieldName.OBSERVED_VALUES,
              ),
              AddTimeFeatures(
                  start_field=FieldName.START,
                  target_field=FieldName.TARGET,
                  output_field=FieldName.FEAT_TIME,
                  time_features=self.time_features,
                  pred_length=self.prediction_length,
              ),
              AddAgeFeature(
                  target_field=FieldName.TARGET,
                  output_field=FieldName.FEAT_AGE,
                  pred_length=self.prediction_length,
                  log_scale=True,
              ),
              VstackFeatures(
                  output_field=FieldName.FEAT_DYNAMIC_REAL,
                  input_fields=[FieldName.FEAT_TIME, FieldName.FEAT_AGE]
                  + (
                      [FieldName.FEAT_DYNAMIC_REAL]
                      if self.use_feat_dynamic_real
                      else []
                  ),
              ),
          ]
      )
      return Chain(transforms)
  
imports: from functools import partial
  from typing import List, Optional
  from mxnet.gluon import HybridBlock
  from gluonts.core.component import validated
  from gluonts.dataset.common import Dataset
  from gluonts.dataset.field_names import FieldName
  from gluonts.dataset.loader import DataLoader, TrainDataLoader, ValidationDataLoader
  from gluonts.model.forecast_generator import QuantileForecastGenerator
  from gluonts.mx.batchify import batchify
  from gluonts.mx.model.estimator import GluonEstimator
  from gluonts.mx.model.predictor import RepresentableBlockPredictor
  from gluonts.mx.trainer import Trainer
  from gluonts.mx.util import copy_parameters, get_hybrid_forward_input_names
  from gluonts.time_feature import TimeFeature, time_features_from_frequency_str
  from gluonts.transform import AddAgeFeature, AddObservedValuesIndicator, AddTimeFeatures, AsNumpyArray, Chain, ExpectedNumInstanceSampler, InstanceSampler, InstanceSplitter, SelectFields, SetField, TestSplitSampler, Transformation, ValidationSplitSampler, VstackFeatures
  from ._network import SelfAttentionPredictionNetwork, SelfAttentionTrainingNetwork
label_desc: Use image node_id 2 for calling the SelfAttentionEstimator obj's underlying member method code with example usage: obj.create_transformation() and returns: Chain