赞
踩
BERT(Bidirectional Encoder Representations from Transformers)作为自然语言处理领域的里程碑,通过双向Transformer编码器捕捉文本的深层语义,革新了下游NLP任务的处理方式。本文旨在深入探讨BERT模型的预训练与微调流程,通过详尽的代码示例,引导读者从理论到实践,掌握这一强大模型的使用精髓。
BERT基于Transformer架构,引入了两个关键创新:双向上下文理解和掩码语言模型(Masked Language Model, MLM)。通过在训练过程中随机掩盖部分输入词并预测这些词,BERT学会了在理解整个句子的背景下推断每个词的含义。接下来,我们将分步解析BERT的预训练和微调流程。
BERT的预训练主要包含两个任务:掩码语言模型(MLM)和下一句预测(Next Sentence Prediction, NSP)。虽然预训练通常在大规模语料上完成,且资源消耗较大,但这里我们仅概述其原理及代码逻辑框架。
from transformers import BertForMaskedLM, BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForMaskedLM.from_pretrained('bert-base-uncased')
# 假设输入句子
text = "The capital of France is [MASK]."
indexed_tokens = tokenizer.encode(text, add_special_tokens=True)
tokens_tensor = torch.tensor([indexed_tokens])
# 对输入进行掩码处理
mask_token_index = torch.where(tokens_tensor == tokenizer.mask_token_id)[1]
token_logits = model(tokens_tensor).logits
# 获取掩码位置的预测概率分布
mask_token_logits = token_logits[0, mask_token_index, :]
top_5_tokens = torch.topk(mask_token_logits, 5, dim=1).indices[0].tolist()
top_5_words = [tokenizer.decode([predicted_token]) for predicted_token in top_5_tokens]
print(top_5_words)
NSP任务的目的是判断两个句子是否相邻,尽管在实践中NSP任务的重要性有所下降,但了解其原理仍具有教育意义。此处略去具体代码以聚焦于更广泛应用的MLM任务。
微调是指在特定任务的数据集上对预训练好的BERT模型进行进一步训练,使其适应特定任务的需求。以下通过情感分析任务来演示微调过程。
from transformers import BertTokenizer, BertForSequenceClassification
from torch.utils.data import Dataset, DataLoader
import torch
# 使用Hugging Face的BertTokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', num_labels=2) # 假设二分类任务
class SentimentDataset(Dataset):
def __init__(self, texts, labels, tokenizer, max_len):
self.texts = texts
self.labels = labels
self.tokenizer = tokenizer
self.max_len = max_len
def __len__(self):
return len(self.texts)
def __getitem__(self, item):
text = str(self.texts[item])
label = self.labels[item]
encoding = self.tokenizer.encode_plus(
text,
add_special_tokens=True,
max_length=self.max_len,
return_token_type_ids=False,
pad_to_max_length=True,
return_attention_mask=True,
return_tensors='pt',
)
return {
'text': text,
'input_ids': encoding['input_ids'].flatten(),
'attention_mask': encoding['attention_mask'].flatten(),
'labels': torch.tensor(label, dtype=torch.long)
}
# 假设你已经有了texts和labels数据
train_data = SentimentDataset(texts, labels, tokenizer, max_len=128)
train_loader = DataLoader(train_data, batch_size=16, shuffle=True)
from transformers import AdamW, get_linear_schedule_with_warmup
import torch.optim as optim
import torch.nn.functional as F
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False)
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=len(train_loader) * epochs)
for epoch in range(epochs):
for batch in train_loader:
input_ids = batch['input_ids'].to(device)
attention_mask = batch['attention_mask'].to(device)
labels = batch['labels'].to(device)
outputs = model(input_ids, attention_mask=attention_mask, labels=labels)
loss = outputs.loss
loss.backward()
optimizer.step()
scheduler.step()
model.zero_grad()
BERT模型的预训练与微调流程展示了如何从大规模无监督数据中学习通用语言表示,再迁移到特定任务上,极大地提高了NLP任务的性能。通过本文的实操指导,希望读者不仅能够掌握BERT模型的应用技巧,更能深刻理解其背后的设计理念。随着NLP技术的不断进步,未来BERT及其变种模型将继续在对话系统、文本生成、情感分析等多个领域发挥重要作用,推动人工智能向更加智能化的方向发展。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。