(self,
                    init_h=None,
                    encoder_outputs=None, input_valid_length=None,
                    decode=False)
return prediction, final_score, length
Args:
            encoder_outputs (Variable, FloatTensor): [batch_size, source_length, hidden_size]
            input_valid_length (Variable, LongTensor): [batch_size] (optional)
            init_h (variable, FloatTensor): [batch_size, hidden_size] (optional)
        Return:
            out   : [batch_size, seq_len]
Args:
            encoder_outputs (Variable, FloatTensor): [batch_size, source_length, hidden_size]
            input_valid_length (Variable, LongTensor): [batch_size] (optional)
            init_h (variable, FloatTensor): [batch_size, hidden_size] (optional)
        Return:
            out   : [batch_size, seq_len]
Args : encoder_outputs ( Variable FloatTensor ) : [ batch_size source_length hidden_size ] input_valid_length ( Variable LongTensor ) : [ batch_size ] ( optional ) init_h ( variable FloatTensor ) : [ batch_size hidden_size ] ( optional ) Return : out : [ batch_size seq_len ]
def beam_decode(self,
                    init_h=None,
                    encoder_outputs=None, input_valid_length=None,
                    decode=False):
        """
        Args:
            encoder_outputs (Variable, FloatTensor): [batch_size, source_length, hidden_size]
            input_valid_length (Variable, LongTensor): [batch_size] (optional)
            init_h (variable, FloatTensor): [batch_size, hidden_size] (optional)
        Return:
            out   : [batch_size, seq_len]
        """
        batch_size = self.batch_size(h=init_h)

        # [batch_size x beam_size]
        x = self.init_token(batch_size * self.beam_size, SOS_ID)

        # [num_layers, batch_size x beam_size, hidden_size]
        h = self.init_h(batch_size, hidden=init_h).repeat(1, self.beam_size, 1)

        # batch_position [batch_size]
        #   [0, beam_size, beam_size * 2, .., beam_size * (batch_size-1)]
        #   Points where batch starts in [batch_size x beam_size] tensors
        #   Ex. position_idx[5]: when 5-th batch starts
        batch_position = to_var(torch.arange(0, batch_size).long() * self.beam_size)

        # Initialize scores of sequence
        # [batch_size x beam_size]
        # Ex. batch_size: 5, beam_size: 3
        # [0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf]
        score = torch.ones(batch_size * self.beam_size) * -float('inf')
        score.index_fill_(0, torch.arange(0, batch_size).long() * self.beam_size, 0.0)
        score = to_var(score)

        # Initialize Beam that stores decisions for backtracking
        beam = Beam(
            batch_size,
            self.hidden_size,
            self.vocab_size,
            self.beam_size,
            self.max_unroll,
            batch_position)

        for i in range(self.max_unroll):

            # x: [batch_size x beam_size]; (token index)
            # =>
            # out: [batch_size x beam_size, vocab_size]
            # h: [num_layers, batch_size x beam_size, hidden_size]
            out, h = self.forward_step(x, h,
                                       encoder_outputs=encoder_outputs,
                                       input_valid_length=input_valid_length)
            # log_prob: [batch_size x beam_size, vocab_size]
            log_prob = F.log_softmax(out, dim=1)

            # [batch_size x beam_size]
            # => [batch_size x beam_size, vocab_size]
            score = score.view(-1, 1) + log_prob

            # Select `beam size` transitions out of `vocab size` combinations

            # [batch_size x beam_size, vocab_size]
            # => [batch_size, beam_size x vocab_size]
            # Cutoff and retain candidates with top-k scores
            # score: [batch_size, beam_size]
            # top_k_idx: [batch_size, beam_size]
            #       each element of top_k_idx [0 ~ beam x vocab)

            score, top_k_idx = score.view(batch_size, -1).topk(self.beam_size, dim=1)

            # Get token ids with remainder after dividing by top_k_idx
            # Each element is among [0, vocab_size)
            # Ex. Index of token 3 in beam 4
            # (4 * vocab size) + 3 => 3
            # x: [batch_size x beam_size]
            x = (top_k_idx % self.vocab_size).view(-1)

            # top-k-pointer [batch_size x beam_size]
            #       Points top-k beam that scored best at current step
            #       Later used as back-pointer at backtracking
            #       Each element is beam index: 0 ~ beam_size
            #                     + position index: 0 ~ beam_size x (batch_size-1)
            beam_idx = top_k_idx / self.vocab_size  # [batch_size, beam_size]
            top_k_pointer = (beam_idx + batch_position.unsqueeze(1)).view(-1)

            # Select next h (size doesn't change)
            # [num_layers, batch_size * beam_size, hidden_size]
            h = h.index_select(1, top_k_pointer)

            # Update sequence scores at beam
            beam.update(score.clone(), top_k_pointer, x)  # , h)

            # Erase scores for EOS so that they are not expanded
            # [batch_size, beam_size]
            eos_idx = x.data.eq(EOS_ID).view(batch_size, self.beam_size)
            if eos_idx.nonzero().dim() > 0:
                score.data.masked_fill_(eos_idx, -float('inf'))

        # prediction ([batch, k, max_unroll])
        #     A list of Tensors containing predicted sequence
        # final_score [batch, k]
        #     A list containing the final scores for all top-k sequences
        # length [batch, k]
        #     A list specifying the length of each sequence in the top-k candidates
        # prediction, final_score, length = beam.backtrack()
        prediction, final_score, length = beam.backtrack()

        return prediction, final_score, length
