Катастрофическое забвение в просторах: репетиционная функция - PullRequest
0 голосов
/ 09 мая 2019

Я обучил новую сущность с простором, начиная с немецкой модели. Чтобы избежать катастрофического забвения, я попробовал два подхода.

Подход 1: Псевдо-репетиция Как было предложено в документации по пространству, я попробовал использовать псевдорепетиционный подход и снабдил функцию обновления данными обучения + данными ревизии (данными, содержащими стандартные объекты, которые распознаются). Кажется, что после первой итерации обновления модель забывает стандартные объекты и распознает только новую. Есть ли у вас какие-либо понятия, почему это происходит?

Подход 2: Используйте функцию репетиции В качестве второго подхода я попытался использовать функцию репетиции, дающую в качестве данных репетиции текст со стандартными объектами (без аннотаций). Текст выглядит так:

[Gertrude liebt Katze, Paolo hat gerne Katzen,  Anastasia hat gerne Nudeln]

При вызове функции репетиции я получил следующую ошибку:

  File "test.py", line 226, in <module>
new_model = train_ner(nlp, TRAIN_DATA,rehearse_data, n_iter, LABEL, output_dir, model_name)
  File "test.py", line 112, in train_ner
nlp.rehearse(set(raw_batch), sgd=optimizer, losses=r_losses)
  File "/usr/local/lib/python3.6/dist-packages/spacy/language.py", line 503, in rehearse
    proc.rehearse(docs, sgd=get_grads, losses=losses, **config.get(name, {}))
  File "pipes.pyx", line 450, in spacy.pipeline.pipes.Tagger.rehearse
TypeError: unsupported operand type(s) for -: 'list' and 'list'

Я проверил в pipe.pyx функцию репетиции, где градиент вычисляется как:

Градиент = баллы - цель

Конечно, я не могу вычесть список из списка, но мне кажется, что я не правильно понимаю форму данных репетиции, которую он намеревается использовать для функции. Я также попытался дать помеченные данные репетиции в виде пространных лайков:

rehearse_data = [
("Uber blew through $1 million a week", [(0, 4, 'ORG')]),
("Android Pay expands to Canada", [(0, 11, 'PRODUCT'), (23, 30, 'GPE')]),
("Spotify steps up Asia expansion", [(0, 8, "ORG"), (17, 21, "LOC")]),
("Google Maps launches location sharing", [(0, 11, "PRODUCT")]),
("Google rebrands its business apps", [(0, 6, "ORG")]),
("look what i found on google! ?", [(21, 27, "PRODUCT")])]

и получил следующую ошибку:

  File "test.py", line 228, in <module>
    new_model = train_ner(nlp, TRAIN_DATA,rehearse_data, n_iter, LABEL, output_dir, model_name)
  File "test.py", line 109, in train_ner
raw_batch = [nlp.make_doc(text) for text in list(next(r_batches))]
  File "test.py", line 109, in <listcomp>
raw_batch = [nlp.make_doc(text) for text in list(next(r_batches))]
  File "/usr/local/lib/python3.6/dist-packages/spacy/language.py", line 401, in make_doc
return self.tokenizer(text)
TypeError: Argument 'string' has incorrect type (expected str, got tuple)

Вот мой код:

def train_ner(nlp, train_data, rehearse_data, niter, label, output_dir, model_name):

    random.seed(0)

    # Add entity recognizer to model if it's not in the pipeline

    ner = nlp.get_pipe("ner")
    ner.add_label(label)  # add new entity label to entity recognizer

    # Resume training: we want to train only the new entity 
    optimizer = nlp.resume_training()


    sizes = compounding(1.0, 4.0, 1.001)

    # batch up the examples using spaCy's minibatch
    for itn in range(n_iter):
        print("NITER", itn)
        random.shuffle(train_data)
        random.shuffle(rehearse_data)
        #batches = minibatch(TRAIN_DATA, size=sizes)

        #batches = get_batches(TRAIN_DATA,lang)
        losses = {}
        r_losses = {}

        r_batches = minibatch(rehearse_data,size=4)

        #for batch in batches:
        for batch in minibatch(train_data, size=4):
            print("BATCH",batch)

            texts, annotations = zip(*batch)
            print("TEXTS",type(texts))

            nlp.update(texts, annotations, sgd=optimizer, drop=next(dropout), losses=losses) 

            raw_batch = [nlp.make_doc(text) for text in list(next(r_batches))]
            print("RAW_BATCH",raw_batch)
            nlp.rehearse(set(raw_batch), sgd=optimizer, losses=r_losses)

        print("Losses", losses)
        print("R. Losses", r_losses)

    print(nlp.get_pipe('ner').model.unseen_classes)
...