class_docstr: Implementation of the imperceptible attack against a speech recognition model.
  
  | Paper link: http://proceedings.mlr.press/v97/qin19a.html
docstr: Approximate the power spectral density for a perturbation `perturbation` in TensorFlow.
  
  Note that a stabilized PSD approximate is returned, where the `10*log10`-term has been 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`.
  :return: Approximate PSD tensor of shape `(batch_size, window_size // 2 + 1, frame_length)`.
code: def _approximate_power_spectral_density_tf(
      self, perturbation: "Tensor", psd_maximum_stabilized: "Tensor"
  ) -> "Tensor":
      """
      Approximate the power spectral density for a perturbation `perturbation` in TensorFlow.
  
      Note that a stabilized PSD approximate is returned, where the `10*log10`-term has been 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`.
      :return: Approximate PSD tensor of shape `(batch_size, window_size // 2 + 1, frame_length)`.
      """
      import tensorflow.compat.v1 as tf1
  
      # compute short-time Fourier transform (STFT)
      stft_matrix = tf1.signal.stft(
          perturbation,
          self._window_size,
          self._hop_size,
          fft_length=self._window_size,
      )
  
      # compute power spectral density (PSD)
      # note: fixes implementation of Qin et al. by also considering the square root of gain_factor
      gain_factor = np.sqrt(8.0 / 3.0)
      psd_matrix = tf1.square(
          tf1.abs(gain_factor * stft_matrix / self._window_size)
      )
  
      # approximate normalized psd: psd_matrix_approximated = 10^((96.0 - psd_matrix_max + psd_matrix)/10)
      psd_matrix_approximated = (
          tf1.pow(10.0, 9.6)
          / tf1.reshape(psd_maximum_stabilized, [-1, 1, 1])
          * psd_matrix
      )
  
      # return PSD matrix such that shape is (batch_size, window_size // 2 + 1, frame_length)
      return tf1.transpose(psd_matrix_approximated, [0, 2, 1])
  
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 10 for calling the ImperceptibleASR obj's underlying member method code with example usage: obj._approximate_power_spectral_density_tf(perturbation, psd_maximum_stabilized) and returns: tf1