code: def __call__(
      self,
      net: nn.Module,
      train_iter: DataLoader,
      validation_iter: Optional[DataLoader] = None,
  ) -> None:
      optimizer = Adam(
          net.parameters(),
          lr=self.learning_rate,
          weight_decay=self.weight_decay,
      )
  
      lr_scheduler = OneCycleLR(
          optimizer,
          max_lr=self.maximum_learning_rate,
          steps_per_epoch=self.num_batches_per_epoch,
          epochs=self.epochs,
      )
  
      for epoch_no in range(self.epochs):
          # mark epoch start time
          tic = time.time()
          cumm_epoch_loss = 0.0
          total = self.num_batches_per_epoch - 1
  
          # training loop
          with tqdm(train_iter, total=total) as it:
              for batch_no, data_entry in enumerate(it, start=1):
                  optimizer.zero_grad()
                  inputs = []
                  for v in data_entry.values():
                      if v.ndim >= 4:
                          v = v.reshape(v.shape[:3])
                      inputs.append(v.to(self.device))
                  # inputs = [v.to(self.device) for v in data_entry.values()]
  
                  output = net(*inputs)
  
                  if isinstance(output, (list, tuple)):
                      loss = output[0]
                  else:
                      loss = output
  
                  cumm_epoch_loss += loss.item()
                  avg_epoch_loss = cumm_epoch_loss / batch_no
                  it.set_postfix(
                      {
                          "epoch": f"{epoch_no + 1}/{self.epochs}",
                          "avg_loss": avg_epoch_loss,
                      },
                      refresh=False,
                  )
  
                  loss.backward()
                  if self.clip_gradient is not None:
                      nn.utils.clip_grad_norm_(
                          net.parameters(), self.clip_gradient
                      )
  
                  optimizer.step()
                  lr_scheduler.step()
  
                  if self.num_batches_per_epoch == batch_no:
                      break
              it.close()
  
          # validation loop
          if validation_iter is not None:
              cumm_epoch_loss_val = 0.0
              with tqdm(
                  validation_iter, total=total, colour="green"
              ) as it:
                  for batch_no, data_entry in enumerate(it, start=1):
                      inputs = [
                          v.to(self.device) for v in data_entry.values()
                      ]
                      with torch.no_grad():
                          output = net(*inputs)
                      if isinstance(output, (list, tuple)):
                          loss = output[0]
                      else:
                          loss = output
  
                      cumm_epoch_loss_val += loss.item()
                      avg_epoch_loss_val = (
                          cumm_epoch_loss_val / batch_no
                      )
                      it.set_postfix(
                          {
                              "epoch": f"{epoch_no + 1}/{self.epochs}",
                              "avg_loss": avg_epoch_loss,
                              "avg_val_loss": avg_epoch_loss_val,
                          },
                          refresh=False,
                      )
  
                      if self.num_batches_per_epoch == batch_no:
                          break
  
              it.close()
  
          # mark epoch end time and log time cost of current epoch
          toc = time.time()
  
file_path: gluonts/src/gluonts/nursery/robust-mts-attack/pts/trainer.py
imports: import time
  from typing import List, Optional, Union
  from tqdm.auto import tqdm
  import torch
  import torch.nn
  from torch.optim import Adam
  from torch.optim.lr_scheduler import OneCycleLR
  from torch.utils.data import DataLoader
  from gluonts.core.component import validated
label_desc: Use image node_id 2 for calling the Trainer obj's underlying member method code with example usage: obj.__call__(net, train_iter, validation_iter) without return types