Transformers基本组件(二)快速入门Datasets、Evaluate、Trainer

news2024/12/28 9:19:48

Transformers基本组件(二)快速入门Datasets、Evaluate、Trainer

1、基础组件Datasets

数据集部分的工作,一部分在于数据集的收集,另一部分在于数据集的处理。Datasets库的出现,一定程度上也使得这两部分的工作变得简单了许多。

1.1 加载数据集

加载在线数据集

from datasets import load_dataset

# 加载公开数据集只需要两步,导入Datasets包,然后加载想要的数据集即可
# 经过短暂的下载后(当然,大概率会出现443错误),便可以看到数据集已经被成功加载。
# 而且已经被划分为了训练集和验证集两部分,训练集5850条,验证集1679条。


# 官网中列出了公开数据集,点击具体的数据集后,可以查看详细信息。
datasets = load_dataset("madao33/new-title-chinese")
datasets
DatasetDict({
    train: Dataset({
        features: ['title', 'content'],
        num_rows: 5850
    })
    validation: Dataset({
        features: ['title', 'content'],
        num_rows: 1679
    })
})

加载子数据集

super_glue是一系列任务的合集,里面包含多个数据集,假设要加载boolq数据集,要如何做呢

# 直接加子数据集参数
boolq_dataset = load_dataset("super_glue", "boolq")
boolq_dataset
DatasetDict({
    train: Dataset({
        features: ['question', 'passage', 'idx', 'label'],
        num_rows: 9427
    })
    validation: Dataset({
        features: ['question', 'passage', 'idx', 'label'],
        num_rows: 3270
    })
    test: Dataset({
        features: ['question', 'passage', 'idx', 'label'],
        num_rows: 3245
    })
})

按照数据集划分进行加载

# 前面加载的数据集都是将全部数据集加载了,包括训练集、验证集、测试集。
# 我们也可以根据数据集的划分,选择要加载的数据集划分,只需要指定split参数。
# 假设我们要加载前面中文新闻数据集中的训练集,那么代码可以这样:

dataset = load_dataset("madao33/new-title-chinese", split="train")
dataset
Dataset({
    features: ['title', 'content'],
    num_rows: 5850
})
# 其他形式的加载

# 按照条数加载
dataset = load_dataset("madao33/new-title-chinese", split="train[10:100]")

# 按照比例加载
dataset = load_dataset("madao33/new-title-chinese", split="train[:50%]")

1.2 数据集常用操作

1.2.1 查看数据集

datasets = load_dataset("madao33/new-title-chinese")

print(datasets["train"][0])
print(datasets["train"]["title"][:5])
print(datasets["train"].column_names)
print(datasets["train"].features)

1.2.2 数据集划分

dataset = datasets["train"]

# 这里我们对原始的train数据集进行了划分,可以看到数据按照9:1的比例重新进行了划分。
dataset.train_test_split(test_size=0.1)
DatasetDict({
    train: Dataset({
        features: ['title', 'content'],
        num_rows: 5265
    })
    test: Dataset({
        features: ['title', 'content'],
        num_rows: 585
    })
})

1.2.3 数据集的选取与过滤

# 选取
datasets["train"].select([0, 1])
Dataset({
    features: ['title', 'content'],
    num_rows: 2
})
# 过滤
filter_dataset = datasets["train"].filter(lambda example: "中国" in example["title"])
filter_dataset["title"][:5]
['聚焦两会,世界探寻中国成功秘诀',
 '望海楼中国经济的信心来自哪里',
 '“中国奇迹”助力世界减贫跑出加速度',
 '和音瞩目历史交汇点上的中国',
 '中国风采感染世界']

1.2.4 数据映射

def add_prefix(example):
    example["title"] = 'Prefix: ' + example["title"]
    return example


prefix_dataset = datasets.map(add_prefix)
prefix_dataset["train"][:10]["title"]
['Prefix: 望海楼美国打“台湾牌”是危险的赌博',
 'Prefix: 大力推进高校治理能力建设',
 'Prefix: 坚持事业为上选贤任能',
 'Prefix: “大朋友”的话儿记心头',
 'Prefix: 用好可持续发展这把“金钥匙”',
 'Prefix: 跨越雄关,我们走在大路上',
 'Prefix: 脱贫奇迹彰显政治优势',
 'Prefix: 拱卫亿万人共同的绿色梦想',
 'Prefix: 为党育人、为国育才',
 'Prefix: 净化网络语言']

