spaCy 3训练自定义NER模型多轮迭代损失值始终为空问题求助
spaCy 3自定义NER训练损失为空的问题原因及修复方案
核心错误原因
- 你创建了
ner管道后,没有将其添加到nlp的处理流水线中,nlp.update执行时没有可训练的组件,因此损失字典始终为空。 - 你提供的训练数据中实体偏移量存在越界问题:第一条样本的总字符长度远小于你标注的89、98等起始位置,无效标注会被spaCy自动过滤,即便管道添加正确也会影响训练效果。
- 代码中缺少
import random语句,执行random.shuffle时会直接报错,不属于损失为空的直接原因,但需要补充。
修复后的完整代码
import spacy import random from spacy.training.example import Example from spacy.util import minibatch, compounding # 注意:请先修正你的TRAIN_DATA中实体偏移量越界的问题 TRAIN_DATA = [ ('text data text data text data text data text data text data text data text data.', {'entities': [(7, 19, 'PERSON')]}), # 这里删除了越界的标注示例,你需要自行校准所有偏移量 ('"text data text data text data text data text data text data text data text data text data text data text data text data.', {'entities': [(119, 137, 'PERSON')]}), ] n_iter = 8 nlp = spacy.blank('en') # 修正点1:创建ner管道后直接添加到流水线 ner = nlp.add_pipe('ner') for _, annotations in TRAIN_DATA: for _s, _e, label in annotations.get('entities', []) : print('Adding label - "', label, '"') ner.add_label(label) other_pipes = [pipe for pipe in nlp.pipe_names if pipe != 'ner'] with nlp.disable_pipes(*other_pipes): optimizer = nlp.begin_training() for itn in range(n_iter): random.shuffle(TRAIN_DATA) losses = {} for batch in spacy.util.minibatch(TRAIN_DATA, size=compounding(4.0, 32.0, 1.001)): for text, annotations in batch: doc = nlp.make_doc(text) example = Example.from_dict(doc, annotations) nlp.update([example], drop=0.35,losses=losses, sgd=optimizer) print('losses -', losses)
额外校准建议
你可以用如下方法验证标注偏移量是否正确:
text = "你的训练样本文本" for s,e,label in entities: print(text[s:e]) # 打印结果必须是你想要标注的实体内容,为空或者内容不对就是偏移量错误
内容的提问来源于stack exchange,提问作者zzzz
相关产品推荐
相关产品推荐

