class_docstr: A latent diffusion wrapper. Latent diffusion is denoising diffusion
  applied to a latent space instead of the original data space
  
  Arguments
  ---------
  autoencoder: speechbrain.nnet.autoencoders.Autoencoder
      An autoencoder converting the original space to a latent space
  
  diffusion: speechbrian.nnet.diffusion.Diffuser
      A diffusion wrapper
  
  latent_downsample_factor: int
      The factor that latent space dimensions need to be divisible
      by. This is useful if the underlying model for the diffusion
      wrapper is based on a UNet-like architecture where the inputs
      are progressively downsampled and upsampled by factors of two
  
  latent_pad_dims: int|list[int]
      the dimension(s) along which the latent space will be
      padded
  
  Example
  -------
  >>> import torch
  >>> from torch import nn
  >>> from speechbrain.nnet.CNN import Conv2d
  >>> from speechbrain.nnet.autoencoders import NormalizingAutoencoder
  >>> from speechbrain.nnet.unet import UNetModel
  
  Set up a simple autoencoder (a real autoencoder would be a
  deep neural network)
  
  >>> ae_enc = Conv2d(
  ...     kernel_size=3,
  ...     stride=4,
  ...     in_channels=1,
  ...     out_channels=1,
  ...     skip_transpose=True,
  ... )
  >>> ae_dec = nn.ConvTranspose2d(
  ...     kernel_size=3,
  ...     stride=4,
  ...     in_channels=1,
  ...     out_channels=1,
  ...     output_padding=1
  ... )
  >>> ae = NormalizingAutoencoder(
  ...     encoder=ae_enc,
  ...     decoder=ae_dec,
  ... )
  
  Construct a diffusion model with a UNet architecture
  
  >>> unet = UNetModel(
  ...     in_channels=1,
  ...     model_channels=16,
  ...     norm_num_groups=4,
  ...     out_channels=1,
  ...     num_res_blocks=1,
  ...     attention_resolutions=[]
  ... )
  >>> diff = DenoisingDiffusion(
  ...     model=unet,
  ...     timesteps=5
  ... )
  >>> latent_diff = LatentDiffusion(
  ...     autoencoder=ae,
  ...     diffusion=diff,
  ...     latent_downsample_factor=4,
  ...     latent_pad_dim=2
  ... )
  >>> x = torch.randn(4, 1, 64, 64)
  >>> latent_sample = latent_diff.train_sample_latent(x)
  >>> diff_sample, ae_sample = latent_sample
  >>> pred, noise, noisy_sample = diff_sample
  >>> pred.shape
  torch.Size([4, 1, 16, 16])
  >>> noise.shape
  torch.Size([4, 1, 16, 16])
  >>> noisy_sample.shape
  torch.Size([4, 1, 16, 16])
  >>> ae_sample.latent.shape
  torch.Size([4, 1, 16, 16])
  
  Create a few samples (the shape given should be the shape
  of the latent space)
  
  >>> sample = latent_diff.sample((2, 1, 16, 16))
  >>> sample.shape
  torch.Size([2, 1, 64, 64])
docstr: Adds noise to the sample, in a forward diffusion process,
  
  Arguments
  ---------
  x: torch.Tensor
      a data sample of 2 or more dimensions, with the
      first dimension representing the batch
  noise: torch.Tensor
      the noise to add
  timesteps: torch.Tensor
      a 1-D integer tensor of a length equal to the number of
      batches in x, where each entry corresponds to the timestep
      number for the batch. If omitted, timesteps will be randomly
      sampled
  
  Returns
  -------
  result: torch.Tensor
      a tensor of the same dimension as x
code: def distort(self, x):
      """Adds noise to the sample, in a forward diffusion process,
  
      Arguments
      ---------
      x: torch.Tensor
          a data sample of 2 or more dimensions, with the
          first dimension representing the batch
      noise: torch.Tensor
          the noise to add
      timesteps: torch.Tensor
          a 1-D integer tensor of a length equal to the number of
          batches in x, where each entry corresponds to the timestep
          number for the batch. If omitted, timesteps will be randomly
          sampled
  
      Returns
      -------
      result: torch.Tensor
          a tensor of the same dimension as x
      """
  
      latent = self.autencoder.encode(x)
      return self.diffusion.distort(latent)
  
imports: from collections import namedtuple
  import torch
  from torch import nn
  from torch.nn import functional
  from tqdm.auto import tqdm
  from speechbrain.utils.data_utils import unsqueeze_as
  from speechbrain.dataio.dataio import length_to_mask
  from speechbrain.utils import data_utils
label_desc: Use image node_id 5 for calling the LatentDiffusion obj's underlying member method code with example usage: obj.distort(x) and returns: self