当然,真实情况下,我们不会只做这样的处理。

在这里,一般会与Tokenizer做结合实现完整的数据处理函数,将其直接转换为模型想要的输入。

from transformers import AutoTokenizer


tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")

def preprocess_function(example, tokenizer=tokenizer):
    model_inputs = tokenizer(example["content"], max_length=512, truncation=True)
    labels = tokenizer(example["title"], max_length=32, truncation=True)
    # label就是title编码的结果
    model_inputs["labels"] = labels["input_ids"]
    return model_inputs

# 处理完成后,在数据的字段中便多了四个字段,这些字段便是模型能够处理的字段。
processed_datasets = datasets.map(preprocess_function)
processed_datasets
DatasetDict({
    train: Dataset({
        features: ['title', 'content', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 5850
    })
    validation: Dataset({
        features: ['title', 'content', 'input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 1679
    })
})

map函数还支持批量处理数据,只需要指定batched参数值为True。

# 二者效果是一样的,但是使用批量数据处理效率要高的多。
processed_datasets = datasets.map(preprocess_function, batched=True)
processed_datasets

当然,我们一般只需要处理后的字段

processed_datasets = datasets.map(preprocess_function, batched=True, remove_columns=datasets["train"].column_names)


# 可以发现原始字段已经删除,只保留了处理后的字段
processed_datasets
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 5850
    })
    validation: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 1679
    })
})

1.2.5 数据保存和加载

# 当我们处理完数据之后,我们可以将其保存到本地磁盘,需要用时下次直接加载即可,无需二次处理。
processed_datasets.save_to_disk("./processed_data")

processed_datasets = load_from_disk("./processed_data")
processed_datasets
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 5850
    })
    validation: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 1679
    })
})

1.3 加载本地数据集

多数情况下,公开数据集并不能满足我们的需求,需要加载自行准备的数据集。下面来介绍如何加载本地的数据集。

1.3.1 直接加载文件

# 本地文件支持csv、json文件的直接加载
# 1、加载csv文件
dataset = load_dataset("csv", data_files="./ChnSentiCorp_htl_all.csv", split="train")

# 或者
from datasets import Dataset
dataset = Dataset.from_csv("./ChnSentiCorp_htl_all.csv")

# 2、加载json文件
load_dataset("json", data_files=["./cmrc2018_trial.json"], field="data")

1.3.2 加载文件夹中的文件

# 加载整个文件夹的内容
dataset = load_dataset("csv", data_dir='./all_data/', split='train')


# 加载文件夹中特定的文件
dataset = load_dataset("csv", data_files=["./all_data/ChnSentiCorp_htl_all.csv", "./all_data/ChnSentiCorp_htl_all_2.csv"], split='train')

dataset
Dataset({
    features: ['label', 'review'],
    num_rows: 15532
})

1.3.3 转换加载数据集

import pandas as pd

# 1、从pandas中加载
data = pd.read_csv("./ChnSentiCorp_htl_all.csv")

dataset = Dataset.from_pandas(data)

# 2、从list中加载

# List格式的数据需要内嵌{},明确数据字段
data = [{"text": "abc"}, {"text": "def"}]
# data = ["abc", "def"]
Dataset.from_list(data)

1.3.4 利用脚本加载

data中数据如下

      "paragraphs": [
        {
          "id": "TRIAL_800", 
          "context": "基于《跑跑卡丁车》与《泡泡堂》上所开发的游戏,由韩国Nexon开发与发行。中国大陆由盛大游戏运营,这是Nexon时隔6年再次授予盛大网络其游戏运营权。台湾由游戏橘子运营。......", 
          "qas": [
            {
              "question": "生命数耗完即算为什么?", 
              "id": "TRIAL_800_QUERY_0", 
              "answers": [
                {
                  "text": "踢爆", 
                  "answer_start": 127
                }
              ]
            }
          ]
        }
      ], 
      "id": "TRIAL_800", 
      "title": "泡泡战士"
# 直接解析josn不能满足要求,只解析出'paragraphs', 'id', 'title'字段
load_dataset("json", data_files="./cmrc2018_trial.json", field="data")
DatasetDict({
    train: Dataset({
        features: ['paragraphs', 'id', 'title'],
        num_rows: 256
    })
})

