Exemple #1
0
    def predict_span(self, question: TextField, passage: TextField) -> Dict[str, Any]:
        """
        Given a question and a passage, predicts the span in the passage that answers the question.

        Parameters
        ----------
        question : ``TextField``
        passage : ``TextField``
            A ``TextField`` containing the tokens in the passage.  Note that we typically add
            ``SquadReader.STOP_TOKEN`` as the final token in the passage, because we use exclusive
            span indices.  Be sure you've added that to the passage you pass in here.

        Returns
        -------
        A Dict containing:

        span_start_probs : numpy.ndarray
        span_end_probs : numpy.ndarray
        best_span : (int, int)
        """
        instance = Instance({'question': question, 'passage': passage})
        instance.index_fields(self.vocab)
        model_input = util.arrays_to_variables(instance.as_array_dict(),
                                               add_batch_dimension=True,
                                               for_training=False)
        output_dict = self.forward(**model_input)

        # Here we're just removing the batch dimension and converting things to numpy arrays /
        # tuples instead of pytorch variables.
        return {
                "span_start_probs": output_dict["span_start_probs"].data.squeeze(0).cpu().numpy(),
                "span_end_probs": output_dict["span_end_probs"].data.squeeze(0).cpu().numpy(),
                "best_span": tuple(output_dict["best_span"].data.squeeze(0).cpu().numpy()),
                }
Exemple #2
0
    def forward_on_instance(self,
                            instance: Instance) -> Dict[str, numpy.ndarray]:
        """
        Takes an :class:`~allennlp.data.instance.Instance`, which typically has raw text in it,
        converts that text into arrays using this model's :class:`Vocabulary`, passes those arrays
        through :func:`self.forward()` and :func:`self.decode()` (which by default does nothing)
        and returns the result.  Before returning the result, we convert any ``torch.autograd.Variables``
        or ``torch.Tensors`` into numpy arrays and remove the batch dimension.
        """
        # Hack to see what cuda device the model is on, so we know where to put these inputs.  For
        # complicated models, or machines with multiple GPUs, this will not work.  I couldn't find
        # a way to actually query what device a tensor / parameter is on.
        cuda_device = 0 if next(self.parameters()).is_cuda else -1
        instance.index_fields(self.vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          cuda_device=cuda_device,
                                          for_training=False)
        outputs = self.decode(self.forward(**model_input))

        for name, output in list(outputs.items()):
            output = output[0]
            if isinstance(output, torch.autograd.Variable):
                output = output.data.cpu().numpy()
            outputs[name] = output
        return outputs
    def predict_entailment(self, premise: TextField,
                           hypothesis: TextField) -> Dict[str, torch.Tensor]:
        """
        Given a premise and a hypothesis sentence, predict the entailment relationship between
        them.

        Parameters
        ----------
        premise : ``TextField``
        hypothesis : ``TextField``

        Returns
        -------
        A Dict containing:

        label_probs : torch.FloatTensor
            A tensor of shape ``(num_labels,)`` representing probabilities of the entailment label.
        """
        instance = Instance({"premise": premise, "hypothesis": hypothesis})
        instance.index_fields(self._vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          for_training=False)
        output_dict = self.forward(**model_input)

        # Remove batch dimension, as we only had one input.
        label_probs = output_dict["label_probs"].data.squeeze(0)
        return {'label_probs': label_probs.numpy()}
Exemple #4
0
    def forward_on_instance(
            self,
            instance: Instance,
            cuda_device: int,
            calculate_loss: bool = True) -> Dict[str, numpy.ndarray]:
        """
        Takes an :class:`~allennlp.data.instance.Instance`, which typically has raw text in it,
        converts that text into arrays using this model's :class:`Vocabulary`, passes those arrays
        through :func:`self.forward()` and :func:`self.decode()` (which by default does nothing)
        and returns the result.  Before returning the result, we convert any ``torch.autograd.Variables``
        or ``torch.Tensors`` into numpy arrays and remove the batch dimension.
        """
        instance.index_fields(self.vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          cuda_device=cuda_device,
                                          for_training=False)
        forward_tensors = self.forward(**model_input,
                                       calculate_loss=calculate_loss)
        outputs = self.decode(forward_tensors)

        for name, output in list(outputs.items()):
            output = output[0]
            if isinstance(output, torch.autograd.Variable):
                output = output.data.cpu().numpy()
            elif isinstance(output, torch.Tensor):
                output = output.cpu().numpy()
            outputs[name] = output
        return outputs
