SpaCy v3中基于en_core_web_sm扩展自定义NER实体如何保留原有实体?
解决SpaCy微调NER时丢失原有预训练实体的问题
你遇到的是典型的模型灾难性遗忘问题——只训练自定义实体的标注,导致模型覆盖了预训练阶段学到的原有实体识别能力。以下是具体解决方法:
1. 补全训练数据中的原有实体标注
模型只会学习你喂给它的标注内容,只提供自定义实体的话,它自然会遗忘旧实体。你需要:
- 在标注数据里,同时标注自定义实体和
en_core_web_sm原本能识别的实体(比如PERSON、ORG、DATE等)。 - 手动标注所有原有实体太耗时的话,可以用预训练模型先自动标注文本,再补充自定义实体:
import spacy from spacy.tokens import DocBin from spacy.tokens import Span nlp = spacy.load("en_core_web_sm") doc_bin = DocBin() # 你的原始训练文本列表 training_texts = ["Sample text with existing entities like Apple (ORG) and John (PERSON), plus custom entity XYZ"] for text in training_texts: doc = nlp(text) # 手动添加自定义实体示例:假设XYZ在文本中的位置是start=45, end=48 custom_span = Span(doc, 45, 48, label="CUSTOM_ENTITY") # 合并原有实体和自定义实体 doc.ents = list(doc.ents) + [custom_span] doc_bin.add(doc) # 保存带完整标注的训练数据 doc_bin.to_disk("train_full_entities.spacy")
2. 调整训练配置与参数
- 保留预训练权重:训练时使用
--base-model en_core_web_sm参数,让SpaCy基于预训练模型的权重增量训练,而非从头初始化。 - 降低学习率:在
config.cfg里把training.optimizer.learn_rate设为1e-5左右(默认1e-3过高,容易快速覆盖旧权重)。 - 指定所有实体类型:确保
[components.ner.model]下的labels包含原有实体+自定义实体,或者训练时通过--labels参数明确列出所有要保留的类型。
3. 用增量训练命令启动训练
使用以下命令启动训练,确保模型基于预训练权重更新:
python -m spacy train config.cfg --output ./model_output --paths.train ./train_full_entities.spacy --paths.dev ./dev_full_entities.spacy --base-model en_core_web_sm
4. 验证训练数据有效性
用SpaCy的调试工具检查训练数据,确认所有需要保留的实体类型都存在:
python -m spacy debug data config.cfg --paths.train ./train_full_entities.spacy --paths.dev ./dev_full_entities.spacy
该命令会输出数据中的实体类型统计,帮你排查是否遗漏了原有实体标注。
内容的提问来源于stack exchange,提问作者shakeey
相关产品推荐
相关产品推荐

