class_docstr: Implements decoder module of the SAR model
  
  Args:
  ----
      rnn_units: number of hidden units in recurrent cells
      max_length: maximum length of a sequence
      vocab_size: number of classes in the model alphabet
      embedding_units: number of hidden embedding units
      attention_units: number of hidden attention units
      num_decoder_cells: number of LSTMCell layers to stack
      dropout_prob: dropout probability
class_docstr_tok: ["Implements","decoder","module","of","the","SAR","model","Args",":","--","--","rnn_units",":","number","of","hidden","units","in","recurrent","cells","max_length",":","maximum","length","of","a","sequence","vocab_size",":","number","of","classes","in","the","model","alphabet","embedding_units",":","number","of","hidden","embedding","units","attention_units",":","number","of","hidden","attention","units","num_decoder_cells",":","number","of","LSTMCell","layers","to","stack","dropout_prob",":","dropout","probability"]
code: def call(
      self,
      features: tf.Tensor,
      holistic: tf.Tensor,
      gt: Optional[tf.Tensor] = None,
      **kwargs: Any,
  ) -> tf.Tensor:
      if gt is not None:
          gt_embedding = self.embed_tgt(gt, **kwargs)
  
      logits_list: List[tf.Tensor] = []
  
      for t in range(self.max_length + 1):  # 32
          if t == 0:
              # step to init the first states of the LSTMCell
              states = self.lstm_cells.get_initial_state(
                  inputs=None,
                  batch_size=features.shape[0],
                  dtype=features.dtype,
              )
              prev_symbol = holistic
          elif t == 1:
              # step to init a 'blank' sequence of length vocab_size + 1 filled with zeros
              # (N, vocab_size + 1) --> (N, embedding_units)
              prev_symbol = tf.zeros(
                  [features.shape[0], self.vocab_size + 1]
              )
              prev_symbol = self.embed(prev_symbol, **kwargs)
          else:
              if gt is not None:
                  # (N, embedding_units) -2 because of <bos> and <eos> (same)
                  prev_symbol = self.embed(
                      gt_embedding[:, t - 2], **kwargs
                  )
              else:
                  # -1 to start at timestep where prev_symbol was initialized
                  index = tf.argmax(logits_list[t - 1], axis=-1)
                  # update prev_symbol with ones at the index of the previous logit vector
                  # (N, embedding_units)
                  index = tf.ones_like(index)
                  prev_symbol = tf.scatter_nd(
                      tf.expand_dims(index, axis=1),
                      prev_symbol,
                      tf.constant(
                          [features.shape[0], features.shape[-1]],
                          dtype=tf.int64,
                      ),
                  )
  
          # (N, C), (N, C)  take the last hidden state and cell state from current timestep
          _, states = self.lstm_cells(prev_symbol, states, **kwargs)
          # states = (hidden_state, cell_state)
          hidden_state = states[0][0]
          # (N, H, W, C), (N, C) --> (N, C)
          glimpse = self.attention_module(
              features, hidden_state, **kwargs
          )
          # (N, C), (N, C) --> (N, 2 * C)
          logits = tf.concat([hidden_state, glimpse], axis=1)
          logits = self.dropout(logits, **kwargs)
          # (N, vocab_size + 1)
          logits_list.append(self.output_dense(logits, **kwargs))
  
      # (max_length + 1, N, vocab_size + 1) --> (N, max_length + 1, vocab_size + 1)
      return tf.transpose(tf.stack(logits_list[1:]), (1, 0, 2))
  
imports: from copy import deepcopy
  from typing import Any, Dict, List, Optional, Tuple
  import tensorflow
  from tensorflow.keras import Model, Sequential, layers
  from doctr.datasets import VOCABS
  from doctr.utils.repr import NestedObject
  from ...classification import resnet31
  from ...utils.tensorflow import _bf16_to_float32, load_pretrained_params
  from ..core import RecognitionModel, RecognitionPostProcessor
label_desc: Use image node_id 2 for calling the SARDecoder obj's underlying member method code with example usage: obj.call(features, holistic, gt) and returns: tf