def beam_decode ( self , init_h = None , encoder_outputs = None , input_valid_length = None , decode = False ) : batch_size = self . batch_size ( h = init_h ) # [batch_size x beam_size] x = self . init_token ( batch_size * self . beam_size , SOS_ID ) # [num_layers, batch_size x beam_size, hidden_size] h = self . init_h ( batch_size , hidden = init_h ) . repeat ( 1 , self . beam_size , 1 ) # batch_position [batch_size] #   [0, beam_size, beam_size * 2, .., beam_size * (batch_size-1)] #   Points where batch starts in [batch_size x beam_size] tensors #   Ex. position_idx[5]: when 5-th batch starts batch_position = to_var ( torch . arange ( 0 , batch_size ) . long ( ) * self . beam_size ) # Initialize scores of sequence # [batch_size x beam_size] # Ex. batch_size: 5, beam_size: 3 # [0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf, 0, -inf, -inf] score = torch . ones ( batch_size * self . beam_size ) * - float ( 'inf' ) score . index_fill_ ( 0 , torch . arange ( 0 , batch_size ) . long ( ) * self . beam_size , 0.0 ) score = to_var ( score ) # Initialize Beam that stores decisions for backtracking beam = Beam ( batch_size , self . hidden_size , self . vocab_size , self . beam_size , self . max_unroll , batch_position ) for i in range ( self . max_unroll ) : # x: [batch_size x beam_size]; (token index) # => # out: [batch_size x beam_size, vocab_size] # h: [num_layers, batch_size x beam_size, hidden_size] out , h = self . forward_step ( x , h , encoder_outputs = encoder_outputs , input_valid_length = input_valid_length ) # log_prob: [batch_size x beam_size, vocab_size] log_prob = F . log_softmax ( out , dim = 1 ) # [batch_size x beam_size] # => [batch_size x beam_size, vocab_size] score = score . view ( - 1 , 1 ) + log_prob # Select `beam size` transitions out of `vocab size` combinations # [batch_size x beam_size, vocab_size] # => [batch_size, beam_size x vocab_size] # Cutoff and retain candidates with top-k scores # score: [batch_size, beam_size] # top_k_idx: [batch_size, beam_size] #       each element of top_k_idx [0 ~ beam x vocab) score , top_k_idx = score . view ( batch_size , - 1 ) . topk ( self . beam_size , dim = 1 ) # Get token ids with remainder after dividing by top_k_idx # Each element is among [0, vocab_size) # Ex. Index of token 3 in beam 4 # (4 * vocab size) + 3 => 3 # x: [batch_size x beam_size] x = ( top_k_idx % self . vocab_size ) . view ( - 1 ) # top-k-pointer [batch_size x beam_size] #       Points top-k beam that scored best at current step #       Later used as back-pointer at backtracking #       Each element is beam index: 0 ~ beam_size #                     + position index: 0 ~ beam_size x (batch_size-1) beam_idx = top_k_idx / self . vocab_size # [batch_size, beam_size] top_k_pointer = ( beam_idx + batch_position . unsqueeze ( 1 ) ) . view ( - 1 ) # Select next h (size doesn't change) # [num_layers, batch_size * beam_size, hidden_size] h = h . index_select ( 1 , top_k_pointer ) # Update sequence scores at beam beam . update ( score . clone ( ) , top_k_pointer , x ) # , h) # Erase scores for EOS so that they are not expanded # [batch_size, beam_size] eos_idx = x . data . eq ( EOS_ID ) . view ( batch_size , self . beam_size ) if eos_idx . nonzero ( ) . dim ( ) > 0 : score . data . masked_fill_ ( eos_idx , - float ( 'inf' ) ) # prediction ([batch, k, max_unroll]) #     A list of Tensors containing predicted sequence # final_score [batch, k] #     A list containing the final scores for all top-k sequences # length [batch, k] #     A list specifying the length of each sequence in the top-k candidates # prediction, final_score, length = beam.backtrack() prediction , final_score , length = beam . backtrack ( ) return prediction , final_score , length