transformers库的使用【三】对预训练模型进行微调

1、准备一个数据集

在这里将使用Datasets库来下载和准备IMDB数据集

首先,使用load_dataset函数来下载数据集

from datasets import load_dataset
raw_datasets = load_dataset("imdb")

这里创建的raw_datasets对象是一个包三个键的字典,其中包含:train、test和unsupervised。

在这里我们将使用train进行训练,使用test进行验证

DatasetDict({
    train: Dataset({
        features: ['text', 'label'],
        num_rows: 25000
    })
    test: Dataset({
        features: ['text', 'label'],
        num_rows: 25000
    })
    unsupervised: Dataset({
        features: ['text', 'label'],
        num_rows: 50000
    })
})

为了对数据集进行处理,这里需要一个编码器tokenizer

创建一个编码器

from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained('bert-base-cased')

接下来去使用map方法来处理每一个部分

def tokenize_function(examples):
    return tokenizer(examples["text"],padding='max_length',truncation=True)
tokenized_datasets = raw_datasets.map(tokenize_function,batched=True)
print(tokenized_datasets)

 处理完的数据集成了下面的样子

DatasetDict({
    train: Dataset({
        features: ['attention_mask', 'input_ids', 'label', 'text', 'token_type_ids'],
        num_rows: 25000
    })
    test: Dataset({
        features: ['attention_mask', 'input_ids', 'label', 'text', 'token_type_ids'],
        num_rows: 25000
    })
    unsupervised: Dataset({
        features: ['attention_mask', 'input_ids', 'label', 'text', 'token_type_ids'],
        num_rows: 50000
    })
})

那么,接下来去划分一个小的训练集和验证集,来更快的训练

small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))
full_train_dataset = tokenized_datasets["train"]
full_eval_dataset = tokenized_datasets["test"]

在pytorch中使用Trainer API进行微调

由于Pytorch中不提供训练循环,因此Transformers库提供了一个针对Transformers模型的优化器,具有广泛的训练选项以及内置功能

接下来定义模型

from transformers import AutoModelForSequenceClassification
model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased",num_labels=2)

注意,这里会提示一些警告,提示一些未使用与预训练的权重,同时有些权重将会被随机初始化。

Some weights of the model checkpoint at bert-base-cased were not used when initializing BertForSequenceClassification: ['cls.predictions.transform.dense.weight', 'cls.predictions.transform.LayerNorm.weight', 'cls.predictions.transform.LayerNorm.bias', 'cls.predictions.bias', 'cls.seq_relationship.weight', 'cls.seq_relationship.bias', 'cls.predictions.decoder.weight', 'cls.predictions.transform.dense.bias']
- This IS expected if you are initializing BertForSequenceClassification from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing BertForSequenceClassification from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
Some weights of BertForSequenceClassification were not initialized from the model checkpoint at bert-base-cased and are newly initialized: ['classifier.weight', 'classifier.bias']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.

这是因为我们没有使用BERT模型的与训练头,而是使用随机初始化的分类头。

我们将在任务中对这个模型进行微调,把预训练模型的知识转移进去

接下来我们要创建一个Trainer,我们需要实例化TrainingArguments

这个类包含了Trainer的超参数

from transformers import TrainingArguments

training_args = TrainingArguments("test_trainer")

接下来我们需要实例化一个Trainer

from transformers import Trainer
trainer = Trainer(
    model = model,
    args = training_args,
    train_dataset= small_train_dataset,
    eval_dataset=small_eval_dataset
)

 为了微调模型,只需要使用trainer.train()

trainer.train()

在调用过train函数后,可以使用进度条查看训练进度。

 但是这里不会告诉你模型表现如何,默认情况下在训练期间没有评估,那么如何在训练过程中进行模型的评估呢?

为了让Trainer来计算并显示评价指标,需要一个计算指标的函数,这个函数需要接收预测的标签和真实的标签。

在Dataset库中,提供了一个很简单的方法load_metric函数,这个函数中包含一些常用的评价指标。

import numpy as np
from datasets import load_metric
metric = load_metric("accuracy")
def compute_metric(eval_pred):
    logits,labels = eval_pred
    predictions = np.argmax(logits,axis=-1)
    return metric.compute(predictions = predictions,references = labels)
trainer = Trainer(
    model = model,
    args = training_args,
    train_dataset= small_train_dataset,
    eval_dataset=small_eval_dataset,
    compute_metric = compute_metric,
)
trainer.evaluate()

注意,计算函数compute_metric的参数是一个元组,这个元组分别是logits和labels。返回一个带有字符串键的字典。

这个函数将在每一个评估阶段结束的时候,对整个预测/标签数组进行调用。

好的,这是一个很有趣的问题!BERT(Bidirectional Encoder Representations from Transformers)是一种基于Transformer架构的预训练模型,它在自然语言处理领域得到了广泛的应用。对于文本分类任务,我们可以使用BERT预训练模型来提取文本的特征表示,并将这些表示作为输入,通过全连接层进行分类。具体的步骤如下: 1. 下载预训练的BERT模型,在此模型上进行微调。可以选择使用已经训练好的模型,也可以对自己的数据进行微调。 2. 对于每一个输入文本,需要进行一些预处理步骤。首先,将文本转化为标记化的文本,即将每个单词或子单词转化为一个唯一的标记。然后,将每个标记转化为对应的标记ID,并添加一些特殊的标记,如[CLS]和[SEP]。 3. 将标记化的文本输入到BERT模型中,获取每个标记的特征表示。对于分类任务,通常使用最后一个隐藏层的输出,即[CLS]标记所对应的特征表示。 4. 将特征表示输入到一个全连接层中,进行分类。可以使用softmax函数将输出转化为类别概率。 5. 使用交叉熵损失函数进行训练,并根据验证集的表现进行调参。 6. 在测试阶段,输入文本到模型中,获取输出概率,选择概率最大的类别作为预测结果。 以上就是使用BERT预训练模型+微调进行文本分类的基本步骤。需要注意的是,由于BERT模型的复杂性,需要较大的计算资源和时间。同时,在微调阶段需要对超参数进行调参,以达到最优的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值