class_docstr: Sequence-to-sequence base class.
class_docstr_tok: ["Sequence-to-sequence","base","class","."]
docstr: Build and run a RNN decoder with a final projection layer.
  
  Args:
    encoder_outputs: The outputs of encoder for every time step.
    encoder_state: The final state of the encoder.
    hparams: The Hyperparameters configurations.
  
  Returns:
    A tuple of final logits and final decoder state:
      logits: size [time, batch_size, vocab_size] when time_major=True.
docstr_tok: ["Build","and","run","a","RNN","decoder","with","a","final","projection","layer",".","Args",":","encoder_outputs",":","The","outputs","of","encoder","for","every","time","step",".","encoder_state",":","The","final","state","of","the","encoder",".","hparams",":","The","Hyperparameters","configurations",".","Returns",":","A","tuple","of","final","logits","and","final","decoder","state",":","logits",":","size","[","time",",","batch_size",",","vocab_size","]","when","time_major=True","."]
code: def _build_decoder(self, encoder_outputs, encoder_state, hparams):
      """Build and run a RNN decoder with a final projection layer.
  
      Args:
        encoder_outputs: The outputs of encoder for every time step.
        encoder_state: The final state of the encoder.
        hparams: The Hyperparameters configurations.
  
      Returns:
        A tuple of final logits and final decoder state:
          logits: size [time, batch_size, vocab_size] when time_major=True.
      """
      tgt_sos_id = tf.cast(
          self.tgt_vocab_table.lookup(tf.constant(hparams.sos)),
          tf.int32,
      )
      tgt_eos_id = tf.cast(
          self.tgt_vocab_table.lookup(tf.constant(hparams.eos)),
          tf.int32,
      )
      iterator = self.iterator
  
      # maximum_iteration: The maximum decoding steps.
      maximum_iterations = self._get_infer_maximum_iterations(
          hparams, iterator.source_sequence_length
      )
  
      # Decoder.
      with tf.variable_scope("decoder") as decoder_scope:
          cell, decoder_initial_state = self._build_decoder_cell(
              hparams,
              encoder_outputs,
              encoder_state,
              iterator.source_sequence_length,
          )
  
          # Optional ops depends on which mode we are in and which loss function we
          # are using.
          logits = tf.no_op()
          decoder_cell_outputs = None
  
          # Train or eval
          if self.mode != tf.contrib.learn.ModeKeys.INFER:
              # decoder_emp_inp: [max_time, batch_size, num_units]
              target_input = iterator.target_input
              if self.time_major:
                  target_input = tf.transpose(target_input)
              decoder_emb_inp = tf.nn.embedding_lookup(
                  self.embedding_decoder, target_input
              )
  
              # Helper
              helper = tf.contrib.seq2seq.TrainingHelper(
                  decoder_emb_inp,
                  iterator.target_sequence_length,
                  time_major=self.time_major,
              )
  
              # Decoder
              my_decoder = tf.contrib.seq2seq.BasicDecoder(
                  cell,
                  helper,
                  decoder_initial_state,
              )
  
              # Dynamic decoding
              (
                  outputs,
                  final_context_state,
                  _,
              ) = tf.contrib.seq2seq.dynamic_decode(
                  my_decoder,
                  output_time_major=self.time_major,
                  swap_memory=True,
                  scope=decoder_scope,
              )
  
              sample_id = outputs.sample_id
  
              if self.num_sampled_softmax > 0:
                  # Note: this is required when using sampled_softmax_loss.
                  decoder_cell_outputs = outputs.rnn_output
  
              # Note: there's a subtle difference here between train and inference.
              # We could have set output_layer when create my_decoder
              #   and shared more code between train and inference.
              # We chose to apply the output_layer to all timesteps for speed:
              #   10% improvements for small models & 20% for larger ones.
              # If memory is a concern, we should apply output_layer per timestep.
              num_layers = self.num_decoder_layers
              num_gpus = self.num_gpus
              device_id = (
                  num_layers
                  if num_layers < num_gpus
                  else (num_layers - 1)
              )
              # Colocate output layer with the last RNN cell if there is no extra GPU
              # available. Otherwise, put last layer on a separate GPU.
              with tf.device(
                  model_helper.get_device_str(device_id, num_gpus)
              ):
                  logits = self.output_layer(outputs.rnn_output)
  
              if self.num_sampled_softmax > 0:
                  logits = (
                      tf.no_op()
                  )  # unused when using sampled softmax loss.
  
          # Inference
          else:
              infer_mode = hparams.infer_mode
              start_tokens = tf.fill([self.batch_size], tgt_sos_id)
              end_token = tgt_eos_id
              utils.print_out(
                  "  decoder: infer_mode=%sbeam_width=%d, length_penalty=%f"
                  % (
                      infer_mode,
                      hparams.beam_width,
                      hparams.length_penalty_weight,
                  )
              )
  
              if infer_mode == "beam_search":
                  beam_width = hparams.beam_width
                  length_penalty_weight = hparams.length_penalty_weight
  
                  my_decoder = tf.contrib.seq2seq.BeamSearchDecoder(
                      cell=cell,
                      embedding=self.embedding_decoder,
                      start_tokens=start_tokens,
                      end_token=end_token,
                      initial_state=decoder_initial_state,
                      beam_width=beam_width,
                      output_layer=self.output_layer,
                      length_penalty_weight=length_penalty_weight,
                  )
              elif infer_mode == "sample":
                  # Helper
                  sampling_temperature = hparams.sampling_temperature
                  assert sampling_temperature > 0.0, (
                      "sampling_temperature must greater than 0.0 when using sample"
                      " decoder."
                  )
                  helper = tf.contrib.seq2seq.SampleEmbeddingHelper(
                      self.embedding_decoder,
                      start_tokens,
                      end_token,
                      softmax_temperature=sampling_temperature,
                      seed=self.random_seed,
                  )
              elif infer_mode == "greedy":
                  helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(
                      self.embedding_decoder, start_tokens, end_token
                  )
              else:
                  raise ValueError(
                      "Unknown infer_mode '%s'", infer_mode
                  )
  
              if infer_mode != "beam_search":
                  my_decoder = tf.contrib.seq2seq.BasicDecoder(
                      cell,
                      helper,
                      decoder_initial_state,
                      output_layer=self.output_layer,  # applied per timestep
                  )
  
              # Dynamic decoding
              (
                  outputs,
                  final_context_state,
                  _,
              ) = tf.contrib.seq2seq.dynamic_decode(
                  my_decoder,
                  maximum_iterations=maximum_iterations,
                  output_time_major=self.time_major,
                  swap_memory=True,
                  scope=decoder_scope,
              )
  
              if infer_mode == "beam_search":
                  sample_id = outputs.predicted_ids
              else:
                  logits = outputs.rnn_output
                  sample_id = outputs.sample_id
  
      return (
          logits,
          decoder_cell_outputs,
          sample_id,
          final_context_state,
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import abc
  import collections
  import tensorflow
  from tensorflow.contrib.model_pruning import get_masks, get_thresholds
  from tensorflow.contrib.model_pruning.python import pruning
  from tensorflow.contrib.model_pruning.python.layers import core_layers
  from .None import model_helper
  from .utils import misc_utils, iterator_utils
label_desc: Use image node_id 15 for calling the BaseModel obj's underlying member method code with example usage: obj._build_decoder(encoder_outputs, encoder_state, hparams) and returns: logits,  decoder_cell_outputs,  sample_id,  final_context_state