class_docstr: FactorVAE model.
  
  Args:
      model_config (FactorVAEConfig): The Variational Autoencoder configuration setting the main
          parameters of the model.
  
      encoder (BaseEncoder): An instance of BaseEncoder (inheriting from `torch.nn.Module` which
          plays the role of encoder. This argument allows you to use your own neural networks
          architectures if desired. If None is provided, a simple Multi Layer Preception
          (https://en.wikipedia.org/wiki/Multilayer_perceptron) is used. Default: None.
  
      decoder (BaseDecoder): An instance of BaseDecoder (inheriting from `torch.nn.Module` which
          plays the role of decoder. This argument allows you to use your own neural networks
          architectures if desired. If None is provided, a simple Multi Layer Preception
          (https://en.wikipedia.org/wiki/Multilayer_perceptron) is used. Default: None.
  
  
  .. note::
      For high dimensional data we advice you to provide you own network architectures. With the
      provided MLP you may end up with a ``MemoryError``.
class_docstr_tok: ["FactorVAE","model",".","Args",":","model_config","(","FactorVAEConfig",")",":","The","Variational","Autoencoder","configuration","setting","the","main","parameters","of","the","model",".","encoder","(","BaseEncoder",")",":","An","instance","of","BaseEncoder","(","inheriting","from","`","torch.nn.Module","`","which","plays","the","role","of","encoder",".","This","argument","allows","you","to","use","your","own","neural","networks","architectures","if","desired",".","If","None","is","provided",",","a","simple","Multi","Layer","Preception","(","https",":","\/\/en.wikipedia.org\/wiki\/Multilayer_perceptron",")","is","used",".","Default",":","None",".","decoder","(","BaseDecoder",")",":","An","instance","of","BaseDecoder","(","inheriting","from","`","torch.nn.Module","`","which","plays","the","role","of","decoder",".","This","argument","allows","you","to","use","your","own","neural","networks","architectures","if","desired",".","If","None","is","provided",",","a","simple","Multi","Layer","Preception","(","https",":","\/\/en.wikipedia.org\/wiki\/Multilayer_perceptron",")","is","used",".","Default",":","None",".","..","note",":",":","For","high","dimensional","data","we","advice","you","to","provide","you","own","network","architectures",".","With","the","provided","MLP","you","may","end","up","with","a","``","MemoryError","``","."]
docstr: The VAE model
  
  Args:
      inputs (BaseDataset): The training dataset with labels
  
  Returns:
      ModelOutput: An instance of ModelOutput containing all the relevant parameters
docstr_tok: ["The","VAE","model","Args",":","inputs","(","BaseDataset",")",":","The","training","dataset","with","labels","Returns",":","ModelOutput",":","An","instance","of","ModelOutput","containing","all","the","relevant","parameters"]
code: def forward(self, inputs: BaseDataset, **kwargs) -> ModelOutput:
      """
      The VAE model
  
      Args:
          inputs (BaseDataset): The training dataset with labels
  
      Returns:
          ModelOutput: An instance of ModelOutput containing all the relevant parameters
  
      """
      x_in = inputs["data"]
      if x_in.shape[0] <= 1:
          raise ArithmeticError(
              "At least 2 samples in a batch are required for the `FactorVAE` model"
          )
  
      idx = torch.randperm(x_in.shape[0])
      idx_1 = idx[int(x_in.shape[0] / 2) :]
      idx_2 = idx[: int(x_in.shape[0] / 2)]
  
      # first batch
      x = inputs["data"][idx_1]
  
      encoder_output = self.encoder(x)
  
      mu, log_var = (
          encoder_output.embedding,
          encoder_output.log_covariance,
      )
  
      std = torch.exp(0.5 * log_var)
      z, _ = self._sample_gauss(mu, std)
      recon_x = self.decoder(z)["reconstruction"]
  
      # second batch
      x_bis = inputs["data"][idx_2]
  
      encoder_output = self.encoder(x_bis)
  
      mu_bis, log_var_bis = (
          encoder_output.embedding,
          encoder_output.log_covariance,
      )
  
      std_bis = torch.exp(0.5 * log_var_bis)
      z_bis, _ = self._sample_gauss(mu_bis, std_bis)
  
      z_bis_permuted = self._permute_dims(z_bis).detach()
  
      (
          recon_loss,
          autoencoder_loss,
          discriminator_loss,
      ) = self.loss_function(recon_x, x, mu, log_var, z, z_bis_permuted)
  
      loss = autoencoder_loss + discriminator_loss
  
      output = ModelOutput(
          loss=loss,
          recon_loss=recon_loss,
          autoencoder_loss=autoencoder_loss,
          discriminator_loss=discriminator_loss,
          recon_x=recon_x,
          recon_x_indices=idx_1,
          z=z,
          z_bis_permuted=z_bis_permuted,
      )
  
      return output
  
imports: import os
  from typing import Optional
  import torch
  import torch.nn.functional
  from ...customexception import BadInheritanceError
  from ...data.datasets import BaseDataset
  from ..base.base_utils import ModelOutput
  from ..nn import BaseDecoder, BaseDiscriminator, BaseEncoder
  from ..vae import VAE
  from .factor_vae_config import FactorVAEConfig
  from .factor_vae_utils import FactorVAEDiscriminator
label_desc: Use image node_id 3 for calling the FactorVAE obj's underlying member method code with example usage: obj.forward(inputs) and returns: output