class_docstr: SimpleFeedForwardEstimator shows how to build a simple MLP model predicting
  the next target time-steps given the previous ones.
  
  Given that we want to define a pytorch model trainable by SGD, we inherit the
  parent class `PyTorchEstimator` that handles most of the logic for fitting a
  neural-network.
  
  We thus only have to define:
  
  1. How the data is transformed before being fed to our model::
  
      def create_transformation(self) -> Transformation
  
  2. How the training happens::
  
      def create_training_network(self) -> nn.Module
  
  3. how the predictions can be made for a batch given a trained network::
  
      def create_predictor(
           self,
           transformation: Transformation,
           trained_net: nn.Module,
      ) -> Predictor
  
  
  Parameters
  ----------
  freq
      Time time granularity of the data
  prediction_length
      Length of the prediction horizon
  trainer
      Trainer object to be used (default: Trainer())
  num_hidden_dimensions
      Number of hidden nodes in each layer (default: [40, 40])
  context_length
      Number of time units that condition the predictions
      (default: None, in which case context_length = prediction_length)
  distr_output
      Distribution to fit (default: StudentTOutput())
  batch_normalization
      Whether to use batch normalization (default: False)
  mean_scaling
      Scale the network input by the data mean and the network output by
      its inverse (default: True)
  num_parallel_samples
      Number of evaluation samples per time series to increase parallelism during inference.
      This is a model optimization that does not affect the accuracy (default: 100)
code: def create_predictor(
      self,
      transformation: Transformation,
      trained_network: nn.Module,
      device: torch.device,
  ) -> Predictor:
      prediction_splitter = self.create_instance_splitter("test")
  
      prediction_network = SimpleFeedForwardPredictionNetwork(
          num_hidden_dimensions=self.num_hidden_dimensions,
          prediction_length=self.prediction_length,
          context_length=self.context_length,
          distr_output=self.distr_output,
          batch_normalization=self.batch_normalization,
          mean_scaling=self.mean_scaling,
          num_parallel_samples=self.num_parallel_samples,
      ).to(device)
  
      copy_parameters(trained_network, prediction_network)
      input_names = get_module_forward_input_names(prediction_network)
  
      return PyTorchPredictor(
          input_transform=transformation + prediction_splitter,
          input_names=input_names,
          prediction_net=prediction_network,
          batch_size=self.trainer.batch_size,
          freq=self.freq,
          prediction_length=self.prediction_length,
          device=device,
      )
  
imports: from typing import List, Optional
  import torch
  import torch.nn
  from gluonts.core.component import validated
  from gluonts.torch.util import copy_parameters
  from gluonts.torch.model.predictor import PyTorchPredictor
  from gluonts.torch.modules.distribution_output import DistributionOutput
  from gluonts.model.predictor import Predictor
  from gluonts.dataset.field_names import FieldName
  from gluonts.transform import Transformation, Chain, InstanceSplitter, ExpectedNumInstanceSampler, ValidationSplitSampler, TestSplitSampler
  from pts.model.utils import get_module_forward_input_names
  from pts import Trainer
  from pts.model import PyTorchEstimator
  from pts.modules import StudentTOutput
  from .simple_feedforward_network import SimpleFeedForwardTrainingNetwork, SimpleFeedForwardPredictionNetwork
label_desc: Use image node_id 5 for calling the SimpleFeedForwardEstimator obj's underlying member method code with example usage: obj.create_predictor(transformation, trained_network, device) and returns: PyTorchPredictor