class_docstr: Implementation of the imperceptible attack against a speech recognition model.
  
  | Paper link: http://proceedings.mlr.press/v97/qin19a.html
docstr: Compute loss gradient of the masking threshold loss in TensorFlow.
  
  Note that the PSD maximum and masking threshold are required to be stabilized, i.e. have the `10*log10`-term
  canceled out. Following Qin et al (2019) this mitigates optimization instabilities.
  
  :param perturbation: Adversarial perturbation.
  :param psd_maximum_stabilized: Stabilized maximum across frames, i.e. shape is `(batch_size, frame_length)`, of
      the original unnormalized PSD of `x`.
  :param masking_threshold_stabilized: Stabilized masking threshold for the original input `x`.
  :return: Approximate PSD tensor of shape `(batch_size, window_size // 2 + 1, frame_length)`.
code: def _loss_gradient_masking_threshold_tf(
      self,
      perturbation: "Tensor",
      psd_maximum_stabilized: "Tensor",
      masking_threshold_stabilized: "Tensor",
  ) -> Union["Tensor", "Tensor"]:
      """
      Compute loss gradient of the masking threshold loss in TensorFlow.
  
      Note that the PSD maximum and masking threshold are required to be stabilized, i.e. have the `10*log10`-term
      canceled out. Following Qin et al (2019) this mitigates optimization instabilities.
  
      :param perturbation: Adversarial perturbation.
      :param psd_maximum_stabilized: Stabilized maximum across frames, i.e. shape is `(batch_size, frame_length)`, of
          the original unnormalized PSD of `x`.
      :param masking_threshold_stabilized: Stabilized masking threshold for the original input `x`.
      :return: Approximate PSD tensor of shape `(batch_size, window_size // 2 + 1, frame_length)`.
      """
      import tensorflow.compat.v1 as tf1
  
      # calculate approximate power spectral density
      psd_perturbation = self._approximate_power_spectral_density_tf(
          perturbation, psd_maximum_stabilized
      )
  
      # calculate hinge loss
      loss = tf1.reduce_mean(
          tf1.nn.relu(psd_perturbation - masking_threshold_stabilized),
          axis=[1, 2],
          keepdims=False,
      )
  
      # compute loss gradient
      loss_gradient = tf1.gradients(loss, [perturbation])[0]
      return loss_gradient, loss
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import TYPE_CHECKING, Optional, Tuple, Union
  import numpy
  import scipy.signal
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator, LossGradientsMixin, NeuralNetworkMixin
  from art.estimators.pytorch import PyTorchEstimator
  from art.estimators.speech_recognition.speech_recognizer import SpeechRecognizerMixin
  from art.estimators.tensorflow import TensorFlowV2Estimator
  from art.utils import pad_sequence_input
label_desc: Use image node_id 8 for calling the ImperceptibleASR obj's underlying member method code with example usage: obj._loss_gradient_masking_threshold_tf(perturbation, psd_maximum_stabilized, masking_threshold_stabilized) and returns: loss_gradient,  loss