【MindSpore学习打卡】应用实践-LLM原理和实践-基于MindSpore实现BERT对话情绪识别

在当今的自然语言处理(NLP)领域,情绪识别是一个非常重要的应用场景。无论是在智能客服、社交媒体分析,还是在情感计算领域,准确地识别用户的情绪都能够极大地提升用户体验和系统的智能化水平。BERT(Bidirectional Encoder Representations from Transformers)作为一种强大的预训练语言模型,已经在多个NLP任务中展示了其卓越的性能。在这篇博客中,我们将详细介绍如何基于MindSpore框架,利用BERT模型实现对话情绪识别。通过一步步的代码示例和详细解释,帮助你掌握这一技术。

模型简介

BERT(Bidirectional Encoder Representations from Transformers)是一种基于Transformer的双向编码器表征模型。它主要通过两种预训练任务来捕捉词语和句子级别的表征:Masked Language Model(MLM)和Next Sentence Prediction(NSP)。

  • Masked Language Model:随机将语料库中15%的单词进行掩码操作,模型需要预测这些被掩码的单词。
  • Next Sentence Prediction:模型需要预测两个句子之间是否存在顺序关系。

BERT预训练后,可以用于多种下游任务,如文本分类、相似度判断、阅读理解等。

数据集准备

在数据集准备部分,我们下载并解压了百度飞桨团队提供的机器人聊天数据集。这个数据集已经过预处理,并包含了情绪标签。每一行数据由一个标签和一个经过分词处理的文本组成。标签表示情绪类别(0表示消极,1表示中性,2表示积极),文本则是用户的对话内容。通过使用这种结构化的数据,我们可以更方便地进行情感分类任务。

python 复制代码
# 下载数据集
!wget https://baidu-nlp.bj.bcebos.com/emotion_detection-dataset-1.0.0.tar.gz -O emotion_detection.tar.gz
!tar xvf emotion_detection.tar.gz

数据集格式如下:

复制代码
label--text_a
0--谁骂人了?我从来不骂人,我骂的都不是人,你是人吗 ?
1--我有事等会儿就回来和你聊
2--我见到你很高兴谢谢你帮我

数据加载和预处理

数据加载和预处理是机器学习流程中至关重要的一步。我们使用了GeneratorDataset来加载数据,并通过映射操作将文本转换为模型可以接受的格式。具体来说,我们使用了BertTokenizer将文本Tokenize成词汇ID,并进行填充(Pad)操作。这样做的目的是确保所有输入序列的长度一致,从而提高训练效率和模型性能。

python 复制代码
import numpy as np
from mindspore.dataset import text, GeneratorDataset, transforms
from mindnlp.transformers import BertTokenizer

def process_dataset(source, tokenizer, max_seq_len=64, batch_size=32, shuffle=True):
    is_ascend = mindspore.get_context('device_target') == 'Ascend'
    column_names = ["label", "text_a"]
    
    dataset = GeneratorDataset(source, column_names=column_names, shuffle=shuffle)
    type_cast_op = transforms.TypeCast(mindspore.int32)
    
    def tokenize_and_pad(text):
        if is_ascend:
            tokenized = tokenizer(text, padding='max_length', truncation=True, max_length=max_seq_len)
        else:
            tokenized = tokenizer(text)
        return tokenized['input_ids'], tokenized['attention_mask']
    
    dataset = dataset.map(operations=tokenize_and_pad, input_columns="text_a", output_columns=['input_ids', 'attention_mask'])
    dataset = dataset.map(operations=[type_cast_op], input_columns="label", output_columns='labels')
    
    if is_ascend:
        dataset = dataset.batch(batch_size)
    else:
        dataset = dataset.padded_batch(batch_size, pad_info={'input_ids': (None, tokenizer.pad_token_id), 'attention_mask': (None, 0)})

    return dataset

tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
dataset_train = process_dataset(SentimentDataset("data/train.tsv"), tokenizer)
dataset_val = process_dataset(SentimentDataset("data/dev.tsv"), tokenizer)
dataset_test = process_dataset(SentimentDataset("data/test.tsv"), tokenizer, shuffle=False)

模型构建

