class_docstr: Implements a basic GAN for the purpose of illustrating multiple optimizers.
code: def training_step(self, batch, batch_idx):
      imgs, _ = batch
      self.last_imgs = imgs
  
      optimizer1, optimizer2 = self.optimizers()
  
      # train generator
      # sample noise
      self.toggle_optimizer(optimizer1)
      z = torch.randn(imgs.shape[0], self.hidden_dim)
      z = z.type_as(imgs)
  
      # generate images
      self.generated_imgs = self(z)
  
      # ground truth result (ie: all fake)
      # put on GPU because we created this tensor inside training_loop
      valid = torch.ones(imgs.size(0), 1)
      valid = valid.type_as(imgs)
  
      # adversarial loss is binary cross-entropy
      g_loss = self.adversarial_loss(
          self.discriminator(self.generated_imgs), valid
      )
      self.log("g_loss", g_loss, prog_bar=True, logger=True)
      self.manual_backward(g_loss)
      optimizer1.step()
      optimizer1.zero_grad()
      self.untoggle_optimizer(optimizer1)
  
      # train discriminator
      # Measure discriminator's ability to classify real from generated samples
      self.toggle_optimizer(optimizer2)
      # how well can it label as real?
      valid = torch.ones(imgs.size(0), 1)
      valid = valid.type_as(imgs)
  
      real_loss = self.adversarial_loss(self.discriminator(imgs), valid)
  
      # how well can it label as fake?
      fake = torch.zeros(imgs.size(0), 1)
      fake = fake.type_as(fake)
  
      fake_loss = self.adversarial_loss(
          self.discriminator(self.generated_imgs.detach()), fake
      )
  
      # discriminator loss is the average of these
      d_loss = (real_loss + fake_loss) / 2
      self.log("d_loss", d_loss, prog_bar=True, logger=True)
      self.manual_backward(d_loss)
      optimizer2.step()
      optimizer2.zero_grad()
      self.untoggle_optimizer(optimizer2)
  
imports: import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from lightning.pytorch.core.module import LightningModule
  from torch.utils.data import DataLoader
  from tests_pytorch import _PATH_DATASETS
  from tests_pytorch.helpers.datasets import MNIST, AverageDataset, TrialMNIST
label_desc: Use image node_id 4 for calling the BasicGAN obj's underlying member method code with example usage: obj.training_step(batch, batch_idx) without return types