(self, sentences, sentence_length,
                input_conversation_length, target_sentences, decode=False)
Args:
            sentences: (Variable, LongTensor) [num_sentences + batch_size, seq_len]
            target_sentences: (Variable, LongTensor) [num_sentences, seq_len]
        Return:
            decoder_outputs: (Variable, FloatTensor)
                - train: [batch_size, seq_len, vocab_size]
                - eval: [batch_size, seq_len]
Args:
            sentences: (Variable, LongTensor) [num_sentences + batch_size, seq_len]
            target_sentences: (Variable, LongTensor) [num_sentences, seq_len]
        Return:
            decoder_outputs: (Variable, FloatTensor)
                - train: [batch_size, seq_len, vocab_size]
                - eval: [batch_size, seq_len]
Args : sentences : ( Variable LongTensor ) [ num_sentences + batch_size seq_len ] target_sentences : ( Variable LongTensor ) [ num_sentences seq_len ] Return : decoder_outputs : ( Variable FloatTensor ) - train : [ batch_size seq_len vocab_size ] - eval : [ batch_size seq_len ]
def forward(self, sentences, sentence_length,
                input_conversation_length, target_sentences, decode=False):
        """
        Args:
            sentences: (Variable, LongTensor) [num_sentences + batch_size, seq_len]
            target_sentences: (Variable, LongTensor) [num_sentences, seq_len]
        Return:
            decoder_outputs: (Variable, FloatTensor)
                - train: [batch_size, seq_len, vocab_size]
                - eval: [batch_size, seq_len]
        """
        batch_size = input_conversation_length.size(0)
        num_sentences = sentences.size(0) - batch_size
        max_len = input_conversation_length.data.max().item()

        # encoder_outputs: [num_sentences + batch_size, max_source_length, hidden_size]
        # encoder_hidden: [num_layers * direction, num_sentences + batch_size, hidden_size]
        encoder_outputs, encoder_hidden = self.encoder(sentences,
                                                       sentence_length)

        # encoder_hidden: [num_sentences + batch_size, num_layers * direction * hidden_size]
        encoder_hidden = encoder_hidden.transpose(
            1, 0).contiguous().view(num_sentences + batch_size, -1)

        # pad and pack encoder_hidden
        start = torch.cumsum(torch.cat((to_var(input_conversation_length.data.new(1).zero_()),
                                        input_conversation_length[:-1] + 1)), 0)
        # encoder_hidden: [batch_size, max_len + 1, num_layers * direction * hidden_size]
        encoder_hidden = torch.stack([pad(encoder_hidden.narrow(0, s, l + 1), max_len + 1)
                                      for s, l in zip(start.data.tolist(),
                                                      input_conversation_length.data.tolist())], 0)

        # encoder_hidden_inference: [batch_size, max_len, num_layers * direction * hidden_size]
        encoder_hidden_inference = encoder_hidden[:, 1:, :]
        encoder_hidden_inference_flat = torch.cat(
            [encoder_hidden_inference[i, :l, :] for i, l in enumerate(input_conversation_length.data)])

        # encoder_hidden_input: [batch_size, max_len, num_layers * direction * hidden_size]
        encoder_hidden_input = encoder_hidden[:, :-1, :]

        # context_outputs: [batch_size, max_len, context_size]
        context_outputs, context_last_hidden = self.context_encoder(encoder_hidden_input,
                                                                    input_conversation_length)
        # flatten outputs
        # context_outputs: [num_sentences, context_size]
        context_outputs = torch.cat([context_outputs[i, :l, :]
                                     for i, l in enumerate(input_conversation_length.data)])

        mu_prior, var_prior = self.prior(context_outputs)
        eps = to_var(torch.randn((num_sentences, self.config.z_sent_size)))
        if not decode:
            mu_posterior, var_posterior = self.posterior(
                context_outputs, encoder_hidden_inference_flat)
            z_sent = mu_posterior + torch.sqrt(var_posterior) * eps
            log_q_zx = normal_logpdf(z_sent, mu_posterior, var_posterior).sum()

            log_p_z = normal_logpdf(z_sent, mu_prior, var_prior).sum()
            # kl_div: [num_sentneces]
            kl_div = normal_kl_div(mu_posterior, var_posterior,
                                    mu_prior, var_prior)
            kl_div = torch.sum(kl_div)
        else:
            z_sent = mu_prior + torch.sqrt(var_prior) * eps
            kl_div = None
            log_p_z = normal_logpdf(z_sent, mu_prior, var_prior).sum()
            log_q_zx = None

        self.z_sent = z_sent
        latent_context = torch.cat([context_outputs, z_sent], 1)
        decoder_init = self.context2decoder(latent_context)
        decoder_init = decoder_init.view(-1,
                                         self.decoder.num_layers,
                                         self.decoder.hidden_size)
        decoder_init = decoder_init.transpose(1, 0).contiguous()

        # train: [batch_size, seq_len, vocab_size]
        # eval: [batch_size, seq_len]
        if not decode:

            decoder_outputs = self.decoder(target_sentences,
                                           init_h=decoder_init,
                                           decode=decode)

            return decoder_outputs, kl_div, log_p_z, log_q_zx

        else:
            # prediction: [batch_size, beam_size, max_unroll]
            prediction, final_score, length = self.decoder.beam_decode(init_h=decoder_init)

            return prediction, kl_div, log_p_z, log_q_zx
