code: def train(self, train_params=None, optimizer_params=None):
      num_epochs = train_params["num_epochs"]
      num_early_stop = train_params["num_early_stop"]
      milestones = train_params["milestones"]
      gamma = train_params["gamma"]
  
      if optimizer_params is None:
          self.optimizer = Adam(self.model.parameters())
      else:
          self.optimizer = Adam(
              self.model.parameters(), **optimizer_params
          )
  
      if milestones is not None and gamma is not None:
          lr_schedule = MultiStepLR(
              self.optimizer, milestones=milestones, gamma=gamma
          )
      else:
          lr_schedule = None
  
      self.model.to(self.device)
      best_eval_acc = 0.0
      best_eval_loss = 0.0
      early_stop_counter = 0
      for epoch in range(num_epochs):
          is_best = False
          self.model.train()
          if self.graph_classification:
              losses = []
              for batch in self.loader["train"]:
                  batch = batch.to(self.device)
                  loss = self._train_batch(batch, batch.y)
                  losses.append(loss)
              train_loss = torch.FloatTensor(losses).mean().item()
  
          else:
              data = self.dataset.data.to(self.device)
              train_loss = self._train_batch(data, data.y)
  
          with torch.no_grad():
              eval_loss, eval_acc = self.eval()
          print(
              f"Epoch:{epoch}, Training_loss:{train_loss:.4f}, Eval_loss:{eval_loss:.4f}, Eval_acc:{eval_acc:.4f}"
          )
          if num_early_stop > 0:
              if eval_loss <= best_eval_loss:
                  best_eval_loss = eval_loss
                  early_stop_counter = 0
              else:
                  early_stop_counter += 1
              if (
                  epoch > num_epochs / 2
                  and early_stop_counter > num_early_stop
              ):
                  break
          if lr_schedule:
              lr_schedule.step()
  
          if best_eval_acc < eval_acc:
              is_best = True
              best_eval_acc = eval_acc
          recording = {"epoch": epoch, "is_best": str(is_best)}
          if self.save:
              self.save_model(is_best, recording=recording)
  
imports: import os
  import hydra
  import torch
  import shutil
  import warnings
  from torch.optim import Adam
  from omegaconf import OmegaConf
  from benchmarks.xgraph.utils import check_dir
  from benchmarks.xgraph.gnnNets import get_gnnNets
  from benchmarks.xgraph.dataset import get_dataset, get_dataloader
  import torch.nn.functional
  from torch.optim.lr_scheduler import MultiStepLR
  from utils import fix_random_seed
label_desc: Use image node_id 7 for calling the TrainModel obj's underlying member method code with example usage: obj.train(train_params, optimizer_params) without return types