使用脚本进行加载

load_dataset("./load_cmrc.py", split="train")
Dataset({
    features: ['id', 'context', 'question', 'answers'],
    num_rows: 1002
})

脚本如下

import json
import datasets
from datasets import DownloadManager, DatasetInfo

'''
_info方法定义数据集结构
_split_generators方法指定不同数据划分要加载的数据
_generate_examples方法实现具体的读取数据代码
'''
class CMRC2018TRIAL(datasets.GeneratorBasedBuilder):

    def _info(self) -> DatasetInfo:
        """
            info方法,定义数据集的信息,这里要对数据的字段进行定义
        :return:
        """
        return datasets.DatasetInfo(
            description="CMRC2018 trial",
            features=datasets.Features({
                    "id": datasets.Value("string"),
                    "context": datasets.Value("string"),
                    "question": datasets.Value("string"),
                    "answers": datasets.features.Sequence(
                        {
                            "text": datasets.Value("string"),
                            "answer_start": datasets.Value("int32"),
                        }
                    )
                }),
        )

    def _split_generators(self, dl_manager: DownloadManager):
        """
            返回datasets.SplitGenerator
            涉及两个参数:name和gen_kwargs
            name: 指定数据集的划分
            gen_kwargs: 指定要读取的文件的路径,与_generate_examples的入参数一致
        :param dl_manager:
        :return: [ datasets.SplitGenerator ]
        """
        return [datasets.SplitGenerator(name=datasets.Split.TRAIN, gen_kwargs={"filepath": "./cmrc2018_trial.json"})]

    def _generate_examples(self, filepath):
        """
            生成具体的样本,使用yield
            需要额外指定key,id从0开始自增就可以
        :param filepath:
        :return:
        """
        # Yields (key, example) tuples from the dataset
        with open(filepath, encoding="utf-8") as f:
            data = json.load(f)
            for example in data["data"]:
                for paragraph in example["paragraphs"]:
                    context = paragraph["context"].strip()
                    for qa in paragraph["qas"]:
                        question = qa["question"].strip()
                        id_ = qa["id"]

                        answer_starts = [answer["answer_start"] for answer in qa["answers"]]
                        answers = [answer["text"].strip() for answer in qa["answers"]]

                        yield id_, {
                            "context": context,
                            "question": question,
                            "id": id_,
                            "answers": {
                                "answer_start": answer_starts,
                                "text": answers,
                            },
                        }

1.4 DataCollator

from transformers import  DataCollatorWithPadding

dataset = load_dataset("csv", data_files="./ChnSentiCorp_htl_all.csv", split='train')
dataset = dataset.filter(lambda x: x["review"] is not None)
dataset
Dataset({
    features: ['label', 'review'],
    num_rows: 7765
})
def process_function(examples):
    # 这里我们指定max_length为128,超过此长度,进行截断
    # 注意:这里,我们不指定填充,我们利用 DataCollator进行填充
    tokenized_examples = tokenizer(examples["review"], max_length=128, truncation=True)
    tokenized_examples["labels"] = examples["label"]
    return tokenized_examples



tokenized_dataset = dataset.map(process_function, batched=True, remove_columns=dataset.column_names)

# DataCollatorWithPadding:把一批样本补齐到【这批样本最长句子的长度】而非整个数据集的最大长度
# 这样能够加快补齐速度
collator = DataCollatorWithPadding(tokenizer=tokenizer)


from torch.utils.data import DataLoader
dl = DataLoader(tokenized_dataset, batch_size=4, collate_fn=collator, shuffle=True)

num = 0
for batch in dl:
    # 可以看到每个批次的样本长度不是一样的
    print(batch["input_ids"].size())
    num += 1
    if num > 10:
        break
torch.Size([4, 117])
torch.Size([4, 128])
torch.Size([4, 128])
torch.Size([4, 128])
torch.Size([4, 128])
torch.Size([4, 100])
torch.Size([4, 82])
torch.Size([4, 128])
torch.Size([4, 128])
torch.Size([4, 128])
torch.Size([4, 91])

1.5 利用Datasets优化情感分类

1.5.1 加载数据集

from transformers import AutoTokenizer, AutoModelForSequenceClassification
from datasets import load_dataset

