class_docstr: Zeroes out(cuts) random continuous horisontal or
  vertical segments of the spectrogram as described in
  SpecAugment (https://arxiv.org/abs/1904.08779).
  
  params:
  freq_masks - how many frequency segments should be cut
  time_masks - how many time segments should be cut
  freq_width - maximum number of frequencies to be cut in one segment
  time_width - maximum number of time steps to be cut in one segment.
      Can be a positive integer or a float value in the range [0, 1].
      If positive integer value, defines maximum number of time steps
      to be cut in one segment.
      If a float value, defines maximum percentage of timesteps that
      are cut adaptively.
class_docstr_tok: ["Zeroes","out","(","cuts",")","random","continuous","horisontal","or","vertical","segments","of","the","spectrogram","as","described","in","SpecAugment","(","https",":","\/\/arxiv.org\/abs\/1904.08779",")",".","params",":","freq_masks","-","how","many","frequency","segments","should","be","cut","time_masks","-","how","many","time","segments","should","be","cut","freq_width","-","maximum","number","of","frequencies","to","be","cut","in","one","segment","time_width","-","maximum","number","of","time","steps","to","be","cut","in","one","segment",".","Can","be","a","positive","integer","or","a","float","value","in","the","range","[","0",",","1","]",".","If","positive","integer","value",",","defines","maximum","number","of","time","steps","to","be","cut","in","one","segment",".","If","a","float","value",",","defines","maximum","percentage","of","timesteps","that","are","cut","adaptively","."]
code: def forward(self, input_spec, length):
      batch_size, num_freq_bins, _ = input_spec.shape
      # Move lengths to CPU before repeated indexing
      lengths_cpu = length.cpu().numpy()
      # Generate a numpy boolean mask. `True` elements represent where the input spec will be augmented.
      fill_mask: np.array = np.full(
          shape=input_spec.shape, fill_value=False
      )
      freq_start_upper_bound = num_freq_bins - self.freq_width
      # Choose different mask ranges for each element of the batch
      for idx in range(batch_size):
          # Set freq masking
          for _ in range(self.freq_masks):
              start = self._rng.randint(0, freq_start_upper_bound)
              width = self._rng.randint(0, self.freq_width)
              fill_mask[idx, start : start + width, :] = True
  
          # Derive time width, sometimes based percentage of input length.
          if self.adaptive_temporal_width:
              time_max_width = max(
                  1, int(lengths_cpu[idx] * self.time_width)
              )
          else:
              time_max_width = self.time_width
          time_start_upper_bound = max(
              1, lengths_cpu[idx] - time_max_width
          )
  
          # Set time masking
          for _ in range(self.time_masks):
              start = self._rng.randint(0, time_start_upper_bound)
              width = self._rng.randint(0, time_max_width)
              fill_mask[idx, :, start : start + width] = True
      # Bring the mask to device and fill spec
      fill_mask = torch.from_numpy(fill_mask).to(input_spec.device)
      masked_spec = input_spec.masked_fill(
          mask=fill_mask, value=self.mask_value
      )
      return masked_spec
  
imports: import random
  import numpy
  import torch
  import torch.nn
  from nemo.core.classes import Typing, typecheck
  from nemo.core.neural_types import LengthsType, NeuralType, SpectrogramType
label_desc: Use image node_id 4 for calling the SpecAugment obj's underlying member method code with example usage: obj.forward(input_spec, length) and returns: masked_spec