Transformer: Training and fine-tuning(六)_transformers.from_pretrained batch-程序员宅基地

技术标签: 文本挖掘,情感分类  

1.Fine-tuning in native本地 PyTorch

模型类model class不是以TF开头的都是以Pytorch来运行的。

接下来考虑微调fine-tune一个BERT模型来做句子分类任务。当我们使用from_pretrained()实例化一个模型时,所指定模型的配置configuration 和预训练的权重会被用于初始化模型,这个库library也会包含一些指定任务(task-specific)的最后一层final layer或者头head。当final layers 和head 没有出现在指定的预训练模型中时,会随机分配权重给它们。

举例:实例化一个模型,用的是
BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2)
就会创建一个实例,这个实例会带有来自bert-base-uncased 模型的encoder weights,编码权重。并且随机初始化句子分类头(sequence classification head)在encoder上,output size是2。
模型是默认在eval模式下进行初始化的。我们可以用model.train() 来将其放进训练模式中(to put it in train mode)

from transformers import BertForSequenceClassification
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
model.train()

这是有用的,因为这允许我们利用预训练的BERT编码器(encoder),简单地在任何我们选择的分类数据集上进行训练。我们可以用任何Pytorch的优化器optimizer。同时我们也提供了AdamW()优化器,其实现梯度偏差校正以及权重衰减。

from transformers import AdamW
optimizer = AdamW(model.parameters(), lr=1e-5)

优化器允许我们为特定的参数组应用不同的超参数。 例如,我们可以将权重衰减应用于除bias和layer归一化以外的所有参数:

no_decay = ['bias', 'LayerNorm.weight']
optimizer_grouped_parameters = [
    {
    'params': [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)], 'weight_decay': 0.01},
    {
    'params': [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)], 'weight_decay': 0.0}
]
optimizer = AdamW(optimizer_grouped_parameters, lr=1e-5)

接下来我们可以设置一个极其简单的training batch,使用__call__() ,也就是对其本身进行调用。返回BatchEncoding()实例,这个实例准备好了任何我们想传进模型的东西。

from transformers import BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
text_batch = ["I love Pixar.", "I don't care for Pixar."]
encoding = tokenizer(text_batch, return_tensors='pt', padding=True, truncation=True)
input_ids = encoding['input_ids']
attention_mask = encoding['attention_mask']

当我们召唤一个带有labels参数的分类模型,返回的第一个元素就是预测值和传进去的标签值之间的Cross Entropy loss交叉熵损失。设置好我们的优化器optimizer后,我们可以就可以做后向传播并更新权重了。

labels = torch.tensor([1,0]).unsqueeze(0)
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()

或者,你可以只获取logits并计算自己的损失值,下面的代码跟上面等价

from torch.nn import functional as F
labels = torch.tensor([1,0])
outputs = model(input_ids, attention_mask=attention_mask)
loss = F.cross_entropy(outputs.logits, labels)
loss.backward()
optimizer.step()

当然,可以通过召唤to('cuda')来用GPU训练

我们还提供了一些学习率的调节工具。 通过以下内容,我们可以设置一个调节程序,该调节程序为num_warmup_steps预热,然后在训练结束前线性衰减为0。

from transformers import get_linear_schedule_with_warmup
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps, num_train_steps)

然后只要在optimizer.step()之后召唤scheduler.step()

loss.backward()
optimizer.step()
scheduler.step()

我们强烈推荐使用**Trainer()**会在下面讨论,很方便的训练Transformer模型,

1.1 Freezing the encoder 冻结编码器

在有些情况下,你需要保持预训练编码器的权重冻结,只对head layers的权重进行优化,要这么做的话,只需要在encoder 参数上设置requires_grad 为 False,这样就可以使库中任何task-specific model上的base_model子模块来访问它:

for param in model.base_model.parameters():
    param.requires_grad = False

2.在tensorflow上微调

3.Trainer