# 1、加载数据集
dataset = load_dataset("csv", data_files="./ChnSentiCorp_htl_all.csv", split="train")
dataset = dataset.filter(lambda x: x["review"] is not None)

# 2、划分数据集
datasets = dataset.train_test_split(test_size=0.1)
datasets
DatasetDict({
    train: Dataset({
        features: ['label', 'review'],
        num_rows: 6988
    })
    test: Dataset({
        features: ['label', 'review'],
        num_rows: 777
    })
})

1.5.2 创建Dataloader

import torch
from torch.utils.data import DataLoader
from transformers import DataCollatorWithPadding

# 1、加载离线模型
model_path = '/root/autodl-fs/models/rbt3'
tokenizer = AutoTokenizer.from_pretrained(model_path)

def process_function(examples):
    tokenized_examples = tokenizer(examples["review"], max_length=128, truncation=True)
    tokenized_examples["labels"] = examples["label"]
    return tokenized_examples

# 2、词元化
tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)



# 3、创建Dataloader
trainset, validset = tokenized_datasets["train"], tokenized_datasets["test"]
trainloader = DataLoader(trainset, batch_size=32, shuffle=True, collate_fn=DataCollatorWithPadding(tokenizer))
validloader = DataLoader(validset, batch_size=64, shuffle=False, collate_fn=DataCollatorWithPadding(tokenizer))

1.5.3 创建模型及优化器

from torch.optim import Adam

# 1、创建模型
model = AutoModelForSequenceClassification.from_pretrained(model_path)

if torch.cuda.is_available():
    model = model.cuda()
# 2、创建优化器
optimizer = Adam(model.parameters(), lr=2e-5)    

1.5.4 训练与验证

def evaluate():
    model.eval()
    acc_num = 0
    with torch.inference_mode():
        for batch in validloader:
            if torch.cuda.is_available():
                batch = {k: v.cuda() for k, v in batch.items()}
            output = model(**batch)
            pred = torch.argmax(output.logits, dim=-1)
            acc_num += (pred.long() == batch["labels"].long()).float().sum()
    return acc_num / len(validset)

def train(epoch=3, log_step=100):
    global_step = 0
    for ep in range(epoch):
        model.train()
        for batch in trainloader:
            if torch.cuda.is_available():
                batch = {k: v.cuda() for k, v in batch.items()}
            optimizer.zero_grad()
            output = model(**batch)
            output.loss.backward()
            optimizer.step()
            if global_step % log_step == 0:
                print(f"ep: {ep}, global_step: {global_step}, loss: {output.loss.item()}")
            global_step += 1
        acc = evaluate()
        print(f"ep: {ep}, acc: {acc}")
train()
ep: 0, global_step: 0, loss: 0.7134996056556702
ep: 0, global_step: 100, loss: 0.2385680228471756
ep: 0, global_step: 200, loss: 0.3343896269798279
ep: 0, acc: 0.8764479160308838
ep: 1, global_step: 300, loss: 0.15788553655147552
ep: 1, global_step: 400, loss: 0.339910626411438
ep: 1, acc: 0.8867439031600952
ep: 2, global_step: 500, loss: 0.24706700444221497
ep: 2, global_step: 600, loss: 0.24163328111171722
ep: 2, acc: 0.8828828930854797

1.5.5 模型预测

sen = "我觉得这家酒店不错,饭很好吃!"
id2_label = {0: "差评!", 1: "好评!"}
model.eval()
with torch.inference_mode():
    inputs = tokenizer(sen, return_tensors="pt")
    inputs = {k: v.cuda() for k, v in inputs.items()}
    logits = model(**inputs).logits
    pred = torch.argmax(logits, dim=-1)
    print(f"输入:{sen}\n模型预测结果:{id2_label.get(pred.item())}")
输入:我觉得这家酒店不错,饭很好吃!
模型预测结果:好评!
from transformers import pipeline

model.config.id2label = id2_label
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)
pipe(sen)
[{'label': '好评!', 'score': 0.9937521815299988}]

2、基础组件Evaluate

  • 在训练模型的时候,我们往往会将数据划分为训练集和验证集,会根据模型在验证集的性能来评价模型的好坏。

  • 任务不同,对应的评价指标也不一样,常见的指标包括Accuracy、F1、Rouge等。

  • Evaluate包的出现,一定程度上简化了上述工作,我们可以通过像加载数据集一样加载对应的评估函数,进行模型评估。