def forward ( self , sentences , sentence_length , input_conversation_length , target_sentences , decode = False ) : batch_size = input_conversation_length . size ( 0 ) num_sentences = sentences . size ( 0 ) - batch_size max_len = input_conversation_length . data . max ( ) . item ( ) # encoder_outputs: [num_sentences + batch_size, max_source_length, hidden_size] # encoder_hidden: [num_layers * direction, num_sentences + batch_size, hidden_size] encoder_outputs , encoder_hidden = self . encoder ( sentences , sentence_length ) # encoder_hidden: [num_sentences + batch_size, num_layers * direction * hidden_size] encoder_hidden = encoder_hidden . transpose ( 1 , 0 ) . contiguous ( ) . view ( num_sentences + batch_size , - 1 ) # pad and pack encoder_hidden start = torch . cumsum ( torch . cat ( ( to_var ( input_conversation_length . data . new ( 1 ) . zero_ ( ) ) , input_conversation_length [ : - 1 ] + 1 ) ) , 0 ) # encoder_hidden: [batch_size, max_len + 1, num_layers * direction * hidden_size] encoder_hidden = torch . stack ( [ pad ( encoder_hidden . narrow ( 0 , s , l + 1 ) , max_len + 1 ) for s , l in zip ( start . data . tolist ( ) , input_conversation_length . data . tolist ( ) ) ] , 0 ) # encoder_hidden_inference: [batch_size, max_len, num_layers * direction * hidden_size] encoder_hidden_inference = encoder_hidden [ : , 1 : , : ] encoder_hidden_inference_flat = torch . cat ( [ encoder_hidden_inference [ i , : l , : ] for i , l in enumerate ( input_conversation_length . data ) ] ) # encoder_hidden_input: [batch_size, max_len, num_layers * direction * hidden_size] encoder_hidden_input = encoder_hidden [ : , : - 1 , : ] # context_outputs: [batch_size, max_len, context_size] context_outputs , context_last_hidden = self . context_encoder ( encoder_hidden_input , input_conversation_length ) # flatten outputs # context_outputs: [num_sentences, context_size] context_outputs = torch . cat ( [ context_outputs [ i , : l , : ] for i , l in enumerate ( input_conversation_length . data ) ] ) mu_prior , var_prior = self . prior ( context_outputs ) eps = to_var ( torch . randn ( ( num_sentences , self . config . z_sent_size ) ) ) if not decode : mu_posterior , var_posterior = self . posterior ( context_outputs , encoder_hidden_inference_flat ) z_sent = mu_posterior + torch . sqrt ( var_posterior ) * eps log_q_zx = normal_logpdf ( z_sent , mu_posterior , var_posterior ) . sum ( ) log_p_z = normal_logpdf ( z_sent , mu_prior , var_prior ) . sum ( ) # kl_div: [num_sentneces] kl_div = normal_kl_div ( mu_posterior , var_posterior , mu_prior , var_prior ) kl_div = torch . sum ( kl_div ) else : z_sent = mu_prior + torch . sqrt ( var_prior ) * eps kl_div = None log_p_z = normal_logpdf ( z_sent , mu_prior , var_prior ) . sum ( ) log_q_zx = None self . z_sent = z_sent latent_context = torch . cat ( [ context_outputs , z_sent ] , 1 ) decoder_init = self . context2decoder ( latent_context ) decoder_init = decoder_init . view ( - 1 , self . decoder . num_layers , self . decoder . hidden_size ) decoder_init = decoder_init . transpose ( 1 , 0 ) . contiguous ( ) # train: [batch_size, seq_len, vocab_size] # eval: [batch_size, seq_len] if not decode : decoder_outputs = self . decoder ( target_sentences , init_h = decoder_init , decode = decode ) return decoder_outputs , kl_div , log_p_z , log_q_zx else : # prediction: [batch_size, beam_size, max_unroll] prediction , final_score , length = self . decoder . beam_decode ( init_h = decoder_init ) return prediction , kl_div , log_p_z , log_q_zx