我们也提供了简单,但功能完善的训练和评估接口:Trainer()TFTrainer(),你可以用于训练,微调,评估任何Transformer模型,有这非常多的训练options可供选择,还有许多内建的属性比如 logging, gradient accumulation, and mixed precision.

from transformers import BertForSequenceClassification, Trainer, TrainingArguments

model = BertForSequenceClassification.from_pretrained("bert-large-uncased")

training_args = TrainingArguments(
    output_dir='./results',          # output directory
    num_train_epochs=3,              # total # of training epochs
    per_device_train_batch_size=16,  # batch size per device during training
    per_device_eval_batch_size=64,   # batch size for evaluation
    warmup_steps=500,                # number of warmup steps for learning rate scheduler
    weight_decay=0.01,               # strength of weight decay
    logging_dir='./logs',            # directory for storing logs
)

trainer = Trainer(
    model=model,                         # the instantiated  Transformers model to be trained
    args=training_args,                  # training arguments, defined above
    train_dataset=train_dataset,         # training dataset
    eval_dataset=test_dataset            # evaluation dataset
)

接下来,简单的使用trainer.train() 来训练,使用 trainer.evaluate() 来评估,你也可以是用你自己的模块,但是第一个从forward返回的参数必须是损失值,这个损失值是用来优化的

Trainer()使用的是内建的函数来收集batches并准备好将它们传进模型中,如果需要,也可以使用data_collator参数来传你自己的collator function(校对函数),这个校对函数传进以你提供的数据集的格式的数据,返回可以传进模型的batch。

要计算除损失之外的其他指标,您还可以定义自己的compute_metrics函数并将其传递给Trainer。

from sklearn.metrics import accuracy_score, precision_recall_fscore_support

def compute_metrics(pred):
    labels = pred.label_ids
    preds = pred.predictions.argmax(-1)
    precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average='binary')
    acc = accuracy_score(labels, preds)
    return {
    
        'accuracy': acc,
        'f1': f1,
        'precision': precision,
        'recall': recall
    }

最后,您可以通过在指定的logging_dir目录中启动tensorboard来查看结果,包括所有计算的指标。、

一个轻量化的colab demo,展示IMDb电影情感分析,使用的Trainer,链接

from transformers import BertForSequenceClassification, BertTokenizerFast, Trainer, TrainingArguments
from nlp import load_dataset
import torch
import numpy as np
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
tokenizer = BertTokenizerFast.from_pretrained('bert-base-uncased')
def tokenize(batch):
    return tokenizer(batch['text'], padding=True, truncation=True)

train_dataset, test_dataset = load_dataset('imdb', split=['train', 'test'])
train_dataset = train_dataset.map(tokenize, batched=True, batch_size=len(train_dataset))
test_dataset = test_dataset.map(tokenize, batched=True, batch_size=len(train_dataset))
train_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])
test_dataset.set_format('torch', columns=['input_ids', 'attention_mask', 'label'])
def compute_metrics(pred):
    labels = pred.label_ids
    preds = pred.predictions.argmax(-1)
    precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average='binary')
    acc = accuracy_score(labels, preds)
    return {
    
        'accuracy': acc,
        'f1': f1,
        'precision': precision,
        'recall': recall
    }

training_args = TrainingArguments(
    output_dir='./results',
    num_train_epochs=1,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=64,
    warmup_steps=500,
    weight_decay=0.01,
    evaluate_during_training=True,
    logging_dir='./logs',
)

trainer = Trainer(
    model=model,
    args=training_args,
    compute_metrics=compute_metrics,
    train_dataset=train_dataset,
    eval_dataset=test_dataset
)
trainer.train()
trainer.evaluate()
{
    'epoch': 1.0,
 'eval_accuracy': 0.93552,
 'eval_f1': 0.9362089434111595,
 'eval_loss': 0.18167165885476963,
 'eval_precision': 0.926311667971809,
 'eval_recall': 0.94632}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42167712/article/details/110890965

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签