code: def training_step(
      self,
      batch: Tuple[List[Tensor], Tensor, List[str]],
      batch_idx: int,
  ) -> Tensor:
      # Normalize the prototypes so they are on the unit sphere.
      self.prototypes.normalize()
  
      # The dataloader returns a list of image crops where the
      # first few items are high resolution crops and the rest are low
      # resolution crops.
      multi_crops, targets = batch[0], batch[1]
  
      # Forward pass through backbone and projection head.
      multi_crop_features = [
          self.forward(crops).flatten(start_dim=1)
          for crops in multi_crops
      ]
      multi_crop_projections = [
          self.project(features) for features in multi_crop_features
      ]
  
      # Get the queue projections and logits.
      queue_crop_logits = None
      with torch.no_grad():
          if self.current_epoch >= self.start_queue_at_epoch:
              # Start filling the queue.
              queue_crop_projections = _update_queue(
                  projections=multi_crop_projections[: CROP_COUNTS[0]],
                  queues=self.queues,
              )
              if batch_idx > self.n_batches_in_queue:
                  # The queue is filled, so we can start using it.
                  queue_crop_logits = [
                      self.prototypes(
                          projections, step=self.current_epoch
                      )
                      for projections in queue_crop_projections
                  ]
  
      # Get the rest of the multi-crop logits.
      multi_crop_logits = [
          self.prototypes(projections, step=self.current_epoch)
          for projections in multi_crop_projections
      ]
  
      # Calculate the SwAV loss.
      loss = self.criterion(
          high_resolution_outputs=multi_crop_logits[: CROP_COUNTS[0]],
          low_resolution_outputs=multi_crop_logits[CROP_COUNTS[0] :],
          queue_outputs=queue_crop_logits,
      )
      self.log(
          "train_loss",
          loss,
          prog_bar=True,
          sync_dist=True,
          batch_size=len(targets),
      )
  
      # Calculate the classification loss.
      cls_loss, cls_log = self.online_classifier.training_step(
          (multi_crop_features[0].detach(), targets), batch_idx
      )
      self.log_dict(cls_log, sync_dist=True, batch_size=len(targets))
      return loss + cls_loss
  
imports: import math
  from typing import List, Tuple
  import torch
  from pytorch_lightning import LightningModule
  from torch import Tensor
  from torch.nn import Identity, ModuleList
  from torch.nn import functional
  from torchvision.models import resnet50
  from lightly.loss.swav_loss import SwaVLoss
  from lightly.models.modules import SwaVProjectionHead, SwaVPrototypes
  from lightly.models.modules.memory_bank import MemoryBankModule
  from lightly.models.utils import get_weight_decay_parameters
  from lightly.transforms import SwaVTransform
  from lightly.utils.benchmarking import OnlineLinearClassifier
  from lightly.utils.lars import LARS
  from lightly.utils.scheduler import CosineWarmupScheduler
label_desc: Use image node_id 4 for calling the SwAV obj's underlying member method code with example usage: obj.training_step(batch, batch_idx) and returns: unknown