2.1 评估函数常用操作

2.1.1 查看评估函数

import evaluate

# 查看支持的评估函数
evaluate.list_evaluation_modules(include_community=False, with_details=True)
# 在线加载评估函数
accuracy = evaluate.load("accuracy")

# 查看函数说明
print(accuracy.description)

print(accuracy.inputs_description)

2.1.2 评估指标计算

# 全局计算
accuracy = evaluate.load("accuracy")
results = accuracy.compute(references=[0, 1, 2, 0, 1, 2], predictions=[0, 1, 1, 2, 1, 0])
results # {'accuracy': 0.5}
# 迭代计算
accuracy = evaluate.load("accuracy")
for refs, preds in zip([[0,1],[0,1]], [[1,0],[0,1]]):
    accuracy.add_batch(references=refs, predictions=preds)
accuracy.compute() # {'accuracy': 0.5}
# 多个指标计算
clf_metrics = evaluate.combine(["accuracy", "f1", "recall", "precision"])
clf_metrics.compute(predictions=[0, 1, 0], references=[0, 1, 1])
{'accuracy': 0.6666666666666666,
 'f1': 0.6666666666666666,
 'recall': 0.5,
 'precision': 1.0
 }

2.2 利用Evaluate优化情感分类

加载数据集、创建Dataloader、创建模型及优化器和1.5一致。

2.2.1 训练与验证

import evaluate

# clf_metrics = evaluate.combine(["accuracy", "f1"])

"""
如果直接使用指标名称“accuracy”等,
由于网络问题,无法顺利下载
但是这个错误不会显示,因此导入进去会卡死


解决方法:


从官网下载metrics文件夹,放置在本地的路径,进行离线加载

"""
accuracy_path = '/root/autodl-tmp/transformers-code/metrics/accuracy'
f1_path = '/root/autodl-tmp/transformers-code/metrics/f1'
clf_metrics = evaluate.combine([accuracy_path, f1_path])

# 示例
clf_metrics.compute(references=[0,1,0,1], predictions=[1,0,0,1])

# {'accuracy': 0.5, 'f1': 0.5}
def evaluate():
    model.eval()
    with torch.inference_mode():
        for batch in validloader:
            if torch.cuda.is_available():
                batch = {k: v.cuda() for k, v in batch.items()}
            output = model(**batch)
            pred = torch.argmax(output.logits, dim=-1)
            clf_metrics.add_batch(predictions=pred.long(), references=batch["labels"].long())
    return clf_metrics.compute()

def train(epoch=3, log_step=100):
    global_step = 0
    for ep in range(epoch):
        model.train()
        for batch in trainloader:
            if torch.cuda.is_available():
                batch = {k: v.cuda() for k, v in batch.items()}
            optimizer.zero_grad()
            output = model(**batch)
            output.loss.backward()
            optimizer.step()
            if global_step % log_step == 0:
                print(f"ep: {ep}, global_step: {global_step}, loss: {output.loss.item()}")
            global_step += 1
        clf = evaluate()
        print(f"ep: {ep}, {clf}")
# 进行训练
train()
ep: 0, global_step: 0, loss: 0.6701369285583496
ep: 0, global_step: 100, loss: 0.3432188630104065
ep: 0, global_step: 200, loss: 0.29397645592689514
ep: 0, {'accuracy': 0.9086229086229086, 'f1': 0.9356300997280146}
ep: 1, global_step: 300, loss: 0.2728956639766693
ep: 1, global_step: 400, loss: 0.23207390308380127
ep: 1, {'accuracy': 0.9137709137709138, 'f1': 0.9391462306993643}
ep: 2, global_step: 500, loss: 0.10437105596065521
ep: 2, global_step: 600, loss: 0.18092380464076996
ep: 2, {'accuracy': 0.8996138996138996, 'f1': 0.9275092936802974}

2.2.2 模型预测

sen = "我觉得这家酒店不错,饭很好吃!"
id2_label = {0: "差评!", 1: "好评!"}
model.eval()
with torch.inference_mode():
    inputs = tokenizer(sen, return_tensors="pt")
    inputs = {k: v.cuda() for k, v in inputs.items()}
    logits = model(**inputs).logits
    pred = torch.argmax(logits, dim=-1)
    print(f"输入:{sen}\n模型预测结果:{id2_label.get(pred.item())}")
