[Практика НЛП 01] установка простых трансформеров и простая реализация классификации текста

искусственный интеллект

"Это второй день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."

Быстрая установка простых трансформаторов

Адрес проекта simpletransformers:Hubei.fast git.org/T Привет, Лина Раджа…

Адрес документа simpletransformers:

simpletransformers.ai/

Быстрый способ установки:

  • Установить с помощью Конды

1) Создайте новую виртуальную среду

conda create -n st python pandas tqdm
conda activate st

2) Установите среду cuda

conda install pytorch>=1.6 cudatoolkit=11.0 -c pytorch

3) Установите простые трансформаторы

pip install simpletransformers
  1. установить палочку

wandb для отслеживания и визуализации весов и смещений в веб-браузере (wandb)

pip install wandb

В настоящее время поддерживаются задачи:

Задача Модель
Двоичная и многоклассовая текстовая классификация ClassificationModel
Разговорный ИИ (обучение чат-ботов) ConvAIModel
поколение языка LanguageGenerationModel
Обучение/тонкая настройка языковой модели LanguageModelingModel
Классификация текста с несколькими метками MultiLabelClassificationModel
Мультимодальная классификация (комбинированные текстовые и графические данные) MultiModalClassificationModel
Распознавание именованных объектов NERModel
вопросы и ответы QuestionAnsweringModel
возвращение ClassificationModel
Классификация пар предложений ClassificationModel
Генерация текстового представления RepresentationModel

Где можно скачать предварительно обученную модель?

Для предварительно обученных моделей см.Документация об объятиях лица.

Согласно предоставленной документацииmodel_type, покаargsправильно установить вmodel_nameЗначение словаря — это предварительно обученная модель, которую можно загрузить

[Практика 01] Классификация текста

набор данных

Автор выбираетCLUEдействоватьbenchmarkнабор данных

Выберите набор данных:Классификация длинных текстов IFLYTEK

Тест понимания китайского языка (CLUE)

Woohoo.Стратегические тесты.com/DataSet_sea…

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

Update: Статья CLUE была принята международной конференцией по компьютерной лингвистике COLING2020.

  • Классификация длинных текстов IFLYTEK

ссылка для скачивания:GitHub.com/clueскамейка…

Набор данных содержит более 17 000 длинных текстовых аннотаций к описаниям приложений, включая различные темы приложений, связанные с повседневной жизнью, в общей сложности 119 категорий: «Такси»: 0, «Навигация по карте»: 1, «Бесплатный WIFI»: 2. ,"Аренда автомобиля":3,….,"Женщина":115,"Бизнес":116,"Оплата":117,"Другое":118 (представлены 0-118 соответственно). Каждый фрагмент данных имеет три атрибута: идентификатор категории, название категории, текстовое содержимое.

Количество данных: обучающий набор (12 133), проверочный набор (2 599), тестовый набор (2 600).

{"label": "110",
 "label_des": "社区超市",
 "sentence": "朴朴快送超市创立于2016年,专注于打造移动端30分钟即时配送一站式购物平台,商品品类包含水果、蔬菜、肉禽蛋奶、海鲜水产、粮油调味、酒水饮料、休闲食品、日用品、外卖等。朴朴公司希望能以全新的商业模式,更高效快捷的仓储配送模式,致力于成为更快、更好、更多、更省的在线零售平台,带给消费者更好的消费体验,同时推动中国食品安全进程,成为一家让社会尊敬的互联网公司。,朴朴一下,又好又快,1.配送时间提示更加清晰友好2.保障用户隐私的一些优化3.其他提高使用体验的调整4.修复了一些已知bug"}

обработка данных

Простые преобразователи требуют, чтобы данные содержались в кадрах данных Pandas как минимум с двумя столбцами. Просто назовите текст и метки столбца, и SimpleTransformers обработает данные.
Первый столбец содержит текст и имеет тип str.
Второй столбец содержит метки и имеет тип int.
Для мультиклассовой классификации метки должны быть целыми числами, начиная с 0.

import json
import pandas as pd

