HuggingFace API学习(2)

HuggingFace API学习

Fine-Tuning

处理数据

在之前获取tokenizer和model的基础上,增加以下代码:

batch = tokenizer(sequences, padding=True, truncation=True, return_tensors="pt")

# This is new
batch["labels"] = torch.tensor([1, 1])

optimizer = AdamW(model.parameters())
loss = model(**batch).loss
loss.backward()
optimizer.step()

这部分比较容易懂,为了能够得到一个较好的效果,就需要一个较大的数据集

在这个部分,我们将使用MRPC数据集作为例子,这个数据集包含5801对带有标签的句子。

加载数据:

从hub上加载数据集,所有可用的数据集:

https://huggingface.co/datasets?sort=downloads

从hub上下载MRPC数据集:

from datasets import load_dataset

raw_datasets = load_dataset("glue", "mrpc")
print(raw_datasets.data)

出现的问题:无法连接到"raw.githubusercontent.com"这个网站

解决方法:在网站https://www.ipaddress.com中输入“raw.githubusercontent.com”,可以查到该网站允许访问的Ip地址,如下图:

在这里插入图片描述
在C盘的hosts文件中添加:

185.199.108.133 raw.githubusercontent.com

即可正常运行代码。

得到dataset之后,该dataset是一个字典,被分为了训练集、测试集、验证集,可以使用下标的形式进行获取:

raw_trian_dataset = raw_datasets["train"]
raw_test_dataset = raw_datasets["test"]
raw_val_dataset = raw_datasets["validation"]

print(raw_trian_dataset[0])

其中训练集中的label已经被设置成了numpy,如若想知道对应什么含义,可以使用如下语句:

raw_train_dataset.features

处理数据:

直接使用Tokenizer方法处理刚刚加载在数据集中的数据(根据dataset中的feature进行处理),并且应该将两句话拼接起来,但是使用不同的sentence token:

tokenized_dataset = tokenizer(
    raw_trian_dataset["sentence1"],
    raw_trian_dataset["sentence2"],
    padding=True,
    truncation=True,
    return_tensors="pt"
)

为了能保存数据集,这里先写一个函数:

def tokenize_function(example):
    return tokenizer(example["sentence1"], example["sentence2"], truncation=True)
    
tokenized_datasets = raw_datasets.map(tokenize_function, batched=True)

这里将padding去除了,因为一下子对所有的数据padding相比于对一个batch的数据padding,效率低很多。map方法提供了很大的灵活性,可以一次性对所有的数据进行处理,并且速度更快,而且不需要更大的RAM。并且处理过程可以自由设计,可以不仅仅进行tokenizer操作。最终的结果存放在input_id中。

动态填充

在每批需要时应用填充技术,避免输入过长,这能加快训练速度。但是如果是在TPU上进行训练,则可能需要额外的填充,因为TPU更喜欢固定的形状。

为了实现这一点,必须定义一个collate函数,这里直接使用库中有的:

from transformers import DataCollatorWithPadding

data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

接着使用该函数对数据集进行padding(没怎么学明白,官方文档给的有点粗略了)

使用Trainer API进行Fine-tuning操作

Transformers提供了一个Trainer的类去对任何的预训练模型进行fine-tune操作。

首先应该定义一个TrainArguments类,它包含了Trainer用到的所有超参数。我们唯一需要输入的参数是一个模型保存路径。

from transformers inport TrainingArguments

training_args = TrainingArguments("test-trainer")  # 定义一个trainer所需要的超参数

定义完所有的工具之后,就可以定义Trainer类了:

trainer = Trainer(
    model,
    training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    data_collator=data_collator,
    tokenizer=tokenizer
)

要在数据集上进行微调,只需要调用trainer.train()

开始训练之后,他会每500个steps就报告一次训练损失。但是它不会报告这个模型的性能表现,主要有两个原因:

  1. 我们没有告诉Trainer在训练期间通过设置评估策略(每多少步或者每多少epoch)来进行模型评估。
  2. 没有给Trainer提供评估方法。

模型评估:

我们要想写一个有用的compute_metrics()方法,该方法必须接收一个EvalPrediction对象,这个对象需要是一个元组,并且有prediction和label_ids。为了从模型中得到预测,需要使用Trainer.predict()方法。

该方法返回的也是一个元组,他有三个fields,predictions,label_ids和metrices。第三个fields现在存放的是loss,一旦我们完成了compute_metrics()方法的编写并且将它加入到Trainer中,这个field也将包含compute_metrics()方法的返回值。

print(predictions.predictions.shape, predictions.label_ids.shape)  # predictions是对每个类别的一个打分,我们需要获得得分值最大的标签的index
preds = np.argmax(predictions.predictions)   # 获取最大值的索引值

(题外话)准确率计算方法:sklearn.metrics.accuracy_score(true, predic)

使用evaluate库中的方法构造compute_metric()方法,这样就得到了compute_metrics方法:

def compute_metrics(eval_preds):
    metric = evaluate.load("glue", "mrpc")
    logits, labels = eval_preds
    predictions = np.argmax(logits, axis=-1)
    return metric.compute(predictions=predictions, references=labels)

# 还要在TrainingArguments中添加新的参数:
training_args = TrainingArguments("test-trainer", evaluation_strategy="epoch")
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值