在模型构建部分,我们使用了BertForSequenceClassification来进行情感分类任务。这个预训练模型已经在大规模语料上进行了训练,具有强大的语言理解能力。通过加载预训练权重,我们可以显著提升模型在情感分类任务上的表现。同时,我们使用了自动混合精度(auto mixed precision)技术,这不仅可以加速训练过程,还能减少显存使用,从而在有限的硬件资源下实现更高效的训练。

优化器和评价指标是模型训练中的重要组件。我们选择了Adam优化器,因为它在处理大规模数据和复杂模型时表现优异。评价指标方面,我们使用了准确率(Accuracy)来衡量模型的性能。通过这些设置,我们可以确保模型在训练过程中不断优化,并在验证集上取得良好的表现。

回调函数在模型训练过程中发挥着重要作用。我们设置了两个回调函数:CheckpointCallbackBestModelCallback。前者用于定期保存模型的权重,后者则自动加载表现最好的模型权重。通过这些回调函数,我们可以确保在训练过程中不会丢失重要的模型参数,并且始终使用表现最佳的模型进行推理和评估。

python 复制代码
from mindnlp.transformers import BertForSequenceClassification
from mindspore import nn
from mindnlp._legacy.amp import auto_mixed_precision

model = BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=3)
model = auto_mixed_precision(model, 'O1')

optimizer = nn.Adam(model.trainable_params(), learning_rate=2e-5)
metric = Accuracy()
ckpoint_cb = CheckpointCallback(save_path='checkpoint', ckpt_name='bert_emotect', epochs=1, keep_checkpoint_max=2)
best_model_cb = BestModelCallback(save_path='checkpoint', ckpt_name='bert_emotect_best', auto_load=True)

trainer = Trainer(network=model, train_dataset=dataset_train,
                  eval_dataset=dataset_val, metrics=metric,
                  epochs=5, optimizer=optimizer, callbacks=[ckpoint_cb, best_model_cb])
trainer.run(tgt_columns="labels")

模型验证

在模型验证部分,我们使用验证数据集来评估模型的性能。通过计算模型在验证集上的准确率,我们可以了解模型的泛化能力和实际效果。这一步骤非常重要,因为它可以帮助我们发现模型在训练过程中可能存在的问题,并进行相应的调整和优化。

python 复制代码
evaluator = Evaluator(network=model, eval_dataset=dataset_test, metrics=metric)
evaluator.run(tgt_columns="labels")

模型推理

模型推理部分展示了如何使用训练好的模型对新数据进行情感分类。我们定义了一个predict函数,通过输入文本进行情感预测,并输出预测结果。这个步骤展示了模型的实际应用能力,并验证了模型的泛化性能。

python 复制代码
dataset_infer = SentimentDataset("data/infer.tsv")

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)

for label, text in dataset_infer:
    predict(text, label)

自定义推理数据

最后,我们展示了如何使用模型对自定义输入进行情感识别。这一步骤不仅展示了模型的实际应用能力,还验证了模型在不同输入下的表现。通过这种方式,我们可以进一步了解模型的泛化能力和实际效果。

python 复制代码
predict("家人们咱就是说一整个无语住了 绝绝子叠buff")
相关推荐
Xudde.1 分钟前
班级作业笔记报告0x04
笔记·学习·安全·web安全·php
晓晓hh18 分钟前
JavaSE学习——迭代器
java·开发语言·学习
lijianhua_971231 分钟前
国内某顶级大学内部用的ai自动生成论文的提示词
人工智能
EDPJ37 分钟前
当图像与文本 “各说各话” —— CLIP 中的模态鸿沟与对象偏向
深度学习·计算机视觉
蔡俊锋38 分钟前
用AI实现乐高式大型可插拔系统的技术方案
人工智能·ai工程·ai原子能力·ai乐高工程
自然语40 分钟前
人工智能之数字生命 认知架构白皮书 第7章
人工智能·架构
大熊背44 分钟前
利用ISP离线模式进行分块LSC校正的方法
人工智能·算法·机器学习
eastyuxiao1 小时前
如何在不同的机器上运行多个OpenClaw实例?
人工智能·git·架构·github·php
421!1 小时前
GPIO工作原理以及核心
开发语言·单片机·嵌入式硬件·学习
诸葛务农1 小时前
AGI 主要技术路径及核心技术:归一融合及未来之路5
大数据·人工智能