{"action":"created","comment":{"url":"https://api.github.com/repos/allenai/allennlp/pulls/comments/186894198","pull_request_review_id":118565203,"id":186894198,"diff_hunk":"@@ -0,0 +1,322 @@\n+import logging\n+import os\n+from typing import Dict, List, Tuple\n+\n+from overrides import overrides\n+import torch\n+from torch.autograd import Variable\n+\n+from allennlp.common import Params\n+from allennlp.data import Vocabulary\n+from allennlp.data.fields.production_rule_field import ProductionRuleArray\n+from allennlp.models.model import Model\n+from allennlp.models.archival import load_archive, Archive\n+from allennlp.models.semantic_parsing.wikitables.wikitables_decoder_state import WikiTablesDecoderState\n+from allennlp.models.semantic_parsing.wikitables.wikitables_semantic_parser import WikiTablesSemanticParser\n+from allennlp.modules import TextFieldEmbedder, Seq2SeqEncoder, FeedForward\n+from allennlp.modules.seq2vec_encoders import Seq2VecEncoder\n+from allennlp.modules.similarity_functions import SimilarityFunction\n+from allennlp.nn.decoding.decoder_trainers import ExpectedRiskMinimization\n+from allennlp.semparse import ParsingError\n+from allennlp.semparse.worlds import WikiTablesWorld\n+\n+logger = logging.getLogger(__name__)  # pylint: disable=invalid-name\n+\n+\n+@Model.register(\"wikitables_erm_parser\")\n+class WikiTablesErmSemanticParser(WikiTablesSemanticParser):\n+    \"\"\"\n+    A ``WikiTablesErmSemanticParser`` is a :class:`WikiTablesSemanticParser` that learns to search\n+    for logical forms that yield the correct denotations.\n+\n+    Parameters\n+    ----------\n+    vocab : ``Vocabulary``\n+    question_embedder : ``TextFieldEmbedder``\n+        Embedder for questions. Passed to super class.\n+    action_embedding_dim : ``int``\n+        Dimension to use for action embeddings. Passed to super class.\n+    encoder : ``Seq2SeqEncoder``\n+        The encoder to use for the input question. Passed to super class.\n+    entity_encoder : ``Seq2VecEncoder``\n+        The encoder to used for averaging the words of an entity. Passed to super class.\n+    attention_function : ``SimilarityFunction``\n+        We compute an attention over the input question at each step of the decoder, using the\n+        decoder hidden state as the query.  This is the similarity function we use for that\n+        attention. Passed to super class.\n+    decoder_beam_size : ``int``\n+        Beam size to be used by the ExpectedRiskMinimization algorithm.\n+    max_decoding_steps : ``int``\n+        Maximum number of steps the decoder should take before giving up. Used both during training\n+        and evaluation. Passed to super class.\n+    normalize_beam_score_by_length : ``bool``, optional (default=False)\n+        Should we normalize the log-probabilities by length before renormalizing the beam? This was\n+        shown to work better for NML by Edunov et al., but that many not be the case for semantic\n+        parsing.\n+    use_neighbor_similarity_for_linking : ``bool``, optional (default=False)\n+        If ``True``, we will compute a max similarity between a question token and the `neighbors`\n+        of an entity as a component of the linking scores.  This is meant to capture the same kind\n+        of information as the ``related_column`` feature. Passed to super class.\n+    dropout : ``float``, optional (default=0)\n+        If greater than 0, we will apply dropout with this probability after all encoders (pytorch\n+        LSTMs do not apply dropout to their last layer). Passed to super class.\n+    num_linking_features : ``int``, optional (default=10)\n+        We need to construct a parameter vector for the linking features, so we need to know how\n+        many there are.  The default of 10 here matches the default in the ``KnowledgeGraphField``,\n+        which is to use all ten defined features. If this is 0, another term will be added to the\n+        linking score. This term contains the maximum similarity value from the entity's neighbors\n+        and the question. Passed to super class.\n+    rule_namespace : ``str``, optional (default=rule_labels)\n+        The vocabulary namespace to use for production rules.  The default corresponds to the\n+        default used in the dataset reader, so you likely don't need to modify this. Passed to super\n+        class.\n+    tables_directory : ``str``, optional (default=/wikitables/)\n+        The directory to find tables when evaluating logical forms.  We rely on a call to SEMPRE to\n+        evaluate logical forms, and SEMPRE needs to read the table from disk itself.  This tells\n+        SEMPRE where to find the tables. Passed to super class.\n+    initial_mml_model_file : ``str``, optional (default=None)\n+        If you want to initialize this model using weights from another model trained using MML,\n+        pass the path to the ``model.tar.gz`` file of that model here.\n+    \"\"\"\n+    def __init__(self,\n+                 vocab: Vocabulary,\n+                 question_embedder: TextFieldEmbedder,\n+                 action_embedding_dim: int,\n+                 encoder: Seq2SeqEncoder,\n+                 entity_encoder: Seq2VecEncoder,\n+                 mixture_feedforward: FeedForward,\n+                 attention_function: SimilarityFunction,\n+                 decoder_beam_size: int,\n+                 max_decoding_steps: int,\n+                 normalize_beam_score_by_length: bool = False,\n+                 use_neighbor_similarity_for_linking: bool = False,\n+                 dropout: float = 0.0,\n+                 num_linking_features: int = 10,\n+                 rule_namespace: str = 'rule_labels',\n+                 tables_directory: str = '/wikitables/',\n+                 initial_mml_model_file: str = None) -> None:\n+        use_similarity = use_neighbor_similarity_for_linking\n+        super(WikiTablesErmSemanticParser, self).__init__(vocab=vocab,\n+                                                          question_embedder=question_embedder,\n+                                                          action_embedding_dim=action_embedding_dim,\n+                                                          encoder=encoder,\n+                                                          entity_encoder=entity_encoder,\n+                                                          mixture_feedforward=mixture_feedforward,\n+                                                          max_decoding_steps=max_decoding_steps,\n+                                                          attention_function=attention_function,\n+                                                          use_neighbor_similarity_for_linking=use_similarity,\n+                                                          dropout=dropout,\n+                                                          num_linking_features=num_linking_features,\n+                                                          rule_namespace=rule_namespace,\n+                                                          tables_directory=tables_directory)\n+        # Not sure why mypy needs a type annotation for this!\n+        self._decoder_trainer: ExpectedRiskMinimization = \\\n+                ExpectedRiskMinimization(beam_size=decoder_beam_size,\n+                                         normalize_by_length=normalize_beam_score_by_length,\n+                                         max_decoding_steps=self._max_decoding_steps)\n+        # TODO (pradeep): Checking whether file exists here to avoid raising an error when we've\n+        # copied a trained ERM model from a different machine and the original MML model that was\n+        # used to initialize it does not exist on the current machine. This may not be the best\n+        # solution for the problem.\n+        if initial_mml_model_file is not None:\n+            if os.path.isfile(initial_mml_model_file):\n+                archive = load_archive(initial_mml_model_file)\n+                self._initialize_weights_from_archive(archive)\n+            else:\n+                # A model file is passed, but it does not exist. This is expected to happen when\n+                # you're using a trained ERM model to decode. But it may also happen if the path to\n+                # the file is really just incorrect. So throwing a warning.\n+                logger.warning(\"MML model file for initializing weights is passed, but does not exist.\"\n+                               \" This is fine if you're just decoding.\")\n+\n+    def _initialize_weights_from_archive(self, archive: Archive) -> None:\n+        logger.info(\"Initializing weights from MML model.\")\n+        model_parameters = dict(self.named_parameters())\n+        archived_parameters = dict(archive.model.named_parameters())\n+        question_embedder_weight = \"_question_embedder.token_embedder_tokens.weight\"\n+        if question_embedder_weight not in archived_parameters or \\\n+           question_embedder_weight not in model_parameters:\n+            raise RuntimeError(\"When initializing model weights from an MML model, we need \"\n+                               \"the question embedder to be a TokenEmbedder using namespace called \"\n+                               \"tokens.\")\n+        for name, weights in archived_parameters.items():\n+            if name in model_parameters:\n+                if name == question_embedder_weight:\n+                    # The shapes of embedding weights will most likely differ between the two models\n+                    # because the vocabularies will most likely be different. We will get a mapping\n+                    # of indices from this model's token indices to the archived model's and copy\n+                    # the tensor accordingly.\n+                    vocab_index_mapping = self._get_vocab_index_mapping(archive.model.vocab)\n+                    archived_embedding_weights = weights.data\n+                    new_weights = model_parameters[name].data.clone()\n+                    for index, archived_index in vocab_index_mapping:\n+                        new_weights[index] = archived_embedding_weights[archived_index]\n+                    logger.info(\"Copied embeddings of %d out of %d tokens\",\n+                                len(vocab_index_mapping), new_weights.size()[0])\n+                else:\n+                    new_weights = weights.data\n+                logger.info(\"Copying parameter %s\", name)\n+                model_parameters[name].data.copy_(new_weights)\n+\n+    def _get_vocab_index_mapping(self, archived_vocab: Vocabulary) -> List[Tuple[int, int]]:\n+        vocab_index_mapping: List[Tuple[int, int]] = []\n+        for index in range(self.vocab.get_vocab_size(namespace='tokens')):\n+            token = self.vocab.get_token_from_index(index=index, namespace='tokens')\n+            archived_token_index = archived_vocab.get_token_index(token, namespace='tokens')\n+            # Checking if we got the UNK token index, because we don't want all new token\n+            # representations initialized to UNK token's representation. We do that by checking if\n+            # the two tokens are the same. They will not be if the token at the archived index is\n+            # UNK.\n+            if archived_vocab.get_token_from_index(archived_token_index, namespace=\"tokens\") == token:\n+                vocab_index_mapping.append((index, archived_token_index))\n+        return vocab_index_mapping\n+\n+    @overrides\n+    def forward(self,  # type: ignore\n+                question: Dict[str, torch.LongTensor],\n+                table: Dict[str, torch.LongTensor],\n+                world: List[WikiTablesWorld],\n+                actions: List[List[ProductionRuleArray]],\n+                example_lisp_string: List[str]) -> Dict[str, torch.Tensor]:\n+        # pylint: disable=arguments-differ\n+        # pylint: disable=unused-argument\n+        \"\"\"\n+        Parameters\n+        ----------\n+        question : Dict[str, torch.LongTensor]\n+           The output of ``TextField.as_array()`` applied on the question ``TextField``. This will\n+           be passed through a ``TextFieldEmbedder`` and then through an encoder.\n+        table : ``Dict[str, torch.LongTensor]``\n+            The output of ``KnowledgeGraphField.as_array()`` applied on the table\n+            ``KnowledgeGraphField``.  This output is similar to a ``TextField`` output, where each\n+            entity in the table is treated as a \"token\", and we will use a ``TextFieldEmbedder`` to\n+            get embeddings for each entity.\n+        world : ``List[WikiTablesWorld]``\n+            We use a ``MetadataField`` to get the ``World`` for each input instance.  Because of\n+            how ``MetadataField`` works, this gets passed to us as a ``List[WikiTablesWorld]``,\n+        actions : ``List[List[ProductionRuleArray]]``\n+            A list of all possible actions for each ``World`` in the batch, indexed into a\n+            ``ProductionRuleArray`` using a ``ProductionRuleField``.  We will embed all of these\n+            and use the embeddings to determine which action to take at each timestep in the\n+            decoder.\n+        example_lisp_string : ``List[str]``\n+            The example (lisp-formatted) string corresponding to the given input.  This comes\n+            directly from the ``.examples`` file provided with the dataset.  We pass this to SEMPRE\n+            when evaluating denotation accuracy; it is otherwise unused.\n+        target_action_sequences : torch.Tensor, optional (default=None)\n+           A list of possibly valid action sequences, where each action is an index into the list\n+           of possible actions.  This tensor has shape ``(batch_size, num_action_sequences,\n+           sequence_length)``.\n+        \"\"\"\n+        initial_info = self._get_initial_state_and_scores(question=question,\n+                                                          table=table,\n+                                                          world=world,\n+                                                          actions=actions,\n+                                                          example_lisp_string=example_lisp_string,\n+                                                          add_world_to_initial_state=True)\n+        initial_state = initial_info[\"initial_state\"]\n+        # TODO(pradeep): Keep track of debug info. It's not straightforward currently because the\n+        # ERM's decode does not return the best states.\n+        outputs = self._decoder_trainer.decode(initial_state,\n+                                               self._decoder_step,\n+                                               self._get_state_cost)\n+        if not self.training:\n+            linking_scores = initial_info[\"linking_scores\"]","path":"allennlp/models/semantic_parsing/wikitables/wikitables_erm_semantic_parser.py","position":224,"original_position":224,"commit_id":"b6b74b6e4cc1228dc5c9f9a02e362cd75cfdbaf5","original_commit_id":"b6b74b6e4cc1228dc5c9f9a02e362cd75cfdbaf5","user":{"login":"pdasigi","id":3508113,"avatar_url":"https://avatars2.githubusercontent.com/u/3508113?v=4","gravatar_id":"","url":"https://api.github.com/users/pdasigi","html_url":"https://github.com/pdasigi","followers_url":"https://api.github.com/users/pdasigi/followers","following_url":"https://api.github.com/users/pdasigi/following{/other_user}","gists_url":"https://api.github.com/users/pdasigi/gists{/gist_id}","starred_url":"https://api.github.com/users/pdasigi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdasigi/subscriptions","organizations_url":"https://api.github.com/users/pdasigi/orgs","repos_url":"https://api.github.com/users/pdasigi/repos","events_url":"https://api.github.com/users/pdasigi/events{/privacy}","received_events_url":"https://api.github.com/users/pdasigi/received_events","type":"User","site_admin":false},"body":"The next PR adds agenda coverage computation which makes this block different between the two classes. But I agree that some of these lines can be shared. I added a TODO for this.","created_at":"2018-05-08T23:14:37Z","updated_at":"2018-05-08T23:14:37Z","html_url":"https://github.com/allenai/allennlp/pull/1159#discussion_r186894198","pull_request_url":"https://api.github.com/repos/allenai/allennlp/pulls/1159","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/comments/186894198"},"html":{"href":"https://github.com/allenai/allennlp/pull/1159#discussion_r186894198"},"pull_request":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/1159"}},"in_reply_to_id":186812251},"pull_request":{"url":"https://api.github.com/repos/allenai/allennlp/pulls/1159","id":184748489,"html_url":"https://github.com/allenai/allennlp/pull/1159","diff_url":"https://github.com/allenai/allennlp/pull/1159.diff","patch_url":"https://github.com/allenai/allennlp/pull/1159.patch","issue_url":"https://api.github.com/repos/allenai/allennlp/issues/1159","number":1159,"state":"open","locked":false,"title":"ERM parser for wikitables","user":{"login":"pdasigi","id":3508113,"avatar_url":"https://avatars2.githubusercontent.com/u/3508113?v=4","gravatar_id":"","url":"https://api.github.com/users/pdasigi","html_url":"https://github.com/pdasigi","followers_url":"https://api.github.com/users/pdasigi/followers","following_url":"https://api.github.com/users/pdasigi/following{/other_user}","gists_url":"https://api.github.com/users/pdasigi/gists{/gist_id}","starred_url":"https://api.github.com/users/pdasigi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdasigi/subscriptions","organizations_url":"https://api.github.com/users/pdasigi/orgs","repos_url":"https://api.github.com/users/pdasigi/repos","events_url":"https://api.github.com/users/pdasigi/events{/privacy}","received_events_url":"https://api.github.com/users/pdasigi/received_events","type":"User","site_admin":false},"body":"This PR adds a wikitables parser that uses ERM to train. Like with nlvr, I split the existing wikitables parser into two parsers: `WikiTablesMmlParser` and `WikiTablesErmParser`, and kept the common functionality in a base class called `WikiTablesParser`. The ERM parser does not have coverage implemented yet. The cost is currently defined only based on denotation errors. I'll open a separate pr for agenda coverage.","created_at":"2018-04-27T23:32:29Z","updated_at":"2018-05-08T23:14:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6af91e067c44283e1153c231938639ddcb0695e1","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/allenai/allennlp/pulls/1159/commits","review_comments_url":"https://api.github.com/repos/allenai/allennlp/pulls/1159/comments","review_comment_url":"https://api.github.com/repos/allenai/allennlp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/allenai/allennlp/issues/1159/comments","statuses_url":"https://api.github.com/repos/allenai/allennlp/statuses/b6b74b6e4cc1228dc5c9f9a02e362cd75cfdbaf5","head":{"label":"pdasigi:wikitables_erm","ref":"wikitables_erm","sha":"b6b74b6e4cc1228dc5c9f9a02e362cd75cfdbaf5","user":{"login":"pdasigi","id":3508113,"avatar_url":"https://avatars2.githubusercontent.com/u/3508113?v=4","gravatar_id":"","url":"https://api.github.com/users/pdasigi","html_url":"https://github.com/pdasigi","followers_url":"https://api.github.com/users/pdasigi/followers","following_url":"https://api.github.com/users/pdasigi/following{/other_user}","gists_url":"https://api.github.com/users/pdasigi/gists{/gist_id}","starred_url":"https://api.github.com/users/pdasigi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdasigi/subscriptions","organizations_url":"https://api.github.com/users/pdasigi/orgs","repos_url":"https://api.github.com/users/pdasigi/repos","events_url":"https://api.github.com/users/pdasigi/events{/privacy}","received_events_url":"https://api.github.com/users/pdasigi/received_events","type":"User","site_admin":false},"repo":{"id":101232158,"name":"allennlp","full_name":"pdasigi/allennlp","owner":{"login":"pdasigi","id":3508113,"avatar_url":"https://avatars2.githubusercontent.com/u/3508113?v=4","gravatar_id":"","url":"https://api.github.com/users/pdasigi","html_url":"https://github.com/pdasigi","followers_url":"https://api.github.com/users/pdasigi/followers","following_url":"https://api.github.com/users/pdasigi/following{/other_user}","gists_url":"https://api.github.com/users/pdasigi/gists{/gist_id}","starred_url":"https://api.github.com/users/pdasigi/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pdasigi/subscriptions","organizations_url":"https://api.github.com/users/pdasigi/orgs","repos_url":"https://api.github.com/users/pdasigi/repos","events_url":"https://api.github.com/users/pdasigi/events{/privacy}","received_events_url":"https://api.github.com/users/pdasigi/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/pdasigi/allennlp","description":"An open-source NLP research library, built on PyTorch.","fork":true,"url":"https://api.github.com/repos/pdasigi/allennlp","forks_url":"https://api.github.com/repos/pdasigi/allennlp/forks","keys_url":"https://api.github.com/repos/pdasigi/allennlp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pdasigi/allennlp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pdasigi/allennlp/teams","hooks_url":"https://api.github.com/repos/pdasigi/allennlp/hooks","issue_events_url":"https://api.github.com/repos/pdasigi/allennlp/issues/events{/number}","events_url":"https://api.github.com/repos/pdasigi/allennlp/events","assignees_url":"https://api.github.com/repos/pdasigi/allennlp/assignees{/user}","branches_url":"https://api.github.com/repos/pdasigi/allennlp/branches{/branch}","tags_url":"https://api.github.com/repos/pdasigi/allennlp/tags","blobs_url":"https://api.github.com/repos/pdasigi/allennlp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pdasigi/allennlp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pdasigi/allennlp/git/refs{/sha}","trees_url":"https://api.github.com/repos/pdasigi/allennlp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pdasigi/allennlp/statuses/{sha}","languages_url":"https://api.github.com/repos/pdasigi/allennlp/languages","stargazers_url":"https://api.github.com/repos/pdasigi/allennlp/stargazers","contributors_url":"https://api.github.com/repos/pdasigi/allennlp/contributors","subscribers_url":"https://api.github.com/repos/pdasigi/allennlp/subscribers","subscription_url":"https://api.github.com/repos/pdasigi/allennlp/subscription","commits_url":"https://api.github.com/repos/pdasigi/allennlp/commits{/sha}","git_commits_url":"https://api.github.com/repos/pdasigi/allennlp/git/commits{/sha}","comments_url":"https://api.github.com/repos/pdasigi/allennlp/comments{/number}","issue_comment_url":"https://api.github.com/repos/pdasigi/allennlp/issues/comments{/number}","contents_url":"https://api.github.com/repos/pdasigi/allennlp/contents/{+path}","compare_url":"https://api.github.com/repos/pdasigi/allennlp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pdasigi/allennlp/merges","archive_url":"https://api.github.com/repos/pdasigi/allennlp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pdasigi/allennlp/downloads","issues_url":"https://api.github.com/repos/pdasigi/allennlp/issues{/number}","pulls_url":"https://api.github.com/repos/pdasigi/allennlp/pulls{/number}","milestones_url":"https://api.github.com/repos/pdasigi/allennlp/milestones{/number}","notifications_url":"https://api.github.com/repos/pdasigi/allennlp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pdasigi/allennlp/labels{/name}","releases_url":"https://api.github.com/repos/pdasigi/allennlp/releases{/id}","deployments_url":"https://api.github.com/repos/pdasigi/allennlp/deployments","created_at":"2017-08-23T23:05:48Z","updated_at":"2018-04-24T17:20:19Z","pushed_at":"2018-05-08T18:10:36Z","git_url":"git://github.com/pdasigi/allennlp.git","ssh_url":"git@github.com:pdasigi/allennlp.git","clone_url":"https://github.com/pdasigi/allennlp.git","svn_url":"https://github.com/pdasigi/allennlp","homepage":"http://www.allennlp.org/","size":14682,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"allenai:master","ref":"master","sha":"ea2e431cf7672fd1d04bbd382141495bfbc021f7","user":{"login":"allenai","id":5667695,"avatar_url":"https://avatars3.githubusercontent.com/u/5667695?v=4","gravatar_id":"","url":"https://api.github.com/users/allenai","html_url":"https://github.com/allenai","followers_url":"https://api.github.com/users/allenai/followers","following_url":"https://api.github.com/users/allenai/following{/other_user}","gists_url":"https://api.github.com/users/allenai/gists{/gist_id}","starred_url":"https://api.github.com/users/allenai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/allenai/subscriptions","organizations_url":"https://api.github.com/users/allenai/orgs","repos_url":"https://api.github.com/users/allenai/repos","events_url":"https://api.github.com/users/allenai/events{/privacy}","received_events_url":"https://api.github.com/users/allenai/received_events","type":"Organization","site_admin":false},"repo":{"id":91356408,"name":"allennlp","full_name":"allenai/allennlp","owner":{"login":"allenai","id":5667695,"avatar_url":"https://avatars3.githubusercontent.com/u/5667695?v=4","gravatar_id":"","url":"https://api.github.com/users/allenai","html_url":"https://github.com/allenai","followers_url":"https://api.github.com/users/allenai/followers","following_url":"https://api.github.com/users/allenai/following{/other_user}","gists_url":"https://api.github.com/users/allenai/gists{/gist_id}","starred_url":"https://api.github.com/users/allenai/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/allenai/subscriptions","organizations_url":"https://api.github.com/users/allenai/orgs","repos_url":"https://api.github.com/users/allenai/repos","events_url":"https://api.github.com/users/allenai/events{/privacy}","received_events_url":"https://api.github.com/users/allenai/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/allenai/allennlp","description":"An open-source NLP research library, built on PyTorch.","fork":false,"url":"https://api.github.com/repos/allenai/allennlp","forks_url":"https://api.github.com/repos/allenai/allennlp/forks","keys_url":"https://api.github.com/repos/allenai/allennlp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/allenai/allennlp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/allenai/allennlp/teams","hooks_url":"https://api.github.com/repos/allenai/allennlp/hooks","issue_events_url":"https://api.github.com/repos/allenai/allennlp/issues/events{/number}","events_url":"https://api.github.com/repos/allenai/allennlp/events","assignees_url":"https://api.github.com/repos/allenai/allennlp/assignees{/user}","branches_url":"https://api.github.com/repos/allenai/allennlp/branches{/branch}","tags_url":"https://api.github.com/repos/allenai/allennlp/tags","blobs_url":"https://api.github.com/repos/allenai/allennlp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/allenai/allennlp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/allenai/allennlp/git/refs{/sha}","trees_url":"https://api.github.com/repos/allenai/allennlp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/allenai/allennlp/statuses/{sha}","languages_url":"https://api.github.com/repos/allenai/allennlp/languages","stargazers_url":"https://api.github.com/repos/allenai/allennlp/stargazers","contributors_url":"https://api.github.com/repos/allenai/allennlp/contributors","subscribers_url":"https://api.github.com/repos/allenai/allennlp/subscribers","subscription_url":"https://api.github.com/repos/allenai/allennlp/subscription","commits_url":"https://api.github.com/repos/allenai/allennlp/commits{/sha}","git_commits_url":"https://api.github.com/repos/allenai/allennlp/git/commits{/sha}","comments_url":"https://api.github.com/repos/allenai/allennlp/comments{/number}","issue_comment_url":"https://api.github.com/repos/allenai/allennlp/issues/comments{/number}","contents_url":"https://api.github.com/repos/allenai/allennlp/contents/{+path}","compare_url":"https://api.github.com/repos/allenai/allennlp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/allenai/allennlp/merges","archive_url":"https://api.github.com/repos/allenai/allennlp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/allenai/allennlp/downloads","issues_url":"https://api.github.com/repos/allenai/allennlp/issues{/number}","pulls_url":"https://api.github.com/repos/allenai/allennlp/pulls{/number}","milestones_url":"https://api.github.com/repos/allenai/allennlp/milestones{/number}","notifications_url":"https://api.github.com/repos/allenai/allennlp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/allenai/allennlp/labels{/name}","releases_url":"https://api.github.com/repos/allenai/allennlp/releases{/id}","deployments_url":"https://api.github.com/repos/allenai/allennlp/deployments","created_at":"2017-05-15T15:52:41Z","updated_at":"2018-05-08T13:59:58Z","pushed_at":"2018-05-08T22:14:36Z","git_url":"git://github.com/allenai/allennlp.git","ssh_url":"git@github.com:allenai/allennlp.git","clone_url":"https://github.com/allenai/allennlp.git","svn_url":"https://github.com/allenai/allennlp","homepage":"http://www.allennlp.org/","size":10327,"stargazers_count":2024,"watchers_count":2024,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":298,"mirror_url":null,"archived":false,"open_issues_count":70,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":298,"open_issues":70,"watchers":2024,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/1159"},"html":{"href":"https://github.com/allenai/allennlp/pull/1159"},"issue":{"href":"https://api.github.com/repos/allenai/allennlp/issues/1159"},"comments":{"href":"https://api.github.com/repos/allenai/allennlp/issues/1159/comments"},"review_comments":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/1159/comments"},"review_comment":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/allenai/allennlp/pulls/1159/commits"},"statuses":{"href":"https://api.github.com/repos/allenai/allennlp/statuses/b6b74b6e4cc1228dc5c9f9a02e362cd75cfdbaf5"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"pdasigi"}}