尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
BERT-base/Large 预训练实战:WikiText-2 数据集 50 步 MLM/NSP 双任务 Loss 收敛曲线
BERT预训练实战从零构建WikiText-2双任务模型1. 环境准备与数据加载在开始BERT预训练之前我们需要搭建合适的开发环境并准备数据集。本实验使用PyTorch框架和WikiText-2数据集这是一个包含维基百科文章的经典语言建模数据集大小适中适合教学演示。首先安装必要的Python包pip install torch transformers datasets matplotlib加载WikiText-2数据集并进行预处理from datasets import load_dataset dataset load_dataset(wikitext, wikitext-2-raw-v1) print(f数据集结构: {dataset}) # 过滤空行和标题行 train_texts [text for text in dataset[train][text] if len(text) 0 and not text.startswith( )]2. 构建BERT模型架构我们将实现一个简化版的BERT模型包含以下核心组件import torch import torch.nn as nn from transformers import BertConfig class BertForPretraining(nn.Module): def __init__(self, config): super().__init__() self.bert BertModel(config) self.mlm_head nn.Linear(config.hidden_size, config.vocab_size) self.nsp_head nn.Linear(config.hidden_size, 2) def forward(self, input_ids, attention_mask, token_type_ids): outputs self.bert(input_ids, attention_mask, token_type_ids) sequence_output outputs.last_hidden_state pooled_output outputs.pooler_output mlm_logits self.mlm_head(sequence_output) nsp_logits self.nsp_head(pooled_output) return mlm_logits, nsp_logits配置模型参数简化版config BertConfig( vocab_size30522, hidden_size128, # 原始BERT为768 num_hidden_layers2, # 原始BERT为12 num_attention_heads2, intermediate_size256, max_position_embeddings512 ) model BertForPretraining(config)3. 数据预处理与特征工程BERT预训练需要特殊的数据处理流程包括WordPiece分词和双任务标签生成。3.1 构建词汇表与分词器from tokenizers import Tokenizer, models, trainers tokenizer Tokenizer(models.WordPiece(unk_token[UNK])) trainer trainers.WordPieceTrainer( special_tokens[[PAD], [UNK], [CLS], [SEP], [MASK]], vocab_sizeconfig.vocab_size ) tokenizer.train_from_iterator(train_texts, trainer)3.2 生成训练样本import random def create_mlm_sample(text): tokens tokenizer.encode(text).ids # 随机mask 15%的token masked_indices random.sample(range(len(tokens)), kint(0.15*len(tokens))) labels [-100] * len(tokens) for idx in masked_indices: # 80%概率替换为[MASK] if random.random() 0.8: masked_token tokenizer.token_to_id([MASK]) # 10%概率替换为随机token elif random.random() 0.5: masked_token random.randint(0, config.vocab_size-1) # 10%概率保持不变 else: masked_token tokens[idx] labels[idx] tokens[idx] tokens[idx] masked_token return tokens, labels def create_nsp_sample(text_a, text_b): # 50%概率选择连续句子或随机句子 if random.random() 0.5: text_b random.choice(train_texts) label 0 # NotNext else: label 1 # IsNext return text_a, text_b, label4. 训练过程实现4.1 损失函数定义BERT预训练包含两个任务的联合损失criterion_mlm nn.CrossEntropyLoss(ignore_index-100) criterion_nsp nn.CrossEntropyLoss() def compute_loss(mlm_logits, nsp_logits, mlm_labels, nsp_labels): mlm_loss criterion_mlm( mlm_logits.view(-1, config.vocab_size), mlm_labels.view(-1) ) nsp_loss criterion_nsp(nsp_logits, nsp_labels) return mlm_loss nsp_loss4.2 训练循环from torch.utils.data import DataLoader from tqdm import tqdm optimizer torch.optim.AdamW(model.parameters(), lr5e-5) for epoch in range(5): model.train() total_loss 0 for batch in tqdm(train_loader): optimizer.zero_grad() input_ids batch[input_ids].to(device) attention_mask batch[attention_mask].to(device) token_type_ids batch[token_type_ids].to(device) mlm_labels batch[mlm_labels].to(device) nsp_labels batch[nsp_labels].to(device) mlm_logits, nsp_logits model(input_ids, attention_mask, token_type_ids) loss compute_loss(mlm_logits, nsp_logits, mlm_labels, nsp_labels) loss.backward() optimizer.step() total_loss loss.item() print(fEpoch {epoch1} | Avg Loss: {total_loss/len(train_loader):.4f})5. 损失曲线分析与调优训练过程中记录两种任务的损失值import matplotlib.pyplot as plt plt.figure(figsize(10, 5)) plt.plot(mlm_losses, labelMLM Loss) plt.plot(nsp_losses, labelNSP Loss) plt.xlabel(Steps) plt.ylabel(Loss) plt.title(BERT Pretraining Loss Curves) plt.legend() plt.grid() plt.show()典型损失曲线特征分析阶段MLM Loss特征NSP Loss特征可能原因初期快速下降波动较大模型学习基础表征中期平稳下降逐渐收敛模型捕获语言规律后期小幅波动基本稳定接近局部最优解关键调优参数建议# 推荐参数配置 optimal_config { batch_size: 32, # 平衡显存和稳定性 max_seq_length: 128, # 短文本效率更高 learning_rate: 3e-5, # BERT经典初始学习率 warmup_steps: 1000, # 学习率预热 weight_decay: 0.01 # 防止过拟合 }6. 模型验证与应用6.1 掩码语言预测示例def predict_masked_token(text, mask_position): inputs tokenizer(text, return_tensorspt) inputs.input_ids[0, mask_position] tokenizer.mask_token_id with torch.no_grad(): logits model(**inputs).logits predicted_token_id logits[0, mask_position].argmax().item() return tokenizer.decode(predicted_token_id) text The capital of France is [MASK]. print(predict_masked_token(text, mask_position5)) # 输出可能: paris6.2 下一句关系判断def predict_next_sentence(sentence_a, sentence_b): inputs tokenizer(sentence_a, sentence_b, return_tensorspt) with torch.no_grad(): outputs model(**inputs) prob torch.softmax(outputs.logits, dim-1) return prob[0, 1].item() # IsNext的概率 sentence_a The weather is nice today. sentence_b Lets go to the park. print(fIsNext概率: {predict_next_sentence(sentence_a, sentence_b):.2f}) # 输出可能: 0.877. 进阶优化技巧7.1 动态掩码策略原始BERT在预处理时静态mask tokens现代实现采用动态maskingdef dynamic_masking(tokens): # 每个epoch重新生成mask模式 masking_strategy random.choice([ token_level, span_level, whole_word ]) # 实现不同的mask模式... return masked_tokens7.2 梯度累积在显存有限时使用梯度累积模拟更大batch sizeaccumulation_steps 4 for i, batch in enumerate(train_loader): loss compute_loss(batch) loss loss / accumulation_steps loss.backward() if (i1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad()7.3 混合精度训练使用FP16加速训练from torch.cuda.amp import GradScaler, autocast scaler GradScaler() for batch in train_loader: optimizer.zero_grad() with autocast(): loss compute_loss(batch) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update()8. 实际应用建议资源有限时减小hidden_size至256或层数至4仍能保持不错效果领域适应在专业领域语料上继续预训练Domain-Adaptive Pretraining损失震荡当NSP损失波动较大时可尝试降低学习率或增大batch size早停策略当验证集loss连续3个epoch不下降时停止训练完整训练50步后的典型损失值参考任务初始Loss最终Loss下降幅度MLM8.52.175%NSP0.690.3549%通过本实战教程我们实现了BERT核心预训练流程观察到双任务损失的有效收敛。虽然简化版模型参数较少但完整保留了BERT的核心训练机制为后续微调任务奠定了良好基础。
RELATED

