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` per batch.
docstr_tok: ["Compute","the","gradient","of","the","loss","function","w.r.t",".","`","x","`","per","batch","."]
code: def _loss_gradient_per_batch(
      self, x: np.ndarray, y: np.ndarray
  ) -> np.ndarray:
      """
      Compute the gradient of the loss function w.r.t. `x` per batch.
      """
      assert (
          x.shape[0] == y.shape[0]
      ), "Number of samples in x and y differ."
  
      # pad input
      x_padded, mask, mask_frequency = self._pad_audio_input(x)
  
      # get loss gradients
      feed_dict = {
          self._x_padded: x_padded,
          self._y_target: y,
          self._mask_frequency: mask_frequency,
      }
      gradients_padded = self.sess.run(
          self._loss_gradient_op, feed_dict
      )
  
      # undo padding, i.e. change gradients shape from (nb_samples, max_length) to (nb_samples)
      lengths = mask.sum(axis=1)
      gradients = []
      for gradient_padded, length in zip(gradients_padded, lengths):
          gradient = gradient_padded[:length]
          gradients.append(gradient)
  
      # for ragged input, use object dtype
      dtype = np.float32 if x.ndim != 1 else object
      return np.array(gradients, dtype=dtype)
  
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 13 for calling the TensorFlowLingvoASR obj's underlying member method code with example usage: obj._loss_gradient_per_batch(x, y) and returns: np