将用于生成两个预训练任务的训练样本的辅助函数和用于填充输入的辅助函数放在一起,定义以下类为用于预训练BERT的-2数据集 。通过实现 函数,可以任意访问-2语料库的一对句子生成的预训练样本(遮蔽语言模型和下一句预测)样本 。
class _WikiTextDataset(torch.utils.data.Dataset):def __init__(self, paragraphs, max_len):# 输入paragraphs二维列表,paragraphs[i]表示段落的句子字符串列表;# 输出paragraphs三维列表,paragraphs[i]是代表段落的句子列表,第三维是每个句子的词元列表paragraphs = [d2l.tokenize(paragraph, token='word') for paragraph in paragraphs]# sentences二维列表,sentences[i]表示一个token化的句子列表sentences = [sentence for paragraph in paragraphsfor sentence in paragraph]self.vocab = d2l.Vocab(sentences, min_freq=5, reserved_tokens=['', '
下载并生成-2数据集,并从中生成预训练样本 。
def load_data_wiki(batch_size, max_len):"""加载WikiText-2数据集"""data_dir = d2l.download_extract('wikitext-2', 'wikitext-2')paragraphs = _read_wiki(data_dir)train_set = _WikiTextDataset(paragraphs, max_len)train_iter = torch.utils.data.DataLoader(train_set, batch_size, shuffle=True)return train_iter, train_set.vocab
批量大小为512,输入序列的最大长度为64,打印出小批量的BERT预训练样本的形状 。在每个BERT输入序列中,为遮蔽语言模型任务预测 10 10 10( 64 × 0.15 64 \times 0.15 64×0.15)个位置 。
batch_size, max_len = 512, 64train_iter, vocab = load_data_wiki(batch_size, max_len)for (tokens_X, segments_X, valid_lens_x, pred_positions_X, mlm_weights_X,mlm_Y, nsp_y) in train_iter:print(tokens_X.shape, segments_X.shape, valid_lens_x.shape,pred_positions_X.shape, mlm_weights_X.shape, mlm_Y.shape, nsp_y.shape)break
torch.Size([512, 64]) torch.Size([512, 64]) torch.Size([512]) torch.Size([512, 10]) torch.Size([512, 10]) torch.Size([512, 10]) torch.Size([512])
三、预训练BERT 1.预训练
BERT预训练的最终损失是遮蔽语言模型损失和下一句预测损失的和 。
def _get_batch_loss_bert(net, loss, vocab_size, tokens_X, segments_X, valid_lens_x,pred_positions_X, mlm_weights_X, mlm_Y, nsp_y):# 前向传播_, mlm_Y_hat, nsp_Y_hat = net(tokens_X, segments_X, valid_lens_x.reshape(-1),pred_positions_X)# 计算遮蔽语言模型损失mlm_l = loss(mlm_Y_hat.reshape(-1, vocab_size), mlm_Y.reshape(-1)) * mlm_weights_X.reshape(-1, 1)mlm_l = mlm_l.sum() / (mlm_weights_X.sum() + 1e-8)# 计算下一句子预测任务的损失nsp_l = loss(nsp_Y_hat, nsp_y)l = mlm_l + nsp_lreturn mlm_l, nsp_l, l
函数定义了在-2()数据集上预训练BERT(net)的过程 。训练BERT可能需要很长时间 。函数的输入指定了训练的迭代步数,而不是像函数那样指定训练的轮数 。
- 一、主流的固态硬盘
- 企业如何解决多头领导问题,为什么企业多头领导、均不负责
- 企业微信是干什么用的,微信的二维码是干什么用的
- 汉景帝的一夜风流换来了汉朝的二百年天下
- 中国男篮十大帅哥 中国之最帅哥
- 2023中国十大最受欢迎炸鸡汉堡品牌:塔斯汀第三、华莱士第四 中国之最受
- 追风赏月、静心养神、休闲避暑,来天然氧吧大吸一口清新空气~ 威远吉尼斯记录
- NBA新赛季奢侈税排行:勇士1.8亿财大气粗,篮网仅第二,湖人第六 ba奢侈税历史之最
- 中国历史名人勤学、励志、育人、诚信、齐家、治国等100个小故事 历史之最作文素材初中
- 中华第一大姓,从黄帝时期到明清,58位王姓历史名人 历史王姓名人之最