class_docstr: This class implements the task-specific Lingvo ASR model of Qin et al. (2019).
  
  The estimator uses a pre-trained model provided by Qin et al., which is trained using the Lingvo library and the
  LibriSpeech dataset.
  
  | Paper link: http://proceedings.mlr.press/v97/qin19a.html, https://arxiv.org/abs/1902.08295
  
  .. warning:: In order to calculate loss gradients, this estimator requires a user-patched Lingvo module. A patched
               source file for the `lingvo.tasks.asr.decoder` module will be automatically applied. The original
               source file can be found in `<PYTHON_SITE_PACKAGES>/lingvo/tasks/asr/decoder.py` and will be patched as
               outlined in the following commit diff:
               https://github.com/yaq007/lingvo/commit/414e035b2c60372de732c9d67db14d1003be6dd6
  
  The patched `decoder_patched.py` can be found in `ART_DATA_PATH/lingvo/asr`.
  
  Note: Run `python -m site` to obtain a list of possible candidates where to find the `<PYTHON_SITE_PACKAGES` folder.
docstr: Compute the gradient of the loss function w.r.t. `x`.
  
  :param x: Samples of shape `(nb_samples)`. Note that, it is allowable that sequences in the batch
            could have different lengths. A possible example of `x` could be:
            `x = np.ndarray([[0.1, 0.2, 0.1, 0.4], [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'])`.
  :param batch_mode: If `True` calculate gradient per batch or otherwise per sequence.
  :return: Loss gradients of the same shape as `x`.
docstr_tok: ["Compute","the","gradient","of","the","loss","function","w.r.t",".","`","x","`",".",":","param","x",":","Samples","of","shape","`","(","nb_samples",")","`",".","Note","that",",","it","is","allowable","that","sequences","in","the","batch","could","have","different","lengths",".","A","possible","example","of","`","x","`","could","be",":","`","x","=","np.ndarray","(","[","[","0.1",",","0.2",",","0.1",",","0.4","]",",","[","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","'","]",")","`",".",":","param","batch_mode",":","If","`","True","`","calculate","gradient","per","batch","or","otherwise","per","sequence",".",":","return",":","Loss","gradients","of","the","same","shape","as","`","x","`","."]
code: def loss_gradient(  # pylint: disable=W0221
      self,
      x: np.ndarray,
      y: np.ndarray,
      batch_mode: bool = False,
      **kwargs,
  ) -> np.ndarray:
      """
      Compute the gradient of the loss function w.r.t. `x`.
  
      :param x: Samples of shape `(nb_samples)`. Note that, it is allowable that sequences in the batch
                could have different lengths. A possible example of `x` could be:
                `x = np.ndarray([[0.1, 0.2, 0.1, 0.4], [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'])`.
      :param batch_mode: If `True` calculate gradient per batch or otherwise per sequence.
      :return: Loss gradients of the same shape as `x`.
      """
      # if inputs have 32-bit floating point wav format, the preprocessing argument is required
      is_normalized = max(map(max, np.abs(x))) <= 1.0  # type: ignore
      if is_normalized and self.preprocessing is None:
          raise ValueError(
              "The LingvoASR estimator requires input values in the range [-32768, 32767] or normalized input values"
              " with correct preprocessing argument (mean=0, stddev=1/normalization_factor)."
          )
  
      # Lingvo model works with lower case transcriptions
      y = np.array([y_i.lower() for y_i in y])
  
      # Apply preprocessing
      x_preprocessed, y_preprocessed = self._apply_preprocessing(
          x, y, fit=False
      )
  
      if batch_mode:
          gradients = self._loss_gradient_per_batch(
              x_preprocessed, y_preprocessed
          )
      else:
          gradients = self._loss_gradient_per_sequence(
              x_preprocessed, y_preprocessed
          )
  
      # Apply preprocessing gradients
      gradients = self._apply_preprocessing_gradient(x, gradients)
      return gradients
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  import os
  import sys
  from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
  import numpy
  from art import config
  from art.estimators.speech_recognition.speech_recognizer import SpeechRecognizerMixin
  from art.estimators.tensorflow import TensorFlowV2Estimator
  from art.utils import get_file, make_directory
label_desc: Use image node_id 12 for calling the TensorFlowLingvoASR obj's underlying member method code with example usage: obj.loss_gradient(x, y, batch_mode) and returns: gradients