SpaCy 3从零实现自定义DependencyParser加载到非空模型报错问题
错误原因
你遇到的ValueError: could not broadcast input array from shape (106,64) into shape (27,64)报错,本质是两个依存解析器的标签体系、对应输出层权重维度不一致:
- 空白模型中训练的自定义parser,是根据你提供的少量自定义依存标签生成的动作集合,对应输出层权重维度为
(106,64) en_core_web_md自带的预训练parser使用官方标准依存标签集,动作集数量更少,对应输出层权重维度为(27,64)
直接把自定义parser的权重加载到预训练模型自带的parser中,维度不匹配就会触发报错。
解决方案
根据你的使用场景,有两种可行解决方式:
场景1:完全替换预训练模型的原有parser,使用自定义parser的功能
不要直接调用nlp.get_pipe('parser')获取原有parser加载权重,而是先删除原有parser,再新增空白parser加载权重,保证标签集合和训练时完全一致即可,代码修改如下:
# 加载预训练模型 nlp = spacy.load('en_core_web_md') # 移除原有预训练parser nlp.remove_pipe('parser') # 新增空白parser,和训练时的初始化逻辑一致 parser = nlp.add_pipe('parser', first=True) # 手动添加训练时用到的所有自定义标签,保证标签集合完全匹配 custom_labels = {'ROOT', '-', 'QUALITY', 'ACTIVITY', 'ATTRIBUTE'} for label in custom_labels: parser.add_label(label) # 此时再加载自定义parser权重就不会出现维度错误 load_parser_config(parser)
如果替换后推理效果不符合预期,可以同步替换模型的tok2vec层为训练自定义parser时空白模型的tok2vec,保证输入特征分布一致。
场景2:需要保留预训练parser的原有功能,同时支持自定义标签
不要单独在空白模型训练parser,而是以en_core_web_md的原有parser为基础,先添加你需要的自定义依存标签,再用你的训练数据做增量训练,训练完成后直接保存权重,后续加载就不会出现维度不匹配问题。
内容的提问来源于stack exchange,提问作者Evgen
相关产品推荐
相关产品推荐

