text: import torch.nn.functional as F
  from ignite.contrib.handlers.param_scheduler import LinearCyclicalScheduler
  from ignite.handlers import ModelCheckpoint
  from ignite.metrics import Accuracy, Loss
  from torch import nn
  from torch.optim import SGD
  from torchvision.datasets import MNIST
  from torchvision.transforms import Compose, Normalize, ToTensor
  
  from pipelinex import NetworkTrain
  
  
  class Net(nn.Module):
      def __init__(self):
          super(Net, self).__init__()
          self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
          self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
          self.conv2_drop = nn.Dropout2d()
          self.fc1 = nn.Linear(320, 50)
          self.fc2 = nn.Linear(50, 10)
  
      def forward(self, x):
          x = F.relu(F.max_pool2d(self.conv1(x), 2))
          x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
          x = x.view(-1, 320)
          x = F.relu(self.fc1(x))
          x = F.dropout(x, training=self.training)
          x = self.fc2(x)
          return F.log_softmax(x, dim=-1)
  
  
  if __name__ == "__main__":
  
      train_params = {
          # loss_fn accepts a loss function at https://pytorch.org/docs/stable/nn.html#loss-functions
          "loss_fn": nn.NLLLoss(),
          # epochs accepts an integer
          "epochs": 2,
          # [Optional] seed (random seed) accepts an integer
          "seed": 42,
          # optimizer accepts optimizers at https://pytorch.org/docs/stable/optim.html
          "optimizer": SGD,
          # optimizer_params accepts parameters for the specified optimizer
          "optimizer_params": {"lr": 0.01, "momentum": 0.5},
          # train_data_loader_params accepts args at https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader
          "train_data_loader_params": {"batch_size": 64, "num_workers": 0},
          # val_data_loader_params accepts args at https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader
          "val_data_loader_params": {"batch_size": 1000, "num_workers": 0},
          # [Optional] evaluation_metrics accepts dict of metrics at https://pytorch.org/ignite/metrics.html
          "evaluation_metrics": {
              "accuracy": Accuracy(),
              "loss": Loss(loss_fn=nn.NLLLoss()),
          },
          # [Optional] evaluate_train_data (when to compute evaluation metrics using train_dataset)
          # accepts events at https://pytorch.org/ignite/engine.html#ignite.engine.Events
          "evaluate_train_data": "EPOCH_COMPLETED",
          # [Optional] evaluate_val_data (when to compute evaluation metrics using val_dataset)
          # accepts events at https://pytorch.org/ignite/engine.html#ignite.engine.Events
          "evaluate_val_data": "EPOCH_COMPLETED",
          # [Optional] progress_update (whether to show progress bar using tqdm package) accepts bool
          "progress_update": True,
          # [Optional] param scheduler at
          # https://pytorch.org/ignite/contrib/handlers.html#module-ignite.contrib.handlers.param_scheduler
          "scheduler": LinearCyclicalScheduler,
          # [Optional] scheduler_params accepts parameters for the specified scheduler
          "scheduler_params": {
              "param_name": "lr",
              "start_value": 0.001,
              "end_value": 0.01,
              "cycle_epochs": 2,
              "cycle_mult": 1.0,
              "start_value_mult": 1.0,
              "end_value_mult": 1.0,
              "save_history": False,
          },
          # [Optinal] ModelCheckpoint accepts a ModelCheckpoint at
          # https://pytorch.org/ignite/handlers.html#ignite.handlers.ModelCheckpoint
          "model_checkpoint": ModelCheckpoint,
          # [Optional] parameters for ModelCheckpoint
          "model_checkpoint_params": {
              "dirname": "../checkpoint",
              "filename_prefix": "model",
              "save_interval": None,
              "n_saved": 1,
              "atomic": True,
              "require_empty": False,
              "create_dir": True,
              "save_as_state_dict": True,
          },
          # [Optional] parameters for flexible version of EarlyStopping at
          # https://pytorch.org/ignite/handlers.html#ignite.handlers.EarlyStopping
          "early_stopping_params": {
              # metric (metric to monitor to determine whether to stop early) accepts str
              "metric": "loss",
              # minimize (if set to True, smaller metric value is considered better) accepts bool
              "minimize": True,
              # a parameter for ignite.handlers.EarlyStopping
              "patience": 1000,
              # a parameter for ignite.handlers.EarlyStopping
              "min_delta": 0.0,
              # a parameter for ignite.handlers.EarlyStopping
              "cumulative_delta": False,
          },
          # [Optional] time_limit (time limit for training in seconds) accepts an integer
          "time_limit": 3600,
          # [Optional] train_dataset_size_limit accepts an integer
          # "train_dataset_size_limit": 128,
          # [Optional] val_dataset_size_limit accepts an integer
          # "val_dataset_size_limit": 2000,
          # [Optional] mlflow_logging: If True and MLflow is installed, MLflow logging is enabled.
          "mlflow_logging": False,
      }
  
      nn_train = NetworkTrain(**train_params)
  
      data_transform = Compose([ToTensor(), Normalize((0.1307,), (0.3081,))])
      train_dataset = MNIST(download=True, root=".", transform=data_transform, train=True)
      val_dataset = MNIST(download=False, root=".", transform=data_transform, train=False)
  
      initial_model = Net()
  
      trained_model = nn_train(initial_model, train_dataset, val_dataset)
  