输入:我觉得这家酒店不错,饭很好吃!
模型预测结果:好评!
from transformers import pipeline

model.config.id2label = id2_label
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)
pipe('这家酒店床上特别脏、隔音特别差、还特别贵')
[{'label': '差评!', 'score': 0.9784351587295532}]

3、基础组件Trainer

  • Trainer模块是基础组件的最后一个模块,它封装了一套完整的在数据集上训练、评估与预测的流程。借助Trainer模块,可以快速启动训练。

  • Trainer模块主要包含两部分的内容:TrainingArguments与Trainer,前者用于训练参数的设置,后者用于创建真正的训练器,进行训练、评估预测等实际操作。

  • 此外,针对Seq2Seq训练任务,提供了专门的Seq2SeqTrainingArguments与Seq2SeqTrainer,整体与TrainingArguments和Trainer类似,但是提供了专门用于生成的部分参数。

3.1 TrainingArguments

TrainingArguments中可以配置整个训练过程中使用的参数,默认版本是包含90个参数,涉及模型存储、模型优化、训练日志、GPU使用、模型精度、分布式训练等多方面的配置内容,等后面用到再介绍。

Seq2SeqTrainingArguments中除了上述的内容还包括生成部分的参数设置,如是否要进行生成、最大长度等共94个参数。

3.2 Trainer

Trainer中配置具体的训练用到的内容,包括模型、训练参数、训练集、验证集、分词器、评估函数等内容。

  • 当指定完上述对应参数,便可以通过调用train方法进行模型训练;

  • 训练完成后可以通过调用evaluate方法对模型进行评估;

  • 得到满意的模型后,最后调用predict方法对数据集进行预测。

from transformers import TrainingArguments, Trainer

# 创建TrainingArguments
training_args = TrainingArguments(...)
# 创建Trainer
trainer = Trainer(..., args=training_args, ...)


# 模型训练
trainer.train()
# 模型评估
trainer.evaluate()
# 模型预测
trainer.predict()

需要特别注意的是,使用Trainer进行模型训练对模型的输入输出是有限制的,要求模型返回ModelOutput的元组或子类,同时如果提供了标签,模型要能返回loss结果,并且loss要作为ModelOutput元组的第一个值

3.3 利用Trainer优化情感分类

3.1 数据预处理

from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
from datasets import load_dataset

import warnings
warnings.filterwarnings("ignore")

# 1、加载数据集
dataset = load_dataset("csv", data_files="./ChnSentiCorp_htl_all.csv", split="train")
dataset = dataset.filter(lambda x: x["review"] is not None)

# 2、划分数据集
datasets = dataset.train_test_split(test_size=0.1)


# 3、词元化
# 加载离线模型
model_path = '/root/autodl-fs/models/rbt3'
tokenizer = AutoTokenizer.from_pretrained(model_path)

def process_function(examples):
    tokenized_examples = tokenizer(examples["review"], max_length=128, truncation=True)
    tokenized_examples["labels"] = examples["label"]
    return tokenized_examples

tokenized_datasets = datasets.map(process_function, batched=True, remove_columns=datasets["train"].column_names)

tokenized_datasets
DatasetDict({
    train: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 6988
    })
    test: Dataset({
        features: ['input_ids', 'token_type_ids', 'attention_mask', 'labels'],
        num_rows: 777
    })
})

3.2 创建模型

model = AutoModelForSequenceClassification.from_pretrained(model_path)

3.3 创建模型评估函数

import evaluate

# 下面方式可能加载失败
# acc_metric = evaluate.load("accuracy")
# f1_metirc = evaluate.load("f1")

# 这里采用离线加载
accuracy_path = '/root/autodl-tmp/transformers-code/metrics/accuracy'
f1_path = '/root/autodl-tmp/transformers-code/metrics/f1'

acc_metric = evaluate.load(accuracy_path)
f1_metirc = evaluate.load(f1_path)

def eval_metric(eval_predict):
    predictions, labels = eval_predict
    predictions = predictions.argmax(axis=-1)
    acc = acc_metric.compute(predictions=predictions, references=labels)
    f1 = f1_metirc.compute(predictions=predictions, references=labels)
    acc.update(f1)
    return acc