相关推荐

CLI-Anything:让任意桌面软件秒变AI可操控的API终端

CLI-Anything:让任意桌面软件秒变AI可操控的API终端

1. 这不是又一个“AI调用封装”,而是一次命令行交互范式的底层重定义你有没有遇到过这种场景:想让AI自动帮你批量重命名几百个文件,却发现市面上所有Agent工具都卡在“无法直接操作本地文件管理器”这一步;想让大模型自动部署一个…

📅 2026/11/9 7:55:58
3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失

3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失

3步搞定微信聊天记录永久保存:WeChatMsg让珍贵对话永不消失 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/…

📅 2026/11/9 7:55:58
Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧

Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧

Python scipy.optimize.curve_fit 实战:3种常见非线性模型拟合与参数优化技巧在数据分析与科学计算领域,非线性拟合是揭示复杂数据内在规律的关键技术。当简单的线性模型无法捕捉数据中的曲率变化时,我们需要转向更强大的工具——scipy.optim…

📅 2026/10/1 13:17:10
MORE NEWS

更多资讯

📰

电工证过期时间你知道吗?内部消息告诉你怎么转异地

电工证过期时间你知道吗?内部消息告诉你怎么转异地 你现在急需特种作业证才能上岗找工作,电工证过期时间成了你最关心的问题之一。很多学员在安阳培训后,发现证书有效期只有6年,一旦过期,不仅影响工作,还可能面临重新考试的麻烦。更让人头疼的是,证书…

📰

邳州在哪审电工证多少钱?工地太忙根本没时间复习考试

邳州在哪审电工证多少钱?工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,这是大多数电工、焊工、高处作业人员的真实写照。尤其是像邳州这样的地区,特种作业操作证的审核和复审流程相对复杂,很多人因为时间紧张,往往在关键时刻才发现自己证照过…

📰

义乌哪里换电工证在哪考 工地太忙根本没时间复习考试

义乌哪里换电工证在哪考 工地太忙根本没时间复习考试 工地太忙根本没时间复习考试,你是不是也经常被这个问题困扰?特别是像低压电工证、高压电工证这类特种作业操作证, 换证…

📰

在校生电工证考试报名能跨省转移吗?考前押题资料怎么获取

在校生电工证考试报名能跨省转移吗?考前押题资料怎么获取 之前考的证在外省能不能转过来?这几乎是所有在外省打工或读书的小伙伴最关心的问题。尤其是像你这样在濮阳读书的在校生,如果之前在别的地方考了电工证,想要在本地继续使用,肯定得先搞清楚转移流…

📰

初级电工证报名哪里好网上查询实操考试怎么准备

初级电工证报名哪里好网上查询实操考试怎么准备 实操考试心里没底怕挂科,这是很多准备考初级电工证的学员最真实的状态。尤其是对于安阳公路工程从业者来说,电工证不仅是上岗的门槛,更关系到日常作业的安全责任。初级电工证报名哪里好?网上查询信息不统一…

📰

南宁那里办电工证怎么考怎么考过 郑州报考避坑指南

南宁那里办电工证怎么考怎么考过 郑州报考避坑指南 证书过期了不知道怎么复审延期?别慌,南宁那里的电工证办理流程其实不难,关键是你得知道怎么操作。今天我们就来聊聊南宁地区电工证的报考、复审、薪资前景以及避坑指南,尤其是针对郑州地区报考者的一些…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