docstr: Decoder forward pass for training
  PARAMS
  ------
  memory: Encoder outputs
  obs_and_lat: Observed and latent attribute embeddings
  decoder_inputs: Decoder inputs for teacher forcing. i.e. mel-specs
  memory_lengths: Encoder output lengths for attention masking.
  
  RETURNS
  -------
  mel_outputs: mel outputs from the decoder
  gate_outputs: gate outputs from the decoder
  alignments: sequence of attention weights from the decoder
docstr_tok: ["Decoder","forward","pass","for","training","PARAMS","--","--","--","memory",":","Encoder","outputs","obs_and_lat",":","Observed","and","latent","attribute","embeddings","decoder_inputs",":","Decoder","inputs","for","teacher","forcing",".","i.e",".","mel-specs","memory_lengths",":","Encoder","output","lengths","for","attention","masking",".","RETURNS","--","--","--","-","mel_outputs",":","mel","outputs","from","the","decoder","gate_outputs",":","gate","outputs","from","the","decoder","alignments",":","sequence","of","attention","weights","from","the","decoder"]
code: def forward(
      self, memory, obs_and_lat, decoder_inputs, memory_lengths
  ):
      """Decoder forward pass for training
      PARAMS
      ------
      memory: Encoder outputs
      obs_and_lat: Observed and latent attribute embeddings
      decoder_inputs: Decoder inputs for teacher forcing. i.e. mel-specs
      memory_lengths: Encoder output lengths for attention masking.
  
      RETURNS
      -------
      mel_outputs: mel outputs from the decoder
      gate_outputs: gate outputs from the decoder
      alignments: sequence of attention weights from the decoder
      """
  
      decoder_input = self.get_go_frame(memory).unsqueeze(0)
      decoder_inputs = self.parse_decoder_inputs(decoder_inputs)
      decoder_inputs = torch.cat((decoder_input, decoder_inputs), dim=0)
      decoder_inputs = self.prenet(decoder_inputs)
  
      self.initialize_decoder_states(
          memory,
          obs_and_lat,
          mask=~get_mask_from_lengths(memory_lengths),
      )
  
      mel_outputs, gate_outputs, alignments = [], [], []
      while len(mel_outputs) < decoder_inputs.size(0) - 1:
          decoder_input = decoder_inputs[len(mel_outputs)]
          mel_output, gate_output, attention_weights = self.decode(
              decoder_input
          )
          mel_outputs += [mel_output.squeeze(1)]
          gate_outputs += [gate_output.squeeze()]
          alignments += [attention_weights]
  
      (
          mel_outputs,
          gate_outputs,
          alignments,
      ) = self.parse_decoder_outputs(
          mel_outputs, gate_outputs, alignments
      )
  
      return mel_outputs, gate_outputs, alignments
  
imports: from math import sqrt
  import torch
  import torch.distributions
  from torch.autograd import Variable
  from torch import nn
  from torch.nn import functional
  from .layers import ConvNorm, LinearNorm, GlobalAvgPool
  from .utils import to_gpu, get_mask_from_lengths
label_desc: Use image node_id 7 for calling the Decoder obj's underlying member method code with example usage: obj.forward(memory, obs_and_lat, decoder_inputs, memory_lengths) and returns: mel_outputs,  gate_outputs,  alignments