class_docstr: n-gram decoder.
  
  This decoder implementation does not condition on the full target-side
  history. Instead, predictions only depend on the target n-gram history and
  the full source sentence via attention over encoder outputs. The decoder
  network is a feedforward network with source context as additional input.
class_docstr_tok: ["n-gram","decoder",".","This","decoder","implementation","does","not","condition","on","the","full","target-side","history",".","Instead",",","predictions","only","depend","on","the","target","n-gram","history","and","the","full","source","sentence","via","attention","over","encoder","outputs",".","The","decoder","network","is","a","feedforward","network","with","source","context","as","additional","input","."]
code: def forward_unprojected(
      self, input_tokens, encoder_out, incremental_state=None
  ):
      padded_tokens = F.pad(
          input_tokens,
          (self.history_len - 1, 0, 0, 0),
          "constant",
          self.dst_dict.eos(),
      )
      # We use incremental_state only to check whether we are decoding or not
      # self.training is false even for the forward pass through validation
      if incremental_state is not None:
          padded_tokens = padded_tokens[:, -self.history_len :]
      utils.set_incremental_state(
          self, incremental_state, "incremental_marker", True
      )
  
      bsz, seqlen = padded_tokens.size()
      seqlen -= self.history_len - 1
  
      # get outputs from encoder
      (encoder_outs, final_hidden, _, src_lengths, _) = encoder_out
  
      # padded_tokens has shape [batch_size, seq_len+history_len]
      x = self.embed_tokens(padded_tokens)
      x = F.dropout(x, p=self.dropout_in, training=self.training)
  
      # Convolution needs shape [batch_size, channels, seq_len]
      x = self.history_conv(x.transpose(1, 2)).transpose(1, 2)
      x = F.dropout(x, p=self.dropout_out, training=self.training)
  
      # x has shape [batch_size, seq_len, channels]
      for i, layer in enumerate(self.layers):
          prev_x = x
          x = layer(x)
          x = F.dropout(x, p=self.dropout_out, training=self.training)
          if (
              self.residual_level is not None
              and i >= self.residual_level
          ):
              x = x + prev_x
  
      # Attention
      attn_out, attn_scores = self.attention(
          x.transpose(0, 1).contiguous().view(-1, self.hidden_dim),
          encoder_outs.repeat(1, seqlen, 1),
          src_lengths.repeat(seqlen),
      )
      if attn_out is not None:
          attn_out = attn_out.view(seqlen, bsz, -1).transpose(1, 0)
      attn_scores = attn_scores.view(-1, seqlen, bsz).transpose(0, 2)
      x = maybe_cat((x, attn_out), dim=2)
  
      # bottleneck layer
      if hasattr(self, "additional_fc"):
          x = self.additional_fc(x)
          x = F.dropout(x, p=self.dropout_out, training=self.training)
      return x, attn_scores
  
file_path: translate/pytorch_translate/ngram.py
imports: import torch
  import torch.nn
  import torch.nn.functional
  from fairseq import utils
  from pytorch_translate import attention, utils
  from pytorch_translate.common_layers import DecoderWithOutputProjection, Embedding, Linear, NonlinearLayer
  from pytorch_translate.utils import maybe_cat
label_desc: Use image node_id 2 for calling the NGramDecoder obj's underlying member method code with example usage: obj.forward_unprojected(input_tokens, encoder_out, incremental_state) and returns: x,  attn_scores