Exemple #5
0
    def predict_entailment(self, premise: TextField,
                           hypothesis: TextField) -> Dict[str, torch.Tensor]:
        """
        Given a premise and a hypothesis sentence, predict the entailment relationship between
        them.  Note that in the paper, a null token was appended to each sentence, to allow for
        words to align to nothing in the other sentence.  If you've trained your model with a null
        token, you probably want to include it here, too.

        Parameters
        ----------
        premise : ``TextField``
        hypothesis : ``TextField``

        Returns
        -------
        A Dict containing:

        label_probs : torch.FloatTensor
            A tensor of shape ``(num_labels,)`` representing probabilities of the entailment label.
        """
        instance = Instance({"premise": premise, "hypothesis": hypothesis})
        instance.index_fields(self.vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          for_training=False)
        output_dict = self.forward(**model_input)

        # Remove batch dimension, as we only had one input.
        label_probs = output_dict["label_probs"].data.squeeze(0)
        return {'label_probs': label_probs.numpy()}
    def tag(self, text_field: TextField,
            verb_indicator: IndexField) -> Dict[str, Any]:
        """
        Perform inference on a ``Instance`` consisting of a single ``TextField`` representing
        the sentence and an ``IndexField`` representing an optional index into the sentence
        denoting a verbal predicate.

        Returned sequence is the maximum likelihood tag sequence under the constraint that
        the sequence must be a valid BIO sequence.

        Parameters
        ----------
        text_field : ``TextField``, required.
            A ``TextField`` containing the text to be tagged.
        verb_indicator: ``IndexField``, required.
            The index of the verb whose arguments we are labeling.

        Returns
        -------
        A Dict containing:

        tags : List[str]
            A list the length of the text input, containing the predicted (argmax) tag
            from the model per token.
        class_probabilities : numpy.Array
            An array of shape (text_input_length, num_classes), where each row is a
            distribution over classes for a given token in the sentence.
        """
        instance = Instance({
            "tokens": text_field,
            "verb_indicator": verb_indicator
        })
        instance.index_fields(self.vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          for_training=False)
        output_dict = self.forward(**model_input)

        # Remove batch dimension, as we only had one input.
        predictions = output_dict["class_probabilities"].data.squeeze(0)
        transition_matrix = self.get_viterbi_pairwise_potentials()

        max_likelihood_sequence, _ = viterbi_decode(predictions,
                                                    transition_matrix)
        tags = [
            self.vocab.get_token_from_index(x, namespace="tags")
            for x in max_likelihood_sequence
        ]

        return {"tags": tags, "class_probabilities": predictions.numpy()}
Exemple #7
0
    def tag(self, text_field: TextField) -> Dict[str, Any]:
        """
        Perform inference on a TextField to produce predicted tags and class probabilities
        over the possible tags.

        Parameters
        ----------
        text_field : ``TextField``, required.
            A ``TextField`` containing the text to be tagged.

        Returns
        -------
        A Dict containing:

        tags : List[str]
            A list the length of the text input, containing the predicted (argmax) tag
            from the model per token.
        class_probabilities : numpy.Array
            An array of shape (text_input_length, num_classes), where each row is a
            distribution over classes for a given token in the sentence.
        """
        instance = Instance({'tokens': text_field})
        instance.index_fields(self.vocab)
        model_input = arrays_to_variables(instance.as_array_dict(),
                                          add_batch_dimension=True,
                                          for_training=False)
        output_dict = self.forward(**model_input)

        # Remove batch dimension, as we only had one input.
        predictions = output_dict["class_probabilities"].data.squeeze(0)
        _, argmax = predictions.max(-1)
        indices = argmax.numpy()
        tags = [
            self.vocab.get_token_from_index(x, namespace="labels")
            for x in indices
        ]

        return {"tags": tags, "class_probabilities": predictions.numpy()}