def load_clue_iflytek(path,mode=None):
    """适应simpletransformer的加载方式"""
    data = []
    with open(path, "r", encoding="utf-8") as fp:
        if mode == 'train' or mode =='dev':
            for idx, line in enumerate(fp):
                line = json.loads(line.strip())
                label = int(line["label"])
                text = line['sentence']
                data.append([text, label])
            data_df = pd.DataFrame(data, columns=["text", "labels"])
            return data_df
        elif mode == 'test':
            for idx, line in enumerate(fp):
                line = json.loads(line.strip())
                text = line['sentence']
                data.append([text])
            data_df = pd.DataFrame(data, columns=["text"])
            return data_df

Построение модели и обучение

Сначала настройте параметры. У Simple Transformers есть аргументы dict. Подробное описание каждого аргумента см. по адресу:простые трансформеры.love/docs/tips - ааа...

1) Конфигурация параметров

# 配置config
import argparse

def data_config(parser):
    parser.add_argument("--trainset_path", type=str, default="data/Chinese_Spam_Message/train.json",
                        help="训练集路径")
    parser.add_argument("--testset_path", type=str, default="data/Chinese_Spam_Message/test.txt",
                        help="测试集路径")
    parser.add_argument("--reprocess_input_data", type=bool, default=True,
                        help="如果为True,则即使cache_dir中存在输入数据的缓存文件,也将重新处理输入数据")
    parser.add_argument("--overwrite_output_dir", type=bool, default=True,
                        help="如果为True,则训练后的模型将保存到ouput_dir,并将覆盖同一目录中的现有已保存模型")
    parser.add_argument("--use_cached_eval_features", type=bool, default=True,
                        help="训练期间的评估使用缓存特征,将此设置为False将导致在每个评估步骤中重新计算特征")
    parser.add_argument("--output_dir", type=str, default="outputs/",
                        help="存储所有输出,包括模型checkpoints和评估结果")
    parser.add_argument("--best_model_dir", type=str, default="outputs/best_model/",
                        help="保存评估过程中的最好模型")
    return parser


def model_config(parser):
    parser.add_argument("--max_seq_length", type=int, default=64,
                        help="模型支持的最大序列长度")
    parser.add_argument("--model_type", type=str, default="bert",
                        help="模型类型bert/roberta")
    # 要加载以前保存的模型而不是默认模型的模型,可以将model_name更改为包含已保存模型的目录的路径。
    parser.add_argument("--model_name", type=str, default="./outputs/bert",
                        help="选择使用哪个预训练模型")
    parser.add_argument("--manual_seed", type=int, default=0,
                        help="为了产生可重现的结果,需要设置随机种子")
    parser.add_argument("--learning_rate", type=int, default=4e-5,
                        help="学习率")
    return parser


def train_config(parser):
    parser.add_argument("--num_train_epochs", type=int, default=3,
                        help="模型训练迭代数")
    parser.add_argument("--wandb_kwargs", type=dict, default={"name": "bert"},
                        help="")
    parser.add_argument("--n_gpu", type=int, default=1,
                        help="训练时使用的GPU个数")
    parser.add_argument("--train_batch_size", type=int, default=64)
    parser.add_argument("--eval_batch_size", type=int, default=32)
    return parser


def set_args():
    parser = argparse.ArgumentParser()
    parser = data_config(parser)
    parser = model_config(parser)
    parser = train_config(parser)

    args,_ = parser.parse_known_args()
    return args

2) Построение модели и обучение

from simpletransformers.classification import ClassificationModel
from sklearn.metrics import f1_score, accuracy_score
import logging

def f1_multiclass(labels, preds):
      return f1_score(labels, preds, average='micro')

# 创建分类模型
model = ClassificationModel(args.model_type, args.model_name, num_labels=num_labels, args=vars(args))

# 训练模型,并在训练时评估
model.train_model(train,eval_df=dev)

# 模型预测
result, model_outputs, wrong_predictions = model.eval_model(dev, f1=f1_multiclass)


# 模型预测
predictions, raw_outputs = model.predict(test["text"][0])
print(predictions)
print(raw_outputs)

результат прогноза

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

{"eval_loss" = 1.8086365330510024,"f1" = 0.5917660638707195,"mcc" = 0.5727319886339782}

полный код

import json
import pandas as pd
from simpletransformers.classification import ClassificationModel
from sklearn.metrics import f1_score, accuracy_score
import logging

