docstr: This script computes the SDR and SI-SNR metrics and saves
  them into a csv file
docstr_tok: ["This","script","computes","the","SDR","and","SI-SNR","metrics","and","saves","them","into","a","csv","file"]
code: def save_results(self, test_data):
      """This script computes the SDR and SI-SNR metrics and saves
      them into a csv file"""
  
      # This package is required for SDR computation
      from mir_eval.separation import bss_eval_sources
  
      # Create folders where to store audio
      save_file = os.path.join(
          self.hparams.output_folder, "test_results.csv"
      )
  
      # Variable init
      all_sdrs = []
      all_sdrs_i = []
      all_sisnrs = []
      all_sisnrs_i = []
      all_pesqs = []
      csv_columns = [
          "snt_id",
          "sdr",
          "sdr_i",
          "si-snr",
          "si-snr_i",
          "pesq",
      ]
  
      test_loader = sb.dataio.dataloader.make_dataloader(
          test_data, **self.hparams.dataloader_opts
      )
  
      with open(save_file, "w") as results_csv:
          writer = csv.DictWriter(results_csv, fieldnames=csv_columns)
          writer.writeheader()
  
          # Loop over all test sentence
          with tqdm(test_loader, dynamic_ncols=True) as t:
              for i, batch in enumerate(t):
                  # Apply Separation
                  mixture, mix_len = batch.mix_sig
                  snt_id = batch.id
                  targets = [batch.s1_sig, batch.s2_sig]
                  if self.hparams.num_spks == 3:
                      targets.append(batch.s3_sig)
  
                  with torch.no_grad():
                      predictions, targets = self.compute_forward(
                          batch.mix_sig, targets, sb.Stage.TEST
                      )
  
                  # Compute SI-SNR
                  sisnr = self.compute_objectives(predictions, targets)
  
                  # Compute SI-SNR improvement
                  mixture_signal = torch.stack(
                      [mixture] * self.hparams.num_spks, dim=-1
                  )
                  mixture_signal = mixture_signal.to(targets.device)
                  mix_w = self.compute_feats(mixture_signal.squeeze(-1))
                  sisnr_baseline = self.compute_objectives(
                      [mixture_signal.squeeze(-1), mix_w], targets
                  )
                  sisnr_i = sisnr - sisnr_baseline
  
                  # Compute SDR
                  sdr, _, _, _ = bss_eval_sources(
                      targets[0].t().cpu().numpy(),
                      predictions[0][0].t().detach().cpu().numpy(),
                  )
  
                  sdr_baseline, _, _, _ = bss_eval_sources(
                      targets[0].t().cpu().numpy(),
                      mixture_signal[0].t().detach().cpu().numpy(),
                  )
  
                  sdr_i = sdr.mean() - sdr_baseline.mean()
  
                  # Compute PESQ
                  psq_mode = (
                      "wb"
                      if self.hparams.sample_rate == 16000
                      else "nb"
                  )
                  psq = pesq(
                      self.hparams.sample_rate,
                      targets.squeeze().cpu().numpy(),
                      predictions[0].squeeze().cpu().numpy(),
                      mode=psq_mode,
                  )
  
                  # Saving on a csv file
                  row = {
                      "snt_id": snt_id[0],
                      "sdr": sdr.mean(),
                      "sdr_i": sdr_i,
                      "si-snr": -sisnr.item(),
                      "si-snr_i": -sisnr_i.item(),
                      "pesq": psq,
                  }
                  writer.writerow(row)
  
                  # Metric Accumulation
                  all_sdrs.append(sdr.mean())
                  all_sdrs_i.append(sdr_i.mean())
                  all_sisnrs.append(-sisnr.item())
                  all_sisnrs_i.append(-sisnr_i.item())
                  all_pesqs.append(psq)
  
              row = {
                  "snt_id": "avg",
                  "sdr": np.array(all_sdrs).mean(),
                  "sdr_i": np.array(all_sdrs_i).mean(),
                  "si-snr": np.array(all_sisnrs).mean(),
                  "si-snr_i": np.array(all_sisnrs_i).mean(),
                  "pesq": np.array(all_pesqs).mean(),
              }
              writer.writerow(row)
  
      logger.info(
          "Mean SISNR is {}".format(np.array(all_sisnrs).mean())
      )
      logger.info(
          "Mean SISNRi is {}".format(np.array(all_sisnrs_i).mean())
      )
      logger.info("Mean SDR is {}".format(np.array(all_sdrs).mean()))
      logger.info("Mean SDRi is {}".format(np.array(all_sdrs_i).mean()))
      logger.info("Mean PESQ {}".format(np.array(all_pesqs).mean()))
  
imports: import os
  import sys
  import torch
  import torch.nn.functional
  import torchaudio
  import speechbrain
  import speechbrain.nnet.schedulers
  from speechbrain.utils.distributed import run_on_main
  from hyperpyyaml import load_hyperpyyaml
  import numpy
  from tqdm import tqdm
  import csv
  import logging
  from speechbrain.processing.features import spectral_magnitude
  from speechbrain.utils.metric_stats import MetricStats
  from pesq import pesq
  from speechbrain.core import AMPConfig
label_desc: Use image node_id 11 for calling the Separation obj's underlying member method code with example usage: obj.save_results(test_data) without return types