class_docstr: A GRU copying decoder that accepts an variable-sized set of encodings.
class_docstr_tok: ["A","GRU","copying","decoder","that","accepts","an","variable-sized","set","of","encodings","."]
code: def greedy_decode(
      self,
      *,
      input_concrete_values: List[str],
      input_memories,
      input_memories_origin_idx,
      initial_states,
      neural_model: GruCopyingDecoder,
  ) -> List[Tuple[List[str], float]]:
      output_vocab = self.__output_vocabulary
      batch_size = initial_states.shape[0]
      assert len(input_concrete_values) == input_memories.shape[0]
  
      current_decoder_states = initial_states  # [num-targets, H]
      next_token_sequences = torch.tensor(
          [[output_vocab.get_id_or_unk(self.START)]] * batch_size,
          device=input_memories.device,
      )  # [num-targets x 1]
  
      predicted_tokens: List[List[str]] = [
          [] for _ in range(batch_size)
      ]
      predicted_logprobs: List[float] = [0.0 for _ in range(batch_size)]
      sample_id_done = np.zeros(batch_size, dtype=np.bool)
  
      for i in range(self.max_seq_len):
          (
              copy_logprobs,
              target_logprobs,
              output_decoder_state,
          ) = neural_model._compute_logprobs(
              current_decoder_states,
              input_memories,
              input_memories_origin_idx,
              next_token_sequences,
          )
          current_decoder_states = output_decoder_state.squeeze(
              0
          )  # [num-targets, H]
  
          # To speed things up, look up the top 100 vocab tokens
          topk_vocab_logprobs, topk_vocab_idxs = torch.topk(
              target_logprobs.squeeze(1),
              min(100, target_logprobs.shape[-1]),
              dim=-1,
          )  # [num-targets, 100], [num-targets, 100]
  
          # Move to CPU and show as numpy
          topk_vocab_logprobs = topk_vocab_logprobs.cpu().numpy()
          topk_vocab_idxs = topk_vocab_idxs.cpu().numpy()
          copy_logprobs = copy_logprobs.squeeze(1).cpu().numpy()
  
          target_token_predictions = [
              {
                  output_vocab.get_name_for_id(
                      int(token_idx)
                  ): token_logprob
                  for token_idx, token_logprob in zip(
                      topk_vocab_idxs[batch_idx],
                      topk_vocab_logprobs[batch_idx],
                  )
              }
              for batch_idx in range(batch_size)
          ]  # for each element in the batch, the logprobs of the target predictions
  
          for batch_idx, concrete_value, copy_logprob in zip(
              input_memories_origin_idx.cpu().numpy(),
              input_concrete_values,
              copy_logprobs,
          ):
              predictions = target_token_predictions[batch_idx]
              predictions[concrete_value] = np.logaddexp(
                  predictions.get(concrete_value, -math.inf),
                  copy_logprob,
              )
  
          predicted_tokens_for_this_step = []
          for batch_idx, predictions in enumerate(
              target_token_predictions
          ):
              if sample_id_done[batch_idx]:
                  predicted_tokens_for_this_step.append(self.END)
                  continue
  
              predicted_token, predicted_logprob = max(
                  target_token_predictions[batch_idx].items(),
                  key=lambda x: x[1],
              )
  
              if predicted_token == self.END:
                  sample_id_done[batch_idx] = True
              else:
                  predicted_tokens[batch_idx].append(predicted_token)
  
              predicted_tokens_for_this_step.append(predicted_token)
              predicted_logprobs[batch_idx] += predicted_logprob
  
          next_token_sequences = torch.tensor(
              [
                  [output_vocab.get_id_or_unk(t)]
                  for t in predicted_tokens_for_this_step
              ],
              device=input_memories.device,
          )
  
      return list(zip(predicted_tokens, predicted_logprobs))
  
imports: from typing_extensions import Final
  import logging
  import math
  import numpy
  import torch
  import torch.nn
  from dpu_utils.mlutils import Vocabulary
  from torch_scatter import scatter_add
  from torch_scatter.composite import scatter_log_softmax, scatter_logsumexp
  from typing import Any, Counter, Dict, List, NamedTuple, Tuple, Union
  from ptgnn.baseneuralmodel import AbstractNeuralModel
label_desc: Use image node_id 12 for calling the GruCopyingDecoderModel obj's underlying member method code with example usage: obj.greedy_decode() and returns: list