如何将COMET生成的知识库融入HuggingFace预训练BERT模型?
将COMET生成的常识知识融入BERT用于情感分析
1. 预处理COMET三元组数据
- 加载pickle文件并解析三元组:
import pickle with open("comet_triples.pkl", "rb") as f: comet_triples = pickle.load(f) # 假设三元组格式为 (head, relation, tail),例如 ("PersonX buys a gift", "xReact", "happy") - 过滤情感相关关系:保留
xReact(主体情感反应)、oReact(他人情感反应)这类与情感直接关联的三元组,减少冗余信息。 - 三元组转自然文本:将
(head, relation, tail)转换为模型易理解的表述,比如"{head}, so I feel {tail}"或"When {head}, people usually feel {tail}"。
2. 选择知识融合方案
根据实现复杂度和效果需求,推荐三种主流方案:
方案一:输入文本拼接(最易落地)
将情感分析原文本与匹配到的COMET知识用[SEP]分隔拼接,示例:原文本:"I got a surprise gift today" 拼接后:"I got a surprise gift today [SEP] When I got a surprise gift today, I feel happy"注意:单样本匹配多个三元组时,优先选置信度最高的1-3个拼接,避免超出BERT默认的
max_seq_length(512)。方案二:Embedding层知识注入
将COMET中的实体/短语映射到BERT的Embedding空间,通过注意力机制计算知识与原文本token的相关性,把相关知识Embedding加权叠加到对应token的Embedding上。可参考ERNIE的知识融合思路,自定义BERT的Embedding模块。方案三:Transformer层知识注意力
在BERT的Transformer编码层中插入知识注意力子模块,让模型编码文本时主动关注匹配到的COMET三元组,动态融合知识信息。该方案效果更优,但需修改BERT核心结构。
3. 基于HuggingFace改造BERT模型
以输入拼接方案为例,快速实现融合:
from transformers import AutoModelForSequenceClassification, AutoTokenizer # 加载预训练模型与分词器 model_name = "bert-base-cased" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2) # 二分类情感任务 # 处理带知识的输入 def encode_with_knowledge(text, knowledge): return tokenizer(text, knowledge, truncation=True, padding="max_length", max_length=512)
若选择Embedding层融合,可继承BertModel重写模块:
from transformers import BertModel import torch.nn as nn class BertWithKnowledgeEmbed(BertModel): def __init__(self, config): super().__init__(config) self.knowledge_attn = nn.MultiheadAttention(config.hidden_size, config.num_attention_heads) def forward(self, input_ids, attention_mask, knowledge_embeds=None, **kwargs): # 计算原文本Embedding embed_output = self.embeddings(input_ids=input_ids, attention_mask=attention_mask) # 融合知识Embedding if knowledge_embeds is not None: fused_embed, _ = self.knowledge_attn(embed_output, knowledge_embeds, knowledge_embeds) embed_output = embed_output + fused_embed # 后续编码流程 encoder_outputs = self.encoder(inputs_embeds=embed_output, attention_mask=attention_mask, **kwargs) return encoder_outputs
4. 数据准备与训练
- 样本-知识匹配:用spaCy等工具提取文本实体,为每个情感样本匹配对应的COMET三元组。
- 训练配置:通过HuggingFace的
Trainer完成训练:from transformers import Trainer, TrainingArguments training_args = TrainingArguments( output_dir="./bert-comet-sentiment", per_device_train_batch_size=8, num_train_epochs=3, evaluation_strategy="epoch", logging_dir="./logs" ) trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, # 预处理好的带知识训练集 eval_dataset=eval_dataset ) trainer.train()
5. 效果验证与对比
- 在测试集上评估融合模型的准确率、F1值,与纯BERT模型结果对比,验证知识融合的增益。
- 分析错误样本:判断哪些样本因知识融合提升了性能,针对性优化知识筛选策略(比如只保留高置信度三元组)。
内容的提问来源于stack exchange,提问作者IneG
相关产品推荐
相关产品推荐

