code: def __init__(
      self,
      normalization_parameters: Dict[int, NormalizationParameters],
      use_gpu: Optional[bool] = None,
      device: Optional[torch.device] = None,
  ) -> None:
      super().__init__()
      self.normalization_parameters = normalization_parameters
      (
          self.feature_id_to_index,
          self.sorted_features,
          self.sorted_feature_boundaries,
      ) = self._sort_features_by_normalization()
  
      cuda_available = torch.cuda.is_available()
      logger.info("CUDA availability: {}".format(cuda_available))
      if device is not None:
          self.device = device
      elif use_gpu and cuda_available:
          logger.warn(
              "use_gpu is deprecated, please pass in the device directly"
          )
          logger.info("Using GPU: GPU requested and available.")
          self.device = torch.device("cuda")
      else:
          logger.info(
              "NOT Using GPU: GPU not requested or not available."
          )
          self.device = torch.device("cpu")
  
      # NOTE: Because of the way we call AppendNet to squash ONNX to a C2 net,
      # We need to make tensors for every numeric literal
      self.zero_tensor = Parameter(
          torch.tensor([0.0], device=self.device), requires_grad=False
      )
      self.one_tensor = Parameter(
          torch.tensor([1.0], device=self.device), requires_grad=False
      )
      self.one_half_tensor = Parameter(
          torch.tensor([0.5], device=self.device), requires_grad=False
      )
      self.one_hundredth_tensor = Parameter(
          torch.tensor([0.01], device=self.device), requires_grad=False
      )
      self.negative_one_tensor = Parameter(
          torch.tensor([-1.0], device=self.device), requires_grad=False
      )
      self.min_tensor = Parameter(
          torch.tensor([-1e20], device=self.device), requires_grad=False
      )
      self.max_tensor = Parameter(
          torch.tensor([1e20], device=self.device), requires_grad=False
      )
      self.epsilon_tensor = Parameter(
          torch.tensor([EPS], device=self.device), requires_grad=False
      )
  
      self.feature_starts = self._get_type_boundaries()
      self.split_sections: List[int] = []
      for i, feature_type in enumerate(FEATURE_TYPES):
          begin_index = self.feature_starts[i]
          if (i + 1) == len(FEATURE_TYPES):
              end_index = len(self.normalization_parameters)
          else:
              end_index = self.feature_starts[i + 1]
          if begin_index == end_index:
              continue  # No features of this type
          if feature_type == ENUM:
              # Process one-at-a-time
              for j in range(begin_index, end_index):
                  enum_norm_params = self.normalization_parameters[
                      self.sorted_features[j]
                  ]
                  func = getattr(
                      self, "_create_parameters_" + feature_type
                  )
                  func(j, enum_norm_params)
                  self.split_sections.append(1)
          else:
              norm_params = []
              for f in self.sorted_features[begin_index:end_index]:
                  norm_params.append(self.normalization_parameters[f])
              func = getattr(self, "_create_parameters_" + feature_type)
              func(begin_index, norm_params)
              self.split_sections.append(end_index - begin_index)
  
imports: import logging
  from typing import cast, Dict, List, Optional, Tuple
  import torch
  from reagent.core.parameters import NormalizationParameters
  from reagent.preprocessing.identify_types import DO_NOT_PREPROCESS, ENUM, FEATURE_TYPES
  from reagent.preprocessing.normalization import EPS, MAX_FEATURE_VALUE, MIN_FEATURE_VALUE
  from torch.nn import Module, Parameter
label_desc: Use image node_id 1 to create a new Preprocessor object from inherited base classes: Module with example: obj = Preprocessor(normalization_parameters, use_gpu, device)