当前位置:   article > 正文

昇思25天学习打卡营第16天|LLM原理和实践-基于 MindSpore 实现 BERT 对话情绪识别

昇思25天学习打卡营第16天|LLM原理和实践-基于 MindSpore 实现 BERT 对话情绪识别

昇思25天学习打卡营第16天|LLM原理和实践-基于 MindSpore 实现 BERT 对话情绪识别

应用场景:

  1. 智能评判企业客服的服务质量
  2. 适用社交媒体数据,检测一些暴力犯罪辱骂等言论
  3. 一些消极、自杀性言论的情感智能检测
  4. 情感驱动的内容推荐(如对歌曲的情感进行分类)

Bert了解

  1. 一种基于Transformer架构(最初用来作翻译)的预训练语言模型
  2. 在预训练阶段通过遮盖部分输入词语来学习双向上下文信息
  3. BERT在大规模数据上进行了预训练,学习到了通用的语言表示
  4. BERT预训练之后,会保存它的Embedding table和12层Transformer权重(BERT-BASE)或24层Transformer权重(BERT-LARGE)。使用预训练好的BERT模型可以对下游任务进行Fine-tuning(再次针对特殊场景进行训练)

数据集准备

import numpy as np
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)
    # transforms
    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']
    # map dataset
    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')
    # batch dataset
    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进行转换和进行数据集划分
from mindnlp.transformers import BertTokenizer
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)
dataset_train.get_col_names()
print(next(dataset_train.create_tuple_iterator()))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  1. 函数 process_dataset:

    source:数据集的来源,可以是文件路径或其他形式的数据源。

    tokenizer:用于将文本转换为模型输入格式的tokenizer对象,例如BERTTokenizer。

    max_seq_len:最大序列长度,用于控制输入文本的最大长度,超出部分将被截断,不足部分将被填充。

    batch_size:批处理大小,指定每个批次包含的样本数量。

    shuffle:是否在加载数据时对数据进行洗牌(打乱顺序),默认为True。

  2. GeneratorDataset(source, column_names=column_names, shuffle=shuffle):通过指定的 source 和列名 column_names 创建一个GeneratorDataset对象,用于加载数据。

  3. type_cast_op = transforms.TypeCast(mindspore.int32):定义了一个类型转换操作,将标签转换为整数类型,以符合模型的要求(在dataset.map中被调用)。

  4. tokenize_and_pad(text):使用 tokenizer 对文本进行tokenize操作。对数据集中的文本列进行映射操作,将文本转换为模型所需的 input_idsattention_mask。(所有输入文本都需要经过分词器tokenizer 转换成模型输入所需的token IDs(即input_ids)和attention mask)

  5. 数据集对象 dataset含了经过tokenize、类型转换和批处理后的数据

模型构建和训练

from mindnlp.transformers import BertForSequenceClassification, BertModel
from mindnlp._legacy.amp import auto_mixed_precision

# set bert config and define parameters for training
#使用 'bert-base-chinese' 预训练的BERT模型,适用于中文语境,输出标签数为3(适用于文本分类任务)。
model = BertForSequenceClassification.from_pretrained('bert-base-chinese', num_labels=3)
#应用自动混合精度优化(Mixed Precision),提高模型训练速度和效率。
model = auto_mixed_precision(model, 'O1')
#使用Adam优化器,设定学习率为2e-5。
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])
                  
%%time
# start training
trainer.run(tgt_columns="labels")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

适用的库和模块介绍

  1. BertForSequenceClassification:用于文本分类任务的BERT模型。
  2. auto_mixed_precision:用于自动混合精度优化的函数。
  3. Trainer:用于管理模型训练过程的类。
  4. CheckpointCallbackBestModelCallback:用于保存模型检查点和最佳模型的回调函数,自动加载表现最佳的模型给到model实例
  5. Adam:MindSpore中的Adam优化器。
  6. Accuracy:用于计算准确率的指标。
  7. trainer:创建 Trainer 对象,传入模型、训练集、验证集、优化器、评估指标、训练轮数和回调函数列表。

模型测试和体验

# 定义评估器,用于评估模型在测试集上的性能(metric = Accuracy())
evaluator = Evaluator(network=model, eval_dataset=dataset_test, metrics=metric)
evaluator.run(tgt_columns="labels")
# 加载推断数据集
dataset_infer = SentimentDataset("data/infer.tsv")
def predict(text, label=None):
    # 标签映射
    label_map = {0: "消极", 1: "中性", 2: "积极"}
    # 对输入文本进行tokenize
    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)

# 单独进行一个样本的预测示例
predict("今天天气真好,但我感觉很糟糕")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/852550
推荐阅读
相关标签
  

闽ICP备14008679号