Пользовательское обучение NER с помощью spaCy 3 вызывает ошибку ValueError

Я пытаюсь добавить собственные метки NER, используя spacy 3. Я нашел учебные пособия для более старых версий и внес изменения для spacy 3. Вот весь код, который я использую:

      import random
import spacy
from spacy.training import Example

LABEL = 'ANIMAL'
TRAIN_DATA = [
    ("Horses are too tall and they pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("Do they bite?", {'entities': []}),
    ("horses are too tall and they pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("horses pretend to care about your feelings", {'entities': [(0, 6, LABEL)]}),
    ("they pretend to care about your feelings, those horses", {'entities': [(48, 54, LABEL)]}),
    ("horses?", {'entities': [(0, 6, LABEL)]})
]
nlp = spacy.load('en_core_web_sm')  # load existing spaCy model
ner = nlp.get_pipe('ner')
ner.add_label(LABEL)
print(ner.move_names) # Here I see, that the new label was added
optimizer = nlp.create_optimizer()
# get names of other pipes to disable them during training
other_pipes = [pipe for pipe in nlp.pipe_names if pipe != "ner"]
with nlp.disable_pipes(*other_pipes):  # only train NER
    for itn in range(20):
        random.shuffle(TRAIN_DATA)
        losses = {}
        for text, annotations in TRAIN_DATA:
            doc = nlp(text)
            example = Example.from_dict(doc, annotations)
            nlp.update([example], drop=0.35, sgd=optimizer, losses=losses)
        print(losses)
# test the trained model # add some dummy sentences with many NERs

test_text = 'Do you like horses?'
doc = nlp(test_text)
print("Entities in '%s'" % test_text)
for ent in doc.ents:
    print(ent.label_, " -- ", ent.text)

Этот код выводит исключение ValueError, но только после 2 итераций - обратите внимание на первые 2 строки:

      {'ner': 9.862242701536594}
{'ner': 8.169456698315201}
Traceback (most recent call last):
  File ".\custom_ner_training.py", line 46, in <module>
    nlp.update([example], drop=0.35, sgd=optimizer, losses=losses)
  File "C:\ogr\moje\python\spacy_pg\myvenv\lib\site-packages\spacy\language.py", line 1106, in update
    proc.update(examples, sgd=None, losses=losses, **component_cfg[name])
  File "spacy\pipeline\transition_parser.pyx", line 366, in spacy.pipeline.transition_parser.Parser.update
  File "spacy\pipeline\transition_parser.pyx", line 478, in spacy.pipeline.transition_parser.Parser.get_batch_loss
  File "spacy\pipeline\_parser_internals\ner.pyx", line 310, in spacy.pipeline._parser_internals.ner.BiluoPushDown.set_costs
ValueError

Я вижу ANIMAL ярлык был добавлен звонком ner.move_names.

Когда я меняю свою ценность LABEL = 'PERSON, код работает успешно и распознает лошадей как PERSONпо новым данным. Вот почему я предполагаю, что в самом коде нет ошибки.

Что-то мне не хватает? Что я делаю не так? Может кто-нибудь воспроизвести, пожалуйста?

ПРИМЕЧАНИЕ. Это мой первый вопрос. Надеюсь, я предоставил всю информацию. Если нет, дайте мне знать в комментариях.

2 ответа

Вам нужно изменить следующую строку в for петля

      doc = nlp(text)

к

      doc = nlp.make_doc(text)

Код должен работать и давать следующие результаты:

      {'ner': 9.60289144264557}
{'ner': 8.875474230820478}
{'ner': 6.370401408220459}
{'ner': 6.687456469517201}
... 
{'ner': 1.3796682589133492e-05}
{'ner': 1.7709562613218738e-05}

Entities in 'Do you like horses?'
ANIMAL  --  horses

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

Другие вопросы по тегам