class_docstr: This class implements the imperceptible, robust, and targeted attack to generate adversarial examples for automatic
  speech recognition models. This attack will be implemented specifically for DeepSpeech model and is framework
  dependent, specifically for PyTorch.
  
  | Paper link: https://arxiv.org/abs/1903.10346
docstr: Generate adversarial samples and return them in an array.
  
  :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
            could have different lengths. A possible example of `x` could be:
            `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
  :param y: Target values of shape (nb_samples). Each sample in `y` is a string and it may possess different
            lengths. A possible example of `y` could be: `y = np.array(['SIXTY ONE', 'HELLO'])`. Note that, this
            class only supports targeted attack.
  :return: An array holding the adversarial examples.
docstr_tok: ["Generate","adversarial","samples","and","return","them","in","an","array",".",":","param","x",":","Samples","of","shape","(","nb_samples",",","seq_length",")",".","Note","that",",","it","is","allowable","that","sequences","in","the","batch","could","have","different","lengths",".","A","possible","example","of","`","x","`","could","be",":","`","x","=","np.array","(","[","np.array","(","[","0.1",",","0.2",",","0.1",",","0.4","]",")",",","np.array","(","[","0.3",",","0.1","]",")","]",")","`",".",":","param","y",":","Target","values","of","shape","(","nb_samples",")",".","Each","sample","in","`","y","`","is","a","string","and","it","may","possess","different","lengths",".","A","possible","example","of","`","y","`","could","be",":","`","y","=","np.array","(","[","'SIXTY","ONE","'",",","'HELLO","'","]",")","`",".","Note","that",",","this","class","only","supports","targeted","attack",".",":","return",":","An","array","holding","the","adversarial","examples","."]
code: def generate(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> np.ndarray:
      """
      Generate adversarial samples and return them in an array.
  
      :param x: Samples of shape (nb_samples, seq_length). Note that, it is allowable that sequences in the batch
                could have different lengths. A possible example of `x` could be:
                `x = np.array([np.array([0.1, 0.2, 0.1, 0.4]), np.array([0.3, 0.1])])`.
      :param y: Target values of shape (nb_samples). Each sample in `y` is a string and it may possess different
                lengths. A possible example of `y` could be: `y = np.array(['SIXTY ONE', 'HELLO'])`. Note that, this
                class only supports targeted attack.
      :return: An array holding the adversarial examples.
      """
      import torch
  
      if y is None:  # pragma: no cover
          raise ValueError(
              "`ImperceptibleASRPyTorch` is a targeted attack and requires the definition of target"
              "labels `y`. Currently `y` is set to `None`."
          )
  
      # Cast to type float64 to avoid overflow
      adv_x = np.array([x_i.copy().astype(np.float64) for x_i in x])
  
      # Put the estimator in the training mode, otherwise CUDA may not be able to backpropagate through the model in
      # case a PyTorchDeepSpeech estimator is used. However, the PyTorchDeepSpeech estimator uses batch norm layers
      # which need to be frozen
      self.estimator.to_training_mode()
      self.estimator.set_batchnorm(train=False)
  
      # Compute perturbation with batching
      num_batch = int(np.ceil(len(x) / float(self.batch_size)))
  
      for m in range(num_batch):
          # Batch indexes
          batch_index_1, batch_index_2 = (
              m * self.batch_size,
              min((m + 1) * self.batch_size, len(x)),
          )
  
          # First reset delta
          self.global_optimal_delta.data = torch.zeros(
              self.batch_size, self.global_max_length
          ).type(torch.float64)
  
          # Next, reset optimizers
          if self._optimizer_arg_1 is None:
              self.optimizer_1 = torch.optim.Adam(
                  params=[self.global_optimal_delta],
                  lr=self.learning_rate_1,
              )
          else:
              self.optimizer_1 = self._optimizer_arg_1(  # type: ignore
                  params=[self.global_optimal_delta],
                  lr=self.learning_rate_1,
              )
  
          if self._optimizer_arg_2 is None:
              self.optimizer_2 = torch.optim.Adam(
                  params=[self.global_optimal_delta],
                  lr=self.learning_rate_2,
              )
          else:
              self.optimizer_2 = self._optimizer_arg_2(  # type: ignore
                  params=[self.global_optimal_delta],
                  lr=self.learning_rate_2,
              )
  
          # Then compute the batch
          adv_x_batch = self._generate_batch(
              adv_x[batch_index_1:batch_index_2],
              y[batch_index_1:batch_index_2],
          )
  
          for i in range(len(adv_x_batch)):
              adv_x[batch_index_1 + i] = adv_x_batch[
                  i, : len(adv_x[batch_index_1 + i])
              ]
  
      # Unfreeze batch norm layers again, needed in case of PyTorchDeepSpeech
      self.estimator.set_batchnorm(train=True)
  
      # Recast to the original type
      adv_x = np.array(
          [adv_x[i].astype(x[i].dtype) for i in range(len(adv_x))]
      )
  
      return adv_x
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import TYPE_CHECKING, Optional, Tuple, List
  import numpy
  import scipy
  from art.attacks.attack import EvasionAttack
  from art.estimators.pytorch import PyTorchEstimator
  from art.estimators.speech_recognition.pytorch_deep_speech import PyTorchDeepSpeech
  from art.estimators.speech_recognition.speech_recognizer import SpeechRecognizerMixin
  from art.estimators.speech_recognition.speech_recognizer import PytorchSpeechRecognizerMixin
label_desc: Use image node_id 2 for calling the ImperceptibleASRPyTorch obj's underlying member method code with example usage: obj.generate(x, y) and returns: adv_x