class_docstr: Defines the SVGDecoder model.
code: def lstm_decoder_infer(
      self,
      inputs,
      sequence_length,
      hparams,
      clss,
      train,
      initial_state=None,
      bottleneck=None,
  ):
      # IN PREDICT MODE, RUN tf.while RNN
      max_decode_length = 51
      batch_size = common_layers.shape_list(inputs)[0]
      zero_pad, logits_so_far = self.create_initial_input_for_decode(
          batch_size
      )
  
      layers = rnn.MultiRNNCell(
          [
              self.lstm_cell(hparams, train)
              for _ in range(hparams.num_hidden_layers)
          ]
      )
  
      if initial_state is None:
          raise Exception(
              "initial state should be init from bottleneck!"
          )
  
      # append one-hot class to bottleneck, which will be given per step
      clss = tf.reshape(clss, [-1])
      if not hparams.use_cls:
          clss = tf.zeros_like(clss)
      if hparams.condition_on_sln:
          sln = tf.reshape(sequence_length, [-1])
          bottleneck = tf.concat(
              (
                  bottleneck,
                  tf.one_hot(clss, hparams.num_categories),
                  tf.one_hot(sln, max_decode_length),
              ),
              -1,
          )
      else:
          bottleneck = tf.concat(
              (bottleneck, tf.one_hot(clss, hparams.num_categories)), -1
          )
  
      def infer_step(logits_so_far, current_hidden):
          """Inference step of LSTM while loop."""
          # unflatten hidden:
          current_hidden = tuple(
              rnn.LSTMStateTuple(c=s[0], h=s[1]) for s in current_hidden
          )
  
          # put logits_so_far through top
          tm = self._problem_hparams.modality["targets"]
          # need to reuse top params
          reset_scope = tf.variable_scope(
              tf.VariableScope(tf.AUTO_REUSE, ""),
              reuse=tf.AUTO_REUSE,
              auxiliary_name_scope=False,
          )
          top_scope = tf.variable_scope(
              "svg_decoder/{}_modality".format(tm), reuse=tf.AUTO_REUSE
          )
          with reset_scope, top_scope:
              samples_so_far = self.hparams.top["targets"](
                  logits_so_far,
                  None,
                  self.hparams,
                  self.problem_hparams.vocab_size,
              )
          # append a zero pad to the samples. this effectively shifts the samples
          # right, but, unlike shift_right, by not removing the last element, we
          # allow an empty samples_so_far to not be empty after padding
          samples_so_far = tf.concat([zero_pad, samples_so_far], axis=1)
          shifted_targets = common_layers.flatten4d3d(samples_so_far)
          # now take the very last one here, will be the actual input to the rnn
          shifted_targets = shifted_targets[:, -1:, :]
  
          # tile and append the bottleneck to inputs
          sln_offset = 0
          if hparams.condition_on_sln:
              sln_offset = 51
          pre_tile_y = tf.reshape(
              bottleneck,
              [
                  common_layers.shape_list(bottleneck)[0],
                  1,
                  hparams.bottleneck_bits
                  + hparams.num_categories
                  + sln_offset,
              ],
          )
          overlay_x = tf.tile(
              pre_tile_y,
              [1, common_layers.shape_list(shifted_targets)[1], 1],
          )
          inputs = tf.concat([shifted_targets, overlay_x], -1)
  
          seq_len_batch = tf.ones([common_layers.shape_list(inputs)[0]])
  
          # RUN PRE-LSTM LAYER
          with tf.variable_scope("pre_decoder", reuse=tf.AUTO_REUSE):
              inputs = tf.layers.dense(
                  inputs, hparams.hidden_size, name="bottom"
              )
              inputs = tf.nn.tanh(inputs)
  
          # RUN LSTM
          with tf.variable_scope("lstm_decoder", reuse=tf.AUTO_REUSE):
              next_step, next_state = tf.nn.dynamic_rnn(
                  layers,
                  inputs,
                  seq_len_batch,
                  initial_state=current_hidden,
                  dtype=tf.float32,
                  time_major=False,
              )
  
          next_step = tf.expand_dims(next_step, [1])
          logits_so_far = tf.concat([logits_so_far, next_step], 1)
  
          # flatten state
          next_state = tuple((s.c, s.h) for s in next_state)
  
          return logits_so_far, next_state
  
      def while_exit_cond(logits_so_far, unused_current_hidden):
          length = common_layers.shape_list(logits_so_far)[1]
          return length < max_decode_length
  
      # passing state must be flattened:
      initial_state = tuple((s.c, s.h) for s in initial_state)
  
      # actually run tf.while:
      logits, final_state = tf.while_loop(
          while_exit_cond,
          infer_step,
          [logits_so_far, initial_state],
          shape_invariants=[
              tf.TensorShape([None, None, 1, hparams.hidden_size]),
              tuple(
                  (s[0].get_shape(), s[1].get_shape())
                  for s in initial_state
              ),
          ],
          back_prop=False,
          parallel_iterations=1,
      )
  
      # logits should be returned in 3d mode:
      logits = common_layers.flatten4d3d(logits)
  
      return logits, final_state
  
imports: import copy
  from magenta.contrib import rnn
  from magenta.models.svg_vae import image_vae
  from magenta.models.svg_vae import svg_decoder_loss
  from tensor2tensor.layers import common_hparams
  from tensor2tensor.layers import common_layers
  from tensor2tensor.utils import registry
  from tensor2tensor.utils import t2t_model
  from tensor2tensor.utils import trainer_lib
  import tensorflow.compat.v1
  from tensorflow.compat.v1 import estimator
label_desc: Use image node_id 4 for calling the SVGDecoder obj's underlying member method code with example usage: obj.lstm_decoder_infer(inputs, sequence_length, hparams, clss, train, initial_state, bottleneck) and returns: logits,  final_state, logits_so_far,  next_state, unknown