From 203d2ea8300cc9ca9f6f529e3546a6ccd9a14533 Mon Sep 17 00:00:00 2001 From: Matthew Honnibal Date: Sun, 21 Jan 2018 19:37:02 +0100 Subject: [PATCH] Allow multitask objectives to be added to the parser and NER more easily --- spacy/pipeline.pyx | 20 ++++++++++++-------- spacy/syntax/nn_parser.pyx | 9 ++++++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/spacy/pipeline.pyx b/spacy/pipeline.pyx index 11e7df3d1..4b64401cd 100644 --- a/spacy/pipeline.pyx +++ b/spacy/pipeline.pyx @@ -881,15 +881,17 @@ cdef class DependencyParser(Parser): @property def postprocesses(self): return [nonproj.deprojectivize] + + def add_multitask_objective(self, target): + labeller = MultitaskObjective(self.vocab, target=target) + self._multitasks.append(labeller) def init_multitask_objectives(self, gold_tuples, pipeline, sgd=None, **cfg): - for target in []: - labeller = MultitaskObjective(self.vocab, target=target) + for labeller in self._multitasks: tok2vec = self.model[0] labeller.begin_training(gold_tuples, pipeline=pipeline, tok2vec=tok2vec, sgd=sgd) - pipeline.append(labeller) - self._multitasks.append(labeller) + pipeline.append((labeller.name, labeller)) def __reduce__(self): return (DependencyParser, (self.vocab, self.moves, self.model), @@ -901,15 +903,17 @@ cdef class EntityRecognizer(Parser): TransitionSystem = BiluoPushDown nr_feature = 6 + + def add_multitask_objective(self, target): + labeller = MultitaskObjective(self.vocab, target=target) + self._multitasks.append(labeller) def init_multitask_objectives(self, gold_tuples, pipeline, sgd=None, **cfg): - for target in []: - labeller = MultitaskObjective(self.vocab, target=target) + for labeller in self._multitasks: tok2vec = self.model[0] labeller.begin_training(gold_tuples, pipeline=pipeline, tok2vec=tok2vec) - pipeline.append(labeller) - self._multitasks.append(labeller) + pipeline.append((labeller.name, labeller)) def __reduce__(self): return (EntityRecognizer, (self.vocab, self.moves, self.model), diff --git a/spacy/syntax/nn_parser.pyx b/spacy/syntax/nn_parser.pyx index bb01cecf1..4a8e14e12 100644 --- a/spacy/syntax/nn_parser.pyx +++ b/spacy/syntax/nn_parser.pyx @@ -269,9 +269,6 @@ cdef class Parser: zero_init(Affine(nr_class, hidden_width, drop_factor=0.0)) ) - # TODO: This is an unfortunate hack atm! - # Used to set input dimensions in network. - lower.begin_training(lower.ops.allocate((500, token_vector_width))) cfg = { 'nr_class': nr_class, 'hidden_depth': depth, @@ -840,8 +837,14 @@ cdef class Parser: self.cfg.update(cfg) elif sgd is None: sgd = self.create_optimizer() + self.model[1].begin_training( + self.model[1].ops.allocate((5, cfg['token_vector_width']))) return sgd + def add_multitask_objective(self, target): + # Defined in subclasses, to avoid circular import + raise NotImplementedError + def init_multitask_objectives(self, gold_tuples, pipeline, **cfg): '''Setup models for secondary objectives, to benefit from multi-task learning. This method is intended to be overridden by subclasses.