docstr: Forward computations from the mixture to the separated signals.
docstr_tok: ["Forward","computations","from","the","mixture","to","the","separated","signals","."]
code: def compute_forward(self, mix, targets, stage, noise=None):
      """Forward computations from the mixture to the separated signals."""
  
      # Unpack lists and put tensors in the right device
      mix, mix_lens = mix
      mix, mix_lens = mix.to(self.device), mix_lens.to(self.device)
  
      # Convert targets to tensor
      targets = torch.cat(
          [
              targets[i][0].unsqueeze(-1)
              for i in range(self.hparams.num_spks)
          ],
          dim=-1,
      ).to(self.device)
  
      # Add speech distortions
      if stage == sb.Stage.TRAIN:
          with torch.no_grad():
              if (
                  self.hparams.use_speedperturb
                  or self.hparams.use_rand_shift
              ):
                  mix, targets = self.add_speed_perturb(targets)
  
                  if self.hparams.use_reverb_augment:
                      targets_rev = [
                          self.hparams.reverb(targets[:, :, i], None)
                          for i in range(self.hparams.num_spks)
                      ]
                      targets_rev = torch.stack(targets_rev, dim=-1)
                      mix = targets_rev.sum(-1)
                  else:
                      mix = targets.sum(-1)
  
                  if self.hparams.use_wham_noise:
                      noise = noise.to(self.device)
                      len_noise = noise.shape[1]
                      len_mix = mix.shape[1]
                      min_len = min(len_noise, len_mix)
  
                      # add the noise
                      mix = mix[:, :min_len] + noise[:, :min_len]
  
                      # fix the length of targets also
                      targets = targets[:, :min_len, :]
  
              if self.hparams.use_wavedrop:
                  mix = self.hparams.drop_chunk(mix, mix_lens)
                  mix = self.hparams.drop_freq(mix)
  
              if self.hparams.limit_training_signal_len:
                  mix, targets = self.cut_signals(mix, targets)
  
      # randomly select the separator to use, and separate
      with torch.no_grad():
          separator_model = np.random.choice(self.all_separators)
          predictions = separator_model.separate_batch(mix)
  
      # normalize the separation results
      if hasattr(self.hparams, "separation_norm_type"):
          if self.hparams.separation_norm_type == "max":
              predictions = (
                  predictions / predictions.max(dim=1, keepdim=True)[0]
              )
              mix = mix / mix.max(dim=1, keepdim=True)[0]
  
          elif self.hparams.separation_norm_type == "stnorm":
              predictions = (
                  predictions - predictions.mean(dim=1, keepdim=True)
              ) / predictions.std(dim=1, keepdim=True)
              mix = (mix - mix.mean(dim=1, keepdim=True)) / mix.std(
                  dim=1, keepdim=True
              )
          else:
              raise ValueError("Unknown type of normalization")
  
      # calculate oracle sisnrs
      snr = self.compute_oracle_sisnrs(predictions, targets)
      snr = snr.to(self.device)
  
      # compress the si-snr values to 0-1 range
      if self.hparams.use_snr_compression:
          snr_compressed = self.compress_snrrange(snr)
      predictions = predictions.permute(0, 2, 1)
      predictions = predictions.reshape(-1, predictions.size(-1))
  
      # make sure signal lengths do not change
      min_T = min(predictions.shape[1], mix.shape[1])
      assert predictions.shape[1] == mix.shape[1], "lengths change"
  
      # concat the mixtures to the separation results
      mix_repeat = mix.repeat(2, 1)
      inp_cat = torch.cat(
          [
              predictions[:, :min_T].unsqueeze(1),
              mix_repeat[:, :min_T].unsqueeze(1),
          ],
          dim=1,
      )
  
      # get the encoder output and then calculate stats pooling
      enc = self.hparams.encoder(inp_cat)
      enc = enc.permute(0, 2, 1)
      enc_stats = self.hparams.stat_pooling(enc)
  
      # get the si-snr estimate by passing through the output layers
      snrhat = self.hparams.encoder_out(enc_stats).squeeze()
      return predictions, snrhat, snr, snr_compressed
  
imports: import os
  import sys
  import torch
  import speechbrain
  import speechbrain.nnet.schedulers
  from speechbrain.utils.distributed import run_on_main
  from hyperpyyaml import load_hyperpyyaml
  import itertools
  from tqdm import tqdm
  import numpy
  import logging
  import csv
  from speechbrain.core import AMPConfig
label_desc: Use image node_id 3 for calling the Separation obj's underlying member method code with example usage: obj.compute_forward(mix, targets, stage, noise) and returns: predictions,  snrhat,  snr,  snr_compressed