class_docstr: Trainer using distinct optimizers for the encoder, decoder and discriminator.
  
  Args:
      model (BaseAE): The model to train
  
      train_dataset (BaseDataset): The training dataset of type
          :class:`~pythae.data.dataset.BaseDataset`
  
      training_args (CoupledOptimizerAdversarialTrainerConfig): The training arguments summarizing
          the main parameters used for training. If None, a basic training instance of
          :class:`AdversarialTrainerConfig` is used. Default: None.
  
      encoder_optimizer (~torch.optim.Optimizer): An instance of `torch.optim.Optimizer`
          used for training the encoder. If None, a :class:`~torch.optim.Adam` optimizer is
          used. Default: None.
  
      decoder_optimizer (~torch.optim.Optimizer): An instance of `torch.optim.Optimizer`
          used for training the decoder. If None, a :class:`~torch.optim.Adam` optimizer is
          used. Default: None.
  
      discriminator_optimizer (~torch.optim.Optimizer): An instance of `torch.optim.Optimizer`
          used for training the discriminator. If None, a :class:`~torch.optim.Adam` optimizer is
          used. Default: None.
docstr: The trainer performs training loop over the train_loader.
  
  Parameters:
      epoch (int): The current epoch number
  
  Returns:
      (torch.Tensor): The step training loss
docstr_tok: ["The","trainer","performs","training","loop","over","the","train_loader",".","Parameters",":","epoch","(","int",")",":","The","current","epoch","number","Returns",":","(","torch.Tensor",")",":","The","step","training","loss"]
code: def train_step(self, epoch: int):
      """The trainer performs training loop over the train_loader.
  
      Parameters:
          epoch (int): The current epoch number
  
      Returns:
          (torch.Tensor): The step training loss
      """
      self.callback_handler.on_train_step_begin(
          training_config=self.training_config,
          train_loader=self.train_loader,
          epoch=epoch,
          rank=self.rank,
      )
  
      # set model in train model
      self.model.train()
  
      epoch_encoder_loss = 0
      epoch_decoder_loss = 0
      epoch_discriminator_loss = 0
      epoch_loss = 0
  
      for inputs in self.train_loader:
          inputs = self._set_inputs_to_device(inputs)
  
          model_output = self.model(
              inputs,
              epoch=epoch,
              dataset_size=len(self.train_loader.dataset),
              uses_ddp=self.distributed,
          )
  
          self._optimizers_step(model_output)
  
          encoder_loss = model_output.encoder_loss
          decoder_loss = model_output.decoder_loss
          discriminator_loss = model_output.discriminator_loss
  
          loss = encoder_loss + decoder_loss + discriminator_loss
  
          epoch_encoder_loss += encoder_loss.item()
          epoch_decoder_loss += decoder_loss.item()
          epoch_discriminator_loss += discriminator_loss.item()
          epoch_loss += loss.item()
  
          self.callback_handler.on_train_step_end(
              training_config=self.training_config
          )
  
      # Allows model updates if needed
      if self.distributed:
          self.model.module.update()
      else:
          self.model.update()
  
      epoch_encoder_loss /= len(self.train_loader)
      epoch_decoder_loss /= len(self.train_loader)
      epoch_discriminator_loss /= len(self.train_loader)
      epoch_loss /= len(self.train_loader)
  
      return (
          epoch_loss,
          epoch_encoder_loss,
          epoch_decoder_loss,
          epoch_discriminator_loss,
      )
  
imports: import datetime
  import dis
  import logging
  import os
  from copy import deepcopy
  from typing import List, Optional
  import torch
  import torch.distributed
  import torch.optim
  import torch.optim.lr_scheduler
  from ...data.datasets import BaseDataset
  from ...models import BaseAE
  from ..base_trainer import BaseTrainer
  from ..trainer_utils import set_seed
  from ..training_callbacks import TrainingCallback
  from .coupled_optimizer_adversarial_trainer_config import CoupledOptimizerAdversarialTrainerConfig
label_desc: Use image node_id 13 for calling the CoupledOptimizerAdversarialTrainer obj's underlying member method code with example usage: obj.train_step(epoch) and returns: epoch_loss,  epoch_encoder_loss,  epoch_decoder_loss,  epoch_discriminator_loss