3.4 创建TrainingArguments及Trainer

创建TrainingArguments

train_args = TrainingArguments(output_dir="./checkpoints",      # 输出文件夹
                               per_device_train_batch_size=64,  # 训练时的batch_size
                               per_device_eval_batch_size=128,  # 验证时的batch_size
                               logging_steps=10,                # log 打印的频率
                               evaluation_strategy="epoch",     # 评估策略
                               save_strategy="epoch",           # 保存策略
                               save_total_limit=3,              # 最大保存数
                               learning_rate=2e-5,              # 学习率
                               weight_decay=0.01,               # weight_decay
                               metric_for_best_model="f1",      # 设定评估指标
                               load_best_model_at_end=True)     # 训练完成后加载最优模型

创建Trainer

from transformers import DataCollatorWithPadding
trainer = Trainer(model=model,     # 预训练模型
                  args=train_args, # 训练参数
                  train_dataset=tokenized_datasets["train"], # 训练集
                  eval_dataset=tokenized_datasets["test"],   # 验证集
                  data_collator=DataCollatorWithPadding(tokenizer=tokenizer),# DataCollator,填充到一个批次中最大长度,加快填充的速度
                  compute_metrics=eval_metric  # 指标评估的方法
)

3.5 模型训练及预测

trainer.train()

在这里插入图片描述

from transformers import pipeline


id2_label = {0: "差评!", 1: "好评!"}
model.config.id2label = id2_label
pipe = pipeline("text-classification", model=model, tokenizer=tokenizer, device=0)

pipe('这家酒店隔音不错、位置离地铁站近、去西湖很方便。')
[{'label': '好评!', 'score': 0.9933173656463623}]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1120061.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习杂谈1

不知道写些什么就想着把这段时间网上看到的一些面试题写下来,供各个找工作的人参考 简述一下RabbitMQ的工作模式 simple模式(即最简单的收发模式) 消息产生消息,将消息放入队列消息的消费者(consumer)监听:消息队列&a…

YOLOV8改进:RefConv(即插即用重参数化重聚焦卷积替代常规卷积,无额外推理成本下涨点明显)

1.该文章属于YOLOV5/YOLOV7/YOLOV8改进专栏,包含大量的改进方式,主要以2023年的最新文章和2022年的文章提出改进方式。 2.提供更加详细的改进方法,如将注意力机制添加到网络的不同位置,便于做实验,也可以当做论文的创新点。 3.涨点效果:RefConv,实现有效涨点! 论文地址…

游戏设计模式专栏(十三):在Cocos游戏开发中运用责任链模式

点击上方亿元程序员关注和★星标 引言 大家好,我是亿元程序员,一位有着8年游戏行业经验的主程。 本系列是《和8年游戏主程一起学习设计模式》,让糟糕的代码在潜移默化中升华,欢迎大家关注分享收藏订阅。 责任链模式&#xff…

面试题:谈谈过滤器和拦截器的区别?

文章目录 一、拦截器和过滤器的区别二、拦截器和过滤器的代码实现1、拦截器2、过滤器 三、总结1、什么是Filter及其作用介绍2、Filter API介绍3、Filter链与Filter生命周期 四、拦截器五、过滤器和拦截器的区别 一、拦截器和过滤器的区别 1、拦截器(Interceptor)只对action请求…

全球国家行政区划边界(中国科学院地理科学与资源研究所)

简介: 行政区划边界是指各个行政区域之间划定的界限,以确保行政管理的有序和合法。通常,这些边界是根据政治、行政、文化等因素来划分的,如国家、省份、市级行政单元、县区等。这些行政区划边界的划分和调整需要经过政府的制定和…

proteus中仿真arduino的水位测试传感器

一、原理介绍 我们这里使用的水位传感器,只能说是一个小实验用途的水位传感器。我们首先上图 如上图所示,线没有连接,传感器由许5对裸露在外的铜线片作为传感部分,当浸入水中时这些铜线片会被水桥接。 这些被水连接起来的铜线&a…

CUDA学习笔记(二)CUDA简介

本篇博文转载于https://www.cnblogs.com/1024incn/tag/CUDA/,仅用于学习。 CUDA是并行计算的平台和类C编程模型,我们能很容易的实现并行算法,就像写C代码一样。只要配备的NVIDIA GPU,就可以在许多设备上运行你的并行程序&#xf…

