code: def train(
      train_loader,
      epoch,
      model1,
      optimizer1,
      model2,
      optimizer2,
      args,
      forget_rate_schedule,
      class_weights,
      accuracy,
  ):
      """PyTorch training function.
  
      Parameters
      ----------
      train_loader : torch.utils.data.DataLoader
      epoch : int
      model1 : PyTorch class inheriting nn.Module
          Must define __init__ and forward(self, x,)
      optimizer1 : PyTorch torch.optim.Adam
      model2 : PyTorch class inheriting nn.Module
          Must define __init__ and forward(self, x,)
      optimizer2 : PyTorch torch.optim.Adam
      args : parser.parse_args() object
          Must contain num_iter_per_epoch, print_freq, and epochs
      forget_rate_schedule : np.ndarray of length number of epochs
          Tells Co-Teaching loss what fraction of examples to forget about.
      class_weights : Tensor array, shape (Number of classes x 1), Default: None
        A np.torch.tensor list of length number of classes with weights
      accuracy : function
          A function of the form accuracy(output, target, topk=(1,)) for
          computing top1 and top5 accuracy given output and true targets.
      """
  
      train_total = 0
      train_correct = 0
      train_total2 = 0
      train_correct2 = 0
  
      # Prepare models for training
      model1.train()
      model2.train()
  
      for i, (images, labels) in enumerate(train_loader):
          if (
              i == len(train_loader) - 1
              and len(labels) < MINIMUM_BATCH_SIZE
          ):
              # Edge case -- the last leftover batch is small (potentially size 1)
              # This will happen if, for example, you train on 35101 examples with
              # batch size of 450. The last batch will be size 1.
              # If you update the weights based on the gradient from one example
              # if that example is noisy, you will add tons of noise to your net
              # and accuracy will actually go down with each epoch.
              # To avoid this, do not train on the last batch if it's small.
              continue
  
          images = Variable(images).cuda()
          labels = Variable(labels).cuda()
  
          # Forward + Backward + Optimize
          logits1 = model1(images)
          prec1, _ = accuracy(logits1, labels, topk=(1, 5))
          train_total += 1
          train_correct += prec1
          logits2 = model2(images)
          prec2, _ = accuracy(logits2, labels, topk=(1, 5))
          train_total2 += 1
          train_correct2 += prec2
          loss_1, loss_2 = loss_coteaching(
              logits1,
              logits2,
              labels,
              forget_rate=forget_rate_schedule[epoch],
              class_weights=class_weights,
          )
          optimizer1.zero_grad()
          loss_1.backward()
          optimizer1.step()
          optimizer2.zero_grad()
          loss_2.backward()
          optimizer2.step()
          if (i + 1) % args.print_freq == 0:
              print(
                  "Epoch [%d/%d], Iter [%d/%d] Training Accuracy1: %.4F, "
                  "Training Accuracy2: %.4f, Loss1: %.4f, Loss2: %.4f "
                  % (
                      epoch + 1,
                      args.epochs,
                      i + 1,
                      len(train_loader.dataset) // args.batch_size,
                      prec1,
                      prec2,
                      loss_1.data.item(),
                      loss_2.data.item(),
                  )
              )
  
      train_acc1 = float(train_correct) / float(train_total)
      train_acc2 = float(train_correct2) / float(train_total2)
      return train_acc1, train_acc2
  
file_path: cleanlab/cleanlab/experimental/coteaching.py
imports: import torch
  import torch.nn.functional
  from torch.autograd import Variable
  import numpy
label_desc: Use image node_id 5 for calling a global function with example usage: train(train_loader, epoch, model1, optimizer1, model2, optimizer2, args, forget_rate_schedule, class_weights, accuracy) and returns: train_acc1,  train_acc2