nlp - 加载训练的 en_core_web_trf spacyV3 NER 模型时出错
问题描述
在加载预训练的 spacy 模型以对自定义数据进行微调之后
spacy.require_gpu()
nlp = spacy.load("en_core_web_trf",exclude=['tagger', 'parser', 'attribute_ruler', 'lemmatizer'])
加载验证时出错
model=spacy.load(category_output_dir + "/%s" % itn,exclude=['tagger', 'parser', 'attribute_ruler', 'lemmatizer'])
文件“/usr/local/lib/python3.6/dist-packages/spacy/init.py”,第 47 行,在加载返回 util.load_model(name, disable=disable, exclude=exclude, config=config) 文件“/usr/local/lib/python3.6/dist-packages/spacy/util.py ",第 275 行,在 load_model 返回 load_model_from_path(Path(name), **kwargs) 文件 "/usr/local/lib/python3.6/dist-packages/spacy/util.py",第 341 行,在 load_model_from_path 返回 nlp .from_disk(model_path, exclude=exclude) File "/usr/local/lib/python3.6/dist-packages/spacy/language.py", line 1705, in from_disk util.from_disk(path, deserializers, exclude) File " /usr/local/lib/python3.6/dist-packages/spacy/util.py”,第 1085 行,在 from_disk 阅读器(路径/键)文件“/usr/local/lib/python3.6/dist-packages/ spacy/language.py",第 1700 行,在 p 中,exclude=["vocab"] 文件 "spacy/pipeline/transition_parser.pyx",第 479 行,在 spacy 中。pipeline.transition_parser.Parser.from_disk 文件“/usr/local/lib/python3.6/dist-packages/thinc/model.py”,第 529 行,from_bytes 返回 self.from_dict(msg) 文件“/usr/local/ lib/python3.6/dist-packages/thinc/model.py”,第 552 行,在 from_dict node.set_dim(dim, value) 文件“/usr/local/lib/python3.6/dist-packages/thinc/model .py”,第 188 行,在 set_dim 中引发 ValueError(err) ValueError:尝试将模型“precomputable_affine”的维度“nO”从 78 更改为 74py",第 188 行,在 set_dim 中引发 ValueError(err) ValueError:尝试将模型 'precomputable_affine' 的维度 'nO' 从 78 更改为 74py",第 188 行,在 set_dim 中引发 ValueError(err) ValueError:尝试将模型 'precomputable_affine' 的维度 'nO' 从 78 更改为 74
这是代码片段
import random
from tqdm import tqdm
import spacy
import os
import copy
from spacy.tokens import Doc
from spacy.training import Example
from spacy.util import minibatch, compounding, decaying
spacy.require_gpu()
nlp = spacy.load("en_core_web_trf",exclude=['tagger', 'parser',
'attribute_ruler', 'lemmatizer'])
ner = nlp.get_pipe('ner')
for _, annotations in TRAIN_DATA:
for ent in annotations.get('entities'):
ner.add_label(ent[2])
for itn in range(n_iter):
random.shuffle(TRAIN_DATA)
losses = {}
for batch in tqdm(minibatch(TRAIN_DATA,size=compounding(4., 64., 1.01))):
for text, annots in batch:
examples = []
try:
examples.append(Example.from_dict(nlp.make_doc(text), annots))
losses=nlp.update(examples,sgd=optimizer,losses=losses)
except:
continue
if use_optimizer_averages:
with nlp.use_params(optimizer.averages):
os.mkdir(output_dir + "/%s" % itn)
nlp.to_disk(output_dir + "/%s" % itn)
model=spacy.load(output_dir + "/%s" % itn,exclude=['tagger', 'parser', 'attribute_ruler', 'lemmatizer'])
火车数据格式:TRAIN_DATA = [["谁是沙卡汗?", {"entities": [(7, 17, "FRIENDS")]}],["我喜欢伦敦。", {"entities": [( 7, 13, "LOC")]}]]
解决方案
看起来您遇到了v3.0.0rc2
spaCy 3 候选版本的错误。我们正在努力为最终的 3.0 版本修复此问题,请参见此处:https ://github.com/explosion/spaCy/pull/6460
同时,恐怕您将无法为基于转换器的预训练 NER 模型添加额外的标签。不过,我建议您从头开始训练一个新的 NER 组件。
在 spaCy 3 中,我们建议使用配置系统而不是编写自己的训练循环 ( https://nightly.spacy.io/usage/training#config )。在配置文件中,您可以从其他管道中获取组件,如下所示:
[components.transformer]
source = "en_core_web_trf"
component = "transformer"
这允许您重用预训练模型的转换器权重,并在此基础上创建一个新的 NER 模型(https://nightly.spacy.io/usage/embeddings-transformers):
[components.ner]
factory = "ner"
[nlp.pipeline.ner.model]
@architectures = "spacy.TransitionBasedParser.v1"
state_type = "ner"
extra_state_tokens = false
hidden_width = 128
maxout_pieces = 3
use_upper = false
[nlp.pipeline.ner.model.tok2vec]
@architectures = "spacy-transformers.TransformerListener.v1"
grad_factor = 1.0
[nlp.pipeline.ner.model.tok2vec.pooling]
@layers = "reduce_mean.v1"
您甚至可以从 NER 组件中获取旧的 NER 组件en_core_web_trf
,只需将其命名不同,您的管道中就会运行两个 NER,每个用于一组不同的标签。
或者,您也可以使用非基于变压器的模型,例如en_core_web_lg
. 像以前一样,向这样的预训练模型添加自定义标签应该可以正常工作。
推荐阅读
- php - Docker PHP/MySQL/Apache 容器
- javascript - 如何使 args 不区分大小写?
- android - 如何修复“E/RecyclerView:未连接适配器;跳过布局”错误
- javascript - 如何修复被打印五次而不是 2 次(PHP)?
- c++ - 编译器是否根据模板实例化为 CPP 中的模板代码生成特定代码?
- javascript - 如何在 Vue.js 中让两个输入相互反应
- html - 仅当表格被打印时,表格前的空间
- django - 在 Django rest ViewSet 中覆盖列表方法
- python - 如何删除所有重复出现或在熊猫数据框中获取唯一值?
- html - 补偿transform移动的区域:translate