Я обучил новую сущность с простором, начиная с немецкой модели. Чтобы избежать катастрофического забвения, я попробовал два подхода.
Подход 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)