2024王道考研计算机组成原理——指令系统

零、本章概要 指令寻址:解决的是PC"1"的问题 数据寻址:使用寄存器/内存/结合 基址寻址:用于多道程序的并发执行 直接寻址:call 0x12345678 变址寻址:esi edi用于循环,因为使用直接寻址需要一堆…

TX Text Control ActiveX 32.0 For VB6 Crack

ActiveX Visual Basic 6 应用程序的文档处理,TX Text Control适用于 Visual Basic 6 和基于 COM 的语言的综合文字处理和报告 视窗用户界面,功能齐全的文档编辑器 TX Text Control 是一款完全可编程的丰富编辑控件,它在专为 Visual Studio 设…

自然语言处理---Transformer机制详解之BERT模型介绍

1 BERT简介 BERT是2018年10月由Google AI研究院提出的一种预训练模型. BERT的全称是Bidirectional Encoder Representation from Transformers.BERT在机器阅读理解顶级水平测试SQuAD1.1中表现出惊人的成绩:全部两个衡量指标上全面超越人类,并且在11种不…

计算机视觉实战项目3(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人机检测+A*路径规划+单目测距与测速+行人车辆计数等)

车辆跟踪及测距 该项目一个基于深度学习和目标跟踪算法的项目,主要用于实现视频中的目标检测和跟踪。该项目使用了 YOLOv5目标检测算法和 DeepSORT 目标跟踪算法,以及一些辅助工具和库,可以帮助用户快速地在本地或者云端上实现视频目标检测和…

最新AI智能写作创作系统源码V2.6.4/AI绘画系统/支持GPT联网提问/支持Prompt应用

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统,支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…

[深入浅出AutoSAR] SWC 设计与应用

依AutoSAR及经验辛苦整理,原创保护,禁止转载。 专栏 《深入浅出AutoSAR》 全文 3100 字, 包含 1. SWC 概念 2. 数据类型(Datatype) 3. 端口(Port) 4. 端口接口(Portinterface&…

【终极版】刷完这100行Python,从新人变成大佬

文章目录 基础入门菜鸟提升基础晋级高手之路内置包库奇技淫巧 基础入门 1 python 即在命令行输入python,进入Python的开发环境。 2 x 12*3-4/56**2 加减乘除四则混合运算,可当作计算器使用,其中**表示乘方。 3 print(x) 输出x的值&#x…

2023年中国跨境电商进出口数据及分布占比分析

中商情报网讯:据海关数据,2022年中国跨境电商进出口(含B2B)2.11万亿元,同比增长9.8%,跨境电商进出口规模首次突破2万亿元关口。其中,出口1.55万亿元,进口0.56万亿元。 2023上半年&a…

基于SSM的快递管理系统设计与实现

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

RBAC——基于角色权限的模型

目录 1、RBAC是什么? 2、为什么要使用RBAC模型? 3、RBAC的适用场景 4、RBAC流程图 5、RBAC各模块功能 6、访问控制流程 7、数据库设计及相关表结构 8、RBAC模型的JPA简单实现-单表及多表查询 9、RBAC模型四级分级 10、总结(优缺点&…

Spring Cloud Alibaba系列(6)之nacos集群搭建

传送门 Spring Cloud Alibaba系列之nacos:(1)安装 Spring Cloud Alibaba系列之nacos:(2)单机模式支持mysql Spring Cloud Alibaba系列之nacos:(3)服务注册发现 Spring Cloud Alibaba系列之nacos:(4)配置管理 Spring Cloud Al…

将本地的项目上传到Gitee

目录 1.先在Gitee新建一个仓库,提交即可 2.进入到要上传的项目里面,右键选择 Git Bash Here 3.右键后就打开了Git命令窗口 4.配置你的用户名和邮箱(已经配置过则可跳过) 5.查看你的用户名和邮箱配置(可不查看) 6.输入git init指令&#…

【第二天】C++类和对象解析:构造函数、析构函数和拷贝构造函数的完全指南

一、类的引出概述 在c语言结构体中,行为和属性是分开的,万一调用错误,将会导致问题发生。c中类将数据和方法封装在一起,加以权限区分,用户只能通过公共方法 访问 私有数据。 二、封装 封装特性包含两个方面&#xff0…