1. BERT 模型概述
BERT(Bidirectional Encoder Representations from Transformers)是一个预训练的语言表示模型,可以应用于多种自然语言处理任务,包括对话情绪识别。BERT 通过双向 Transformer 编码器,能同时考虑句子中每个词的前后文信息,从而生成更为丰富的语义表示。
BERT全称是来自变换器的双向编码器表征量(Bidirectional Encoder Representations from Transformers),它是Google于2018年末开发并发布的一种新型语言模型。与BERT模型相似的预训练语言模型例如问答、命名实体识别、自然语言推理、文本分类等在许多自然语言处理任务中发挥着重要作用。模型是基于Transformer中的Encoder并加上双向的结构,因此一定要熟练掌握Transformer的Encoder的结构。
BERT模型的主要创新点都在pre-train方法上,即用了Masked Language Model和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。
在用Masked Language Model方法训练BERT的时候,随机把语料库中15%的单词做Mask操作。对于这15%的单词做Mask操作分为三种情况:80%的单词直接用[Mask]替换、10%的单词直接替换成另一个新的单词、10%的单词保持不变。
因为涉及到Question Answering (QA) 和 Natural Language Inference (NLI)之类的任务,增加了Next Sentence Prediction预训练任务,目的是让模型理解两个句子之间的联系。与Masked Language Model任务相比,Next Sentence Prediction更简单些,训练的输入是句子A和B,B有一半的几率是A的下一句,输入这两个句子,BERT模型预测B是不是A的下一句。
BERT预训练之后,会保存它的Embedding table和12层Transformer权重(BERT-BASE)或24层Transformer权重(BERT-LARGE)。使用预训练好的BERT模型可以对下游任务进行Fine-tuning,比如:文本分类、相似度判断、阅读理解等。
对话情绪识别(Emotion Detection,简称EmoTect),专注于识别智能对话场景中用户的情绪,针对智能对话场景中的用户文本,自动判断该文本的情绪类别并给出相应的置信度,情绪类型分为积极、消极、中性。 对话情绪识别适用于聊天、客服等多个场景,能够帮助企业更好地把握对话质量、改善产品的用户交互体验,也能分析客服服务质量、降低人工质检成本。
2. 数据预处理
在进行对话情绪识别之前,需要对数据进行预处理,包括:
- 数据清洗:去除特殊字符、空白符等无关内容。
- 分词:将句子拆分为词或子词,可以使用 BERT 的分词器。
- 标注情感标签:为每个对话句子标注情感类别。
3. BERT 模型架构
BERT 的架构包括多个 Transformer 层,每层包括一个多头自注意力机制和一个前馈神经网络。具体步骤如下:
- 输入嵌入层:将输入的词转换为词向量,并加上位置编码。
- Transformer 编码器:经过多个自注意力机制和前馈网络,生成上下文敏感的词表示。
- 输出层:取 [CLS] 标记的输出向量作为整个句子的表示,并通过一个全连接层和 softmax 层进行分类。
4. 模型训练
模型训练过程包括以下步骤:
- 定义损失函数:使用交叉熵损失函数来衡量预测结果和实际情感标签之间的差异。
- 优化算法:使用优化算法(如 Adam)调整模型参数以最小化损失函数。
- 训练过程:迭代地将数据输入模型,计算损失并反向传播误差,更新模型参数。
5. 模型评估
使用验证集或测试集评估模型的性能,常用的评估指标包括准确率、精确率、召回率和 F1 分数。
6. MindSpore 实现
在 MindSpore 中实现 BERT 对话情绪识别的主要步骤包括:
python
import mindspore as ms
import mindspore.nn as nn
from mindspore import context, Tensor
from mindspore.train import Model
from mindspore.train.callback import LossMonitor
from mindspore.dataset import GeneratorDataset
from transformers import BertTokenizer, BertForSequenceClassification
# 设置执行环境
context.set_context(mode=context.GRAPH_MODE, device_target="CPU")
# 加载预训练的 BERT 模型和分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
# 数据预处理函数
def preprocess_data(texts, labels, tokenizer):
inputs = tokenizer(texts, return_tensors="ms", padding=True, truncation=True, max_length=128)
inputs['labels'] = Tensor(labels, dtype=ms.int32)
return inputs
# 自定义数据集
class MyDataset:
def __init__(self, texts, labels, tokenizer):
self.data = preprocess_data(texts, labels, tokenizer)
def __getitem__(self, index):
return {k: v[index] for k, v in self.data.items()}
def __len__(self):
return len(self.data['input_ids'])
# 创建数据集
texts = ["I love this!", "I hate this!"]
labels = [1, 0]
dataset = GeneratorDataset(MyDataset(texts, labels, tokenizer), column_names=['input_ids', 'attention_mask', 'labels'])
# 定义损失函数和优化器
loss_fn = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')
optimizer = nn.Adam(model.trainable_params(), learning_rate=1e-5)
# 创建训练模型
train_model = Model(model, loss_fn=loss_fn, optimizer=optimizer, metrics={'accuracy'})
# 训练模型
train_model.train(1, dataset, callbacks=[LossMonitor()])
# 模型评估
eval_result = train_model.eval(dataset)
print("Evaluation result:", eval_result)
7. 模型预测
训练完成后,可以使用模型进行对话情绪预测:
python
def predict(text, label=None):
label_map = {0: "消极", 1: "中性", 2: "积极"}
text_tokenized = Tensor([tokenizer(text).input_ids])
logits = model(text_tokenized)
predict_label = logits[0].asnumpy().argmax()
info = f"inputs: '{text}', predict: '{label_map[predict_label]}'"
if label is not None:
info += f" , label: '{label_map[label]}'"
print(info)
from mindspore import Tensor
for label, text in dataset_infer:
predict(text, label)