(self, feats)
return torch.cat(tags, 1)
Uses Viterbi algorithm to predict the best sequence
        Parameters:
            feats: Input features [batch size, sequence length, number of tags]
        Returns: Best tag sequence [batch size, sequence length]
Uses Viterbi algorithm to predict the best sequence
        Parameters:
            feats: Input features [batch size, sequence length, number of tags]
        Returns: Best tag sequence [batch size, sequence length]
Uses Viterbi algorithm to predict the best sequence Parameters : feats : Input features [ batch size sequence length number of tags ] Returns : Best tag sequence [ batch size sequence length ]
def _viterbi(self, feats):
        """
        Uses Viterbi algorithm to predict the best sequence
        Parameters:
            feats: Input features [batch size, sequence length, number of tags]
        Returns: Best tag sequence [batch size, sequence length]
        """
        _, seq_size, num_tags = feats.shape

        if self.num_tags != num_tags:
            raise ValueError('num_tags should be {} but got {}'.format(self.num_tags, num_tags))
        
        v = feats[:, 0] + self.start_transitions.unsqueeze(0) # [batch_size, num_tags]
        transitions = self.transitions.unsqueeze(0) # [1, num_tags, num_tags] from -> to
        paths = []

        for i in range(1, seq_size):
            feat = feats[:, i] # [batch_size, num_tags]
            v, idx = (v.unsqueeze(-1) + transitions).max(1) # [batch_size, num_tags], [batch_size, num_tags]
            
            paths.append(idx)
            v = (v + feat) # [batch_size, num_tags]

        
        v, tag = (v + self.stop_transitions.unsqueeze(0)).max(1, True)

        # Backtrack
        tags = [tag]
        for idx in reversed(paths):
            tag = idx.gather(1, tag)
            tags.append(tag)

        tags.reverse()
        return torch.cat(tags, 1)
def _viterbi ( self , feats ) : _ , seq_size , num_tags = feats . shape if self . num_tags != num_tags : raise ValueError ( 'num_tags should be {} but got {}' . format ( self . num_tags , num_tags ) ) v = feats [ : , 0 ] + self . start_transitions . unsqueeze ( 0 ) # [batch_size, num_tags] transitions = self . transitions . unsqueeze ( 0 ) # [1, num_tags, num_tags] from -> to paths = [ ] for i in range ( 1 , seq_size ) : feat = feats [ : , i ] # [batch_size, num_tags] v , idx = ( v . unsqueeze ( - 1 ) + transitions ) . max ( 1 ) # [batch_size, num_tags], [batch_size, num_tags] paths . append ( idx ) v = ( v + feat ) # [batch_size, num_tags] v , tag = ( v + self . stop_transitions . unsqueeze ( 0 ) ) . max ( 1 , True ) # Backtrack tags = [ tag ] for idx in reversed ( paths ) : tag = idx . gather ( 1 , tag ) tags . append ( tag ) tags . reverse ( ) return torch . cat ( tags , 1 )