HuggingFaceTransformers是一个自然语言处理(Natural Language Processing,NLP)的开源库,旨在让用户能够轻松地使用最新的机器学习模型来进行文本分类、问题回答、文本生成、人机对话等任务。该库集成了众多优秀的预训练模型(如BERT、GPT-2等)和用于快速训练和评估这些模型的工具。本文将为大家介绍HuggingFaceTransformers的使用流程和两个基础示例。
安装HuggingFaceTransformers
在使用HuggingFaceTransformers之前,需先安装相关库:
pip install transformers
加载预训练模型
在HuggingFaceTransformers中,我们通过from_pretrained()
方法来加载预训练模型。在方法中,我们需要指定使用的模型名称和文件路径。以BERT模型为例,我们来给大家演示如何加载:
from transformers import BertModel, BertTokenizer
# 加载预训练的Bert模型和分词器
model_name = 'bert-base-chinese'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertModel.from_pretrained(model_name)
示例1:中文情感分析
下面我们通过一个中文情感分析的例子来展示HuggingFaceTransformers的使用过程。
数据准备和处理
我们从网上下载了一个中文情感分析的数据集,包含了1500条文本和对应的情感标签(分别为0表示消极、1表示中性、2表示积极)。代码如下:
import pandas as pd
df = pd.read_csv('data/sentiment.csv')
sentences = df['sentence'].values
labels = df['label'].values
接着,我们需要使用BertTokenizer对原始文本进行分词,得到模型需要的输入格式。代码如下:
input_ids = []
attention_masks = []
# 对每个句子通过BertTokenizer进行分词,并获取特殊token
for sentence in sentences:
encoded_dict = tokenizer.encode_plus(
sentence, # sentence to encode.
add_special_tokens = True, # 增加特殊token
max_length = 64, # 截断或padding每个sequence的长度
truncation=True, # 是否截断
pad_to_max_length = True, # 是否padding
return_attention_mask = True, # 增加attention mask
return_tensors = 'pt', # 返回pytorch tensors格式
)
# 将encoded representation添加到列表中
input_ids.append(encoded_dict['input_ids'])
attention_masks.append(encoded_dict['attention_mask'])
最后,我们将输入数据划分为训练集和测试集,并定义一些超参数。代码如下:
from torch.utils.data import TensorDataset, random_split
from torch.utils.data import DataLoader, RandomSampler, SequentialSampler
# 导入pytorch库
import torch
# 定义一些超参数
batch_size = 32
test_size = 0.3
random_seed = 2021
# 将数据转化为TensorDataset格式
dataset = TensorDataset(torch.cat(input_ids, dim=0),
torch.cat(attention_masks, dim=0),
torch.tensor(labels))
# 划分数据集
train_size = int((1-test_size)*len(dataset))
test_size = len(dataset) - train_size
train_dataset, test_dataset = random_split(dataset, [train_size, test_size])
# 定义sampler和dataloader
train_sampler = RandomSampler(train_dataset)
train_dataloader = DataLoader(train_dataset,
sampler=train_sampler, batch_size=batch_size)
test_sampler = SequentialSampler(test_dataset)
test_dataloader = DataLoader(test_dataset,
sampler=test_sampler, batch_size=batch_size)
模型微调和评估
我们使用了一个分类任务的版本的预训练Bert模型,将其微调用于中文情感分析任务。在训练过程中,我们使用了Adam优化器、交叉熵损失函数、accuracy指标,并定义了一个训练函数。代码如下:
from transformers import AdamW
from tqdm.notebook import tqdm
import numpy as np
# 将模型放到GPU上
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
# 定义优化器和损失函数、评估指标
optimizer = AdamW(model.parameters(), lr=2e-5, eps=1e-8)
loss_func = torch.nn.CrossEntropyLoss()
metric_func = lambda y_pred, y_true: np.sum(np.argmax(y_pred, axis=1) == y_true)
num_epochs = 4
def train(model, optimizer, train_loader, loss_func, metric_func):
model.train()
train_loss = 0.0
train_metric = 0.0
for batch_data in tqdm(train_loader):
# 获取数据
batch_input_ids, batch_attention_mask, batch_label = batch_data
batch_input_ids.to(device)
batch_attention_mask.to(device)
batch_label.to(device)
# 清空历史梯度
optimizer.zero_grad()
# 前向计算
model_output = model(input_ids=batch_input_ids,
attention_mask=batch_attention_mask)
logits = model_output.last_hidden_state[:, 0, :]
# 计算损失值
loss = loss_func(logits, batch_label)
# 反向传播
loss.backward()
# 更新参数
optimizer.step()
# 计算评估指标
train_loss += loss.item() * batch_label.size(0)
train_metric += metric_func(logits.cpu().detach().numpy(),
batch_label.cpu().detach().numpy())
# 计算平均损失值和评估指标
train_loss = train_loss / len(train_loader.dataset)
train_metric = train_metric / len(train_loader.dataset)
return train_loss, train_metric
# 微调模型
for epoch in range(num_epochs):
train_loss, train_metric = train(model, optimizer, train_dataloader, loss_func, metric_func)
print('Epoch {}/{}:'.format(epoch+1, num_epochs))
print('\tTrain - Loss: {:.4f}, Accuracy: {:.4%}'.format(train_loss, train_metric))
经过4个epoch迭代,训练集上的Loss为0.3941,Accuracy为89.05%。
最后,我们使用测试集来对模型进行评估。代码如下:
def evaluate(model, test_loader, loss_func, metric_func):
model.eval()
loss = 0.0
metric = 0.0
for batch_data in tqdm(test_loader):
# 获取数据
batch_input_ids, batch_attention_mask, batch_label = batch_data
batch_input_ids.to(device)
batch_attention_mask.to(device)
batch_label.to(device)
# 前向计算
model_output = model(input_ids=batch_input_ids,
attention_mask=batch_attention_mask)
logits = model_output.last_hidden_state[:, 0, :]
# 计算损失值
loss += loss_func(logits, batch_label).item() * batch_label.size(0)
# 计算评估指标
metric += metric_func(logits.cpu().detach().numpy(),
batch_label.cpu().detach().numpy())
# 计算平均损失值和评估指标
loss = loss / len(test_loader.dataset)
metric = metric / len(test_loader.dataset)
return loss, metric
test_loss, test_metric = evaluate(model, test_dataloader, loss_func=loss_func, metric_func=metric_func)
print('Test - Loss: {:.4f}, Accuracy: {:.4%}'.format(test_loss, test_metric))
在测试集上,模型的Loss为0.4759,Accuracy为81.33%。
示例2:文本生成任务
下面我们将演示如何使用HuggingFaceTransformers来实现文本生成任务。我们以GPT-2模型为例。
加载和准备模型和输入
首先,我们需要下载并加载模型以及分词器:
from transformers import GPT2Tokenizer, GPT2LMHeadModel
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')
接下来,我们为模型准备输入数据。我们可以用分词器将原始文本分成tokens,然后将tokens编码成整数格式:
input_ids = tokenizer.encode('I love writing for Hugging Face')
# 将input充当模型的输入数据,包裹在tensor中
input = torch.tensor(input_ids).unsqueeze(0)
预测和生成文本
接下来我们可以对模型做出预测,并生成一些文本。我们可以调用模型的generate()
函数来生成文本。代码如下:
import random
import torch
# 将模型放到GPU上
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
# 设置生成文本的序列长度
length = 50
# 切换到生成模式
model.eval()
# 使用贪婪算法生成文本
generated_ids = model.generate(input_ids=input,
max_length=length,
repetition_penalty=1.5,
fluency_penalty=1.5,
temperature=0.7,
no_repeat_ngram_size=2)
# 解码生成的ids,输出文本
print(tokenizer.decode(generated_ids[0], skip_special_tokens=True))
在上述代码中,我们为GPT-2模型设置了50个tokens的序列长度,并设置了几个文本生成的超参数:temperature
: 控制生成文本的多样性;repetition_penalty
: 控制生成文本的重复程度,值越大,重复的可能性越低;fluency_penalty
: 控制生成文本的连贯性和流畅度,值越大,结果越流畅。最后,我们使用了贪婪算法(generate()
函数)生成文本。
除了贪婪生成,HuggingFaceTransformers还提供了Beam Search、Top-K Sampling、Top-P Sampling等多种生成文本的策略,具体使用请参考官方文档。
以上是HuggingFaceTransformers的使用介绍和两个基础示例。务必注意选择合适的模型和超参数,才能取得好的结果。