class_docstr: ASV Spoofing model
  A simple ASV Spoofing model
class_docstr_tok: ["ASV","Spoofing","model","A","simple","ASV","Spoofing","model"]
docstr: Frontend + Encoder + Decoder + Calc loss
  Args:
      speech: (Batch, samples)
      spk_labels: (Batch, )
      kwargs: "utt_id" is among the input.
docstr_tok: ["Frontend","+","Encoder","+","Decoder","+","Calc","loss","Args",":","speech",":","(","Batch",",","samples",")","spk_labels",":","(","Batch",",",")","kwargs",":","``","utt_id","''","is","among","the","input","."]
code: def forward(
      self,
      speech: torch.Tensor,
      speech_lengths: torch.Tensor = None,
      label: torch.Tensor = None,
      **kwargs,
  ) -> Tuple[torch.Tensor, Dict[str, torch.Tensor], torch.Tensor]:
      """Frontend + Encoder + Decoder + Calc loss
      Args:
          speech: (Batch, samples)
          spk_labels: (Batch, )
          kwargs: "utt_id" is among the input.
      """
      assert speech.shape[0] == label.shape[0], (
          speech.shape,
          label.shape,
      )
      batch_size = speech.shape[0]
  
      # 1. Encoder
      encoder_out, encoder_out_lens = self.encode(
          speech, speech_lengths
      )
  
      # 2. Decoder (baiscally a predction layer after encoder_out)
      pred = self.decoder(encoder_out, encoder_out_lens)
  
      if "oc_softmax_loss" in self.losses:
          loss = (
              self.losses["oc_softmax_loss"](label, encoder_out)
              * self.losses["oc_softmax_loss"].weight
          )
          pred = self.losses["am_softmax_loss"].score(encoder_out)
      elif "am_softmax_loss" in self.losses:
          loss = (
              self.losses["am_softmax_loss"](label, encoder_out)
              * self.losses["am_softmax_loss"].weight
          )
          pred = self.losses["am_softmax_loss"].score(encoder_out)
      else:
          loss = (
              self.losses["binary_loss"](pred, label)
              * self.losses["binary_loss"].weight
          )
      acc = (
          torch.sum(((pred.view(-1) > 0.5) == (label.view(-1) > 0.5)))
          / batch_size
      )
  
      stats = dict(
          loss=loss.detach(),
          acc=acc.detach(),
      )
  
      loss, stats, weight = force_gatherable(
          (loss, stats, batch_size), loss.device
      )
      return loss, stats, weight
  
imports: import logging
  from contextlib import contextmanager
  from itertools import permutations
  from typing import Dict, Optional, Tuple
  import numpy
  import torch
  import torch.nn.functional
  from packaging.version import parse
  from typeguard import check_argument_types
  from espnet2.asr.encoder.abs_encoder import AbsEncoder
  from espnet2.asr.frontend.abs_frontend import AbsFrontend
  from espnet2.asr.preencoder.abs_preencoder import AbsPreEncoder
  from espnet2.asr.specaug.abs_specaug import AbsSpecAug
  from espnet2.asvspoof.decoder.abs_decoder import AbsDecoder
  from espnet2.asvspoof.loss.abs_loss import AbsASVSpoofLoss
  from espnet2.layers.abs_normalize import AbsNormalize
  from espnet2.torch_utils.device_funcs import force_gatherable
  from espnet2.train.abs_espnet_model import AbsESPnetModel
  from espnet.nets.pytorch_backend.nets_utils import to_device
label_desc: Use image node_id 2 for calling the ESPnetASVSpoofModel obj's underlying member method code with example usage: obj.forward(speech, speech_lengths, label) and returns: loss,  stats,  weight