use*_*154 5 python nlp named-entity-recognition spacy spacy-3
我刚刚开始训练 Spacy 命名实体识别模型,并遵循此处描述的基本示例,您可以通过实例Doc化对象并使用DocBin.
我的自定义preprocess.py文件如下所示:
if __name__ == '__main__':
nlp = spacy.blank("en")
counter = 0
db = DocBin()
with open(sys.argv[1], 'r') as fp:
line = fp.readline()
while line:
record = MyRecord.build(json.loads(line))
doc = record.to_spacy_doc(nlp=nlp)
# internally, something like:
# # char-level indices
# ent = doc.char_span(0, 5, label='SOMETHING')
# doc.set_ents([ent])
db.add(doc)
counter += 1
# hacky way to save 1000 docs in each DocBin
if counter == 1000:
db.to_disk("./train.spacy")
db = DocBin()
if counter == 2000:
db.to_disk("./dev.spacy")
break
line = fp.readline()
Run Code Online (Sandbox Code Playgroud)
然后使用如下命令运行训练脚本:
python -m spacy train config.cfg --output ./output --paths.train train.spacy --paths.dev dev.spacy
Run Code Online (Sandbox Code Playgroud)
这似乎运作良好。然而,我随后了解到,您可以通过编写和注册一个生成器来编写自定义数据加载器函数,该生成器在此处Example描述的过程中生成 的实例。这让我很感兴趣,因为理论上你可以在训练循环期间读取大于 RAM 的文件。
我自己在 中编写了这样一个生成器,它从外部数据源(恰好是来自磁盘的自定义 JSONL)functions.py生成实例,其中我有一些已知的实体标签(带有字符级索引):Example
@spacy.registry.readers("corpus_variants.v1")
def stream_data(source: str) -> Callable[[Language], Iterator[Example]]:
def generate_stream(nlp: Language):
counter = 0
with open(source, 'r') as fp:
line = fp.readline()
while line:
record = MyRecord.build(json.loads(line))
#doc = nlp(record.text)
doc = nlp.make_doc(record.doc_with_annotations.text)
entities = [
(start, end, label) # char-level offets (not token-level)
for start, end, label, _
in record.get_entity_tuples()
]
gold_dict = dict(
entities=entities
)
example = Example.from_dict(doc, gold_dict)
yield example
counter += 1
# arbitrarily stop at 20 for debugging purposes, but ideally stream the very large file
if counter > 20:
break
line = fp.readline()
return generate_stream
Run Code Online (Sandbox Code Playgroud)
我还进行了修改config.cfg以包含以下内容:
[corpora.dev]
@readers = "corpus_variants.v1"
source = "dev.jsonl"
[corpora.train]
@readers = "corpus_variants.v1"
source = "train.jsonl"
Run Code Online (Sandbox Code Playgroud)
当我运行训练命令时:
[corpora.dev]
@readers = "corpus_variants.v1"
source = "dev.jsonl"
[corpora.train]
@readers = "corpus_variants.v1"
source = "train.jsonl"
Run Code Online (Sandbox Code Playgroud)
我收到很多UserWarning: [W030] Some entities could not be aligned in the text警告。我读过一些关于这些警告背后的理论的文章,但我很好奇为什么当我保存时不会发生这种行为DocBin?对齐实际上是不同的还是仅在显式创建实例时才会出现警告Example?
我对让自定义数据加载器处理这些数据感兴趣,但也对替代方法感兴趣,这些方法本质上允许我从(大于 RAM)文件中流式传输任意行作为训练示例。
最后,与回答这个问题相关的还有理解从头开始训练新的 (NER) 模型与更新现有模型之间的差异。如果我正确理解 Spacy 管道,更新现有模型可能会有一些对齐优势,因为在组装训练示例和推理过程中可以使用相同的分词器。