class_docstr: The MLP surrogate predicts a model's performance on a new dataset using an
  MLP.
  
  The MLP converts inputs into feature vectors of the same size and uses
  either ranking or regression to predict metrics.
code: def _predict(
      self, X: List[Config[ModelConfig]]
  ) -> npt.NDArray[np.float32]:
      # Get data
      X_numpy = self.config_transformer.transform(X)
      dataset = TensorDataset(
          torch.from_numpy(X_numpy).float(),
          torch.zeros(len(X_numpy)),  # dummy data due to PL bug
      )
      test_loader = DataLoader(dataset, batch_size=len(dataset))
  
      # Run prediction
      predictions = []
      for model in self.models_:
          module = MLPLightningModule(model, self.loss)
          out = cast(
              List[torch.Tensor],
              self._trainer.predict(module, test_loader),
          )
          predictions.append(out[0].numpy())
  
      return np.concatenate(predictions, axis=-1)
  
imports: from typing import cast, List, Literal, Optional
  import numpy
  import numpy.typing
  import pytorch_lightning
  import torch
  from lightkit.data import DataLoader
  from torch import nn
  from torch.utils.data import TensorDataset
  from tsbench.config import Config, ModelConfig
  from tsbench.evaluations.tracking import ModelTracker
  from ._base import DatasetFeaturesMixin, OutputNormalization, Surrogate
  from ._factory import register_surrogate
  from .torch import ListMLELoss, MLPLightningModule
  from .transformers import ConfigTransformer
label_desc: Use image node_id 4 for calling the MLPSurrogate obj's underlying member method code with example usage: obj._predict(X) and returns: np