def load_clue_iflytek(path,mode=None):
    """适应simpletransformer的加载方式"""
    data = []
    with open(path, "r", encoding="utf-8") as fp:
        if mode == 'train' or mode =='dev':
            for idx, line in enumerate(fp):
                line = json.loads(line.strip())
                label = int(line["label"])
                text = line['sentence']
                data.append([text, label])
            data_df = pd.DataFrame(data, columns=["text", "labels"])
            return data_df
        elif mode == 'test':
            for idx, line in enumerate(fp):
                line = json.loads(line.strip())
                text = line['sentence']
                data.append([text])
            data_df = pd.DataFrame(data, columns=["text"])
            return data_df

# 配置config
import argparse

def data_config(parser):
    parser.add_argument("--trainset_path", type=str, default="data/Chinese_Spam_Message/train.json",
                        help="训练集路径")
    parser.add_argument("--testset_path", type=str, default="data/Chinese_Spam_Message/test.txt",
                        help="测试集路径")
    parser.add_argument("--reprocess_input_data", type=bool, default=True,
                        help="如果为True,则即使cache_dir中存在输入数据的缓存文件,也将重新处理输入数据")
    parser.add_argument("--overwrite_output_dir", type=bool, default=True,
                        help="如果为True,则训练后的模型将保存到ouput_dir,并将覆盖同一目录中的现有已保存模型")
    parser.add_argument("--use_cached_eval_features", type=bool, default=True,
                        help="训练期间的评估使用缓存特征,将此设置为False将导致在每个评估步骤中重新计算特征")
    parser.add_argument("--output_dir", type=str, default="outputs/",
                        help="存储所有输出,包括模型checkpoints和评估结果")
    parser.add_argument("--best_model_dir", type=str, default="outputs/best_model/",
                        help="保存评估过程中的最好模型")
    return parser


def model_config(parser):
    parser.add_argument("--max_seq_length", type=int, default=64,
                        help="模型支持的最大序列长度")
    parser.add_argument("--model_type", type=str, default="bert",
                        help="模型类型bert/roberta")
    # 要加载以前保存的模型而不是默认模型的模型,可以将model_name更改为包含已保存模型的目录的路径。
    parser.add_argument("--model_name", type=str, default="./outputs/bert",
                        help="选择使用哪个预训练模型")
    parser.add_argument("--manual_seed", type=int, default=0,
                        help="为了产生可重现的结果,需要设置随机种子")
    parser.add_argument("--learning_rate", type=int, default=4e-5,
                        help="学习率")
    return parser


def train_config(parser):
    parser.add_argument("--num_train_epochs", type=int, default=3,
                        help="模型训练迭代数")
    parser.add_argument("--wandb_kwargs", type=dict, default={"name": "bert"},
                        help="")
    parser.add_argument("--n_gpu", type=int, default=1,
                        help="训练时使用的GPU个数")
    parser.add_argument("--train_batch_size", type=int, default=64)
    parser.add_argument("--eval_batch_size", type=int, default=32)
    return parser


def set_args():
    parser = argparse.ArgumentParser()
    parser = data_config(parser)
    parser = model_config(parser)
    parser = train_config(parser)

    args,_ = parser.parse_known_args()
    return args



def f1_multiclass(labels, preds):
      return f1_score(labels, preds, average='micro')


if __name__ == "__main__":
    args = set_args()

    logging.basicConfig(level=logging.INFO)
    transformers_logger = logging.getLogger("transformers")
    transformers_logger.setLevel(logging.WARNING)

    # 模型训练
    train = load_clue_iflytek("./data/iflytek/train.json", mode='train')
    dev = load_clue_iflytek("./data/iflytek/dev.json", mode='dev')
    test = load_clue_iflytek("./data/iflytek/test.json", mode='test')
    num_labels = len(train["labels"].unique())
    print(train.shape)
    print(dev.shape)

    # 创建分类模型
    model = ClassificationModel(args.model_type, args.model_name, num_labels=num_labels, args=vars(args))

    # 训练模型,并在训练时评估
    model.train_model(train,eval_df=dev)

    # 模型预测
    result, model_outputs, wrong_predictions = model.eval_model(dev, f1=f1_multiclass)

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

НЛП новое, талант и обучение поверхностны, есть ошибки или несовершенства, прошу критиковать и исправлять! !