Обмен технологиями

[Проверка обучения MindSpore] Практика применения - Принцип LLM и практика реализации BERT Диалог Распознавание эмоций на основе MindSpore

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

В современной области обработки естественного языка (НЛП) распознавание эмоций является очень важным сценарием применения. Будь то интеллектуальное обслуживание клиентов, анализ социальных сетей или эмоциональные вычисления, точное определение эмоций пользователей может значительно улучшить пользовательский опыт и уровень интеллекта системы. BERT (представления двунаправленного кодировщика от Transformers), как мощная предварительно обученная языковая модель, продемонстрировал свою отличную производительность в различных задачах НЛП. В этом блоге мы подробно расскажем, как использовать модель BERT для распознавания разговорных эмоций на основе платформы MindSpore. Пошаговые примеры кода и подробные объяснения помогут вам освоить эту технику.

Введение модели

BERT (представления двунаправленного кодировщика от трансформаторов) — это модель представления двунаправленного кодировщика на основе трансформатора. В основном он фиксирует представления на уровне слов и предложений с помощью двух задач предварительного обучения: модель языка в маске (MLM) и прогнозирование следующего предложения (NSP).

  • Модель замаскированного языка: случайным образом замаскировать 15% слов в корпусе, и модель должна предсказать эти замаскированные слова.
  • Прогнозирование следующего предложения: Модель должна предсказать, существует ли последовательная связь между двумя предложениями.

После предварительной подготовки BERT его можно использовать для различных последующих задач, таких как классификация текста, оценка сходства, понимание прочитанного и т. д.

Подготовка набора данных

На этапе подготовки набора данных мы загрузили и распаковали набор данных чата робота, предоставленный командой Baidu Feipiao. Этот набор данных был предварительно обработан и содержит метки эмоций. Каждая строка данных состоит из метки и текста, разделенного на слова. Метка представляет категорию эмоций (0 означает отрицательную, 1 означает нейтральную, 2 означает положительную), а текст — это содержимое разговора пользователя. Используя эти структурированные данные, мы можем более удобно выполнять задачи классификации настроений.

# 下载数据集
!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
  • 1
  • 2
  • 3

Формат набора данных следующий:

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

Загрузка и предварительная обработка данных

Загрузка и предварительная обработка данных являются важными этапами процесса машинного обучения.мы использовалиGeneratorDataset загрузить данные и использовать операции сопоставления для преобразования текста в формат, приемлемый для модели.В частности, мы использовалиBertTokenizer Преобразуйте текст в идентификатор словаря и выполните операцию заполнения. Целью этого является обеспечение единообразия длины всех входных последовательностей, тем самым повышая эффективность обучения и производительность модели.

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)
  • 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

Вставьте сюда описание изображения

Построение модели

В части построения модели мы использовалиBertForSequenceClassification выполнять задачи по классификации эмоций. Эта предварительно обученная модель была обучена на крупномасштабных корпусах и обладает хорошими возможностями понимания языка. Загружая предварительно обученные веса, мы можем значительно улучшить производительность модели при выполнении задач классификации эмоций. При этом мы используем технологию автоматической смешанной точности, которая не только ускоряет процесс обучения, но и снижает использование видеопамяти, тем самым достигая более эффективного обучения при ограниченных аппаратных ресурсах.

Оптимизаторы и метрики оценки являются важными компонентами обучения модели. Мы выбрали оптимизатор Adam из-за его превосходной производительности при работе с крупномасштабными данными и сложными моделями. Что касается показателей оценки, мы используем точность для измерения эффективности модели. Благодаря этим настройкам мы можем гарантировать, что модель постоянно оптимизируется во время обучения и достигает хорошей производительности на проверочном наборе.

Функции обратного вызова играют важную роль в процессе обучения модели. Мы настроили две функции обратного вызова:CheckpointCallbackиBestModelCallback . Первый используется для регулярного сохранения весов модели, а второй автоматически загружает веса наиболее эффективной модели. С помощью этих функций обратного вызова мы гарантируем, что важные параметры модели не будут потеряны во время обучения и что для вывода и оценки всегда будет использоваться наиболее эффективная модель.

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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Проверка модели

В разделе проверки модели мы используем набор данных проверки для оценки производительности модели. Рассчитав точность модели на проверочном наборе, мы можем понять способность к обобщению и фактический эффект модели. Этот шаг очень важен, поскольку он может помочь нам обнаружить возможные проблемы в процессе обучения модели и внести соответствующие корректировки и оптимизации.

evaluator = Evaluator(network=model, eval_dataset=dataset_test, metrics=metric)
evaluator.run(tgt_columns="labels")
  • 1
  • 2

Модельное рассуждение

В разделе вывода модели показано, как использовать обученную модель для классификации настроений на новых данных.Мы определилиpredict Функция, которая прогнозирует эмоции путем ввода текста и выводит результаты прогнозирования. Этот шаг демонстрирует возможности практического применения модели и проверяет эффективность обобщения модели.

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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Вставьте сюда описание изображения

Пользовательские данные вывода

Наконец, мы покажем, как использовать модель для распознавания эмоций при пользовательском вводе. Этот шаг не только демонстрирует возможности практического применения модели, но также проверяет производительность модели при различных входных данных. Таким образом, мы можем лучше понять способность к обобщению и фактический эффект модели.

predict("家人们咱就是说一整个无语住了 绝绝子叠buff")
  • 1

Вставьте сюда описание изображения