code: def training(self, epoch):
      tbar = tqdm(self.train_data)
      train_loss = 0.0
      for i, (data, target) in enumerate(tbar):
          with autograd.record(True):
              outputs = self.net(data.astype(args.dtype, copy=False))
              losses = self.criterion(outputs, target)
              mx.nd.waitall()
              autograd.backward(losses)
          self.optimizer.step(self.args.batch_size)
          for loss in losses:
              train_loss += np.mean(loss.asnumpy()) / len(losses)
          tbar.set_description(
              "Epoch %d, training loss %.3f"
              % (epoch, train_loss / (i + 1))
          )
          if i != 0 and i % self.args.log_interval == 0:
              self.logger.info(
                  "Epoch %d iteration %04d/%04d: training loss %.3f"
                  % (
                      epoch,
                      i,
                      len(self.train_data),
                      train_loss / (i + 1),
                  )
              )
          mx.nd.waitall()
  
      # save every epoch
      if self.args.no_val:
          save_checkpoint(self.net.module, self.args, epoch, 0, False)
  
imports: import os
  import logging
  import shutil
  import argparse
  import numpy
  from tqdm import tqdm
  import mxnet
  from mxnet import gluon, autograd
  from mxnet.gluon.data.vision import transforms
  import gluoncv
  from gluoncv.loss import *
  from gluoncv.utils import makedirs, LRScheduler, LRSequential
  from gluoncv.model_zoo.segbase import *
  from gluoncv.model_zoo import get_model
  from gluoncv.utils.parallel import *
  from gluoncv.data import get_segmentation_dataset
label_desc: Use image node_id 2 for calling the Trainer obj's underlying member method code with example usage: obj.training(epoch) without return types