(self, input_sentences, input_sentence_length,
                input_conversation_length, target_sentences, decode=False)
Args:
            input_sentences: (Variable, LongTensor) [num_sentences, 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:
            input_sentences: (Variable, LongTensor) [num_sentences, 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 : input_sentences : ( Variable LongTensor ) [ num_sentences 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, input_sentences, input_sentence_length,
                input_conversation_length, target_sentences, decode=False):
        """
        Args:
            input_sentences: (Variable, LongTensor) [num_sentences, 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]
        """
        num_sentences = input_sentences.size(0)
        max_len = input_conversation_length.data.max().item()

        # encoder_outputs: [num_sentences, max_source_length, hidden_size * direction]
        # encoder_hidden: [num_layers * direction, num_sentences, hidden_size]
        encoder_outputs, encoder_hidden = self.encoder(input_sentences,
                                                       input_sentence_length)

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

        # pad and pack encoder_hidden
        start = torch.cumsum(torch.cat((to_var(input_conversation_length.data.new(1).zero_()),
                                        input_conversation_length[:-1])), 0)

        # encoder_hidden: [batch_size, max_len, num_layers * direction * hidden_size]
        encoder_hidden = torch.stack([pad(encoder_hidden.narrow(0, s, l), max_len)
                                      for s, l in zip(start.data.tolist(),
                                                      input_conversation_length.data.tolist())], 0)

        # context_outputs: [batch_size, max_len, context_size]
        context_outputs, context_last_hidden = self.context_encoder(encoder_hidden,
                                                                    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)])

        # project context_outputs to decoder init state
        decoder_init = self.context2decoder(context_outputs)

        # [num_layers, batch_size, hidden_size]
        decoder_init = decoder_init.view(self.decoder.num_layers, -1, self.decoder.hidden_size)

        # 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

        else:
            # decoder_outputs = self.decoder(target_sentences,
            #                                init_h=decoder_init,
            #                                decode=decode)
            # return decoder_outputs.unsqueeze(1)
            # prediction: [batch_size, beam_size, max_unroll]
            prediction, final_score, length = self.decoder.beam_decode(init_h=decoder_init)

            # Get top prediction only
            # [batch_size, max_unroll]
            # prediction = prediction[:, 0]

            # [batch_size, beam_size, max_unroll]
            return prediction
def forward ( self , input_sentences , input_sentence_length , input_conversation_length , target_sentences , decode = False ) : num_sentences = input_sentences . size ( 0 ) max_len = input_conversation_length . data . max ( ) . item ( ) # encoder_outputs: [num_sentences, max_source_length, hidden_size * direction] # encoder_hidden: [num_layers * direction, num_sentences, hidden_size] encoder_outputs , encoder_hidden = self . encoder ( input_sentences , input_sentence_length ) # encoder_hidden: [num_sentences, num_layers * direction * hidden_size] encoder_hidden = encoder_hidden . transpose ( 1 , 0 ) . contiguous ( ) . view ( num_sentences , - 1 ) # pad and pack encoder_hidden start = torch . cumsum ( torch . cat ( ( to_var ( input_conversation_length . data . new ( 1 ) . zero_ ( ) ) , input_conversation_length [ : - 1 ] ) ) , 0 ) # encoder_hidden: [batch_size, max_len, num_layers * direction * hidden_size] encoder_hidden = torch . stack ( [ pad ( encoder_hidden . narrow ( 0 , s , l ) , max_len ) for s , l in zip ( start . data . tolist ( ) , input_conversation_length . data . tolist ( ) ) ] , 0 ) # context_outputs: [batch_size, max_len, context_size] context_outputs , context_last_hidden = self . context_encoder ( encoder_hidden , 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 ) ] ) # project context_outputs to decoder init state decoder_init = self . context2decoder ( context_outputs ) # [num_layers, batch_size, hidden_size] decoder_init = decoder_init . view ( self . decoder . num_layers , - 1 , self . decoder . hidden_size ) # 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 else : # decoder_outputs = self.decoder(target_sentences, #                                init_h=decoder_init, #                                decode=decode) # return decoder_outputs.unsqueeze(1) # prediction: [batch_size, beam_size, max_unroll] prediction , final_score , length = self . decoder . beam_decode ( init_h = decoder_init ) # Get top prediction only # [batch_size, max_unroll] # prediction = prediction[:, 0] # [batch_size, beam_size, max_unroll] return prediction