2026年AI GEO工具推荐:生成引擎优化从业者实用工具选型完整指南
2026/8/4 19:51:40
本文将详细解析一个完整的中文BERT情感分类模型训练流程,涵盖数据预处理、模型配置、训练循环等关键环节。
先上代码:
# 模型训练 train.pyimporttorchfromMyDataimportMyDataset# 自定义数据集类fromtorch.utils.dataimportDataLoader# 数据加载器fromnetimportModel# 自定义模型类fromtransformersimportBertTokenizer# BERT分词器fromtorch.optimimportAdamW# 优化器# 定义设备信息# 关键点1:设备选择 - 优先使用GPU加速训练DEVICE=torch.device("cuda"iftorch.cuda.is_available()else"cpu")# 定义训练的轮次(将整个数据集训练完一次为一轮)# 关键点2:训练轮次 - 需要平衡过拟合和欠拟合EPOCH=6# 加载字典和分词器# 关键点3:预训练模型加载 - 使用中文BERT基础版# 注意:路径指向本地下载的BERT模型token=BertTokenizer.from_pretrained(r"D:\develop\pypro\LLM\LLMPro\01-大模型应用基础\model\google-bert\bert-base-chinese\models--bert-base-chinese\snapshots\8f23c25b06e129b6c986331a13d8d025a92cf0ea")# 将传入的字符串进行编码defcollate_fn(data):""" 关键点4:数据预处理函数 功能:将原始文本批量转换为BERT模型需要的输入格式 参数:data - 批量数据,每个元素是(text, label)元组 处理流程: 1. 分离文本和标签 2. 对文本进行BERT编码 3. 转换为PyTorch张量 """# 分离文本和标签sents=[i[0]foriindata]# 提取所有文本label=[i[1]foriindata]# 提取所有标签# 关键点5:批量编码data=token.batch_encode_plus(batch_text_or_text_pairs=sents,# 要编码的文本列表# 关键点6:截断处理# 当句子长度大于max_length时,截断超出部分truncation=True,max_length=512,# BERT最大序列长度# 关键点7:填充处理# 将短句子填充到max_length,统一批次内张量形状padding="max_length",# 关键点8:返回格式# "pt"表示返回PyTorch张量,其他选项:tf(TensorFlow), np(numpy)return_tensors="pt",# 返回序列长度(可选)return_length=True)# 提取编码后的各个组件input_ids=data["input_ids"]# 词汇ID序列attention_mask=data["attention_mask"]# 注意力掩码(区分真实token和填充)token_type_ids=data["token_type_ids"]# 句子类型ID(用于句子对任务)# 将标签列表转换为长整型张量label=torch.LongTensor(label)returninput_ids,attention_mask,token_type_ids,label# 创建数据集# 关键点9:数据集实例化train_dataset=MyDataset("train")# 加载训练集# 关键点10:数据加载器配置train_loader=DataLoader(dataset=train_dataset,# 使用的数据集# 关键点11:批次大小# 批次大小影响训练稳定性和内存使用batch_size=90,# 关键点12:数据打乱# 打乱数据有助于模型学习更通用的特征,防止顺序偏差shuffle=True,# 关键点13:丢弃最后不完整的批次# 保证每个批次形状一致,便于矩阵运算drop_last=True,# 关键点14:自定义批处理函数# 对每个批次的数据进行预处理collate_fn=collate_fn)if__name__=='__main__':# 开始训练print(f"使用设备:{DEVICE}")# 关键点15:模型实例化并转移到设备model=Model().to(DEVICE)# 关键点16:优化器选择# AdamW是Adam的改进版,加入了权重衰减optimizer=AdamW(model.parameters())# 关键点17:损失函数选择# CrossEntropyLoss适用于多分类任务loss_func=torch.nn.CrossEntropyLoss()# 关键点18:训练循环forepochinrange(EPOCH):print(f"\n=== 开始第{epoch+1}/{EPOCH}轮训练 ===")# 关键点19:批次循环fori,(input_ids,attention_mask,token_type_ids,label)inenumerate(train_loader):# 关键点20:数据转移到设备# 将数据从CPU移动到GPU(如果可用)input_ids,attention_mask,token_type_ids,label=(input_ids.to(DEVICE),attention_mask.to(DEVICE),token_type_ids.to(DEVICE),label.to(DEVICE))# 关键点21:前向传播# 将数据输入模型,得到预测输出out=model(input_ids,attention_mask,token_type_ids)# 关键点22:计算损失# 比较模型预测和真实标签的差异loss=loss_func(out,label)# 关键点23:反向传播# 1. 清空梯度 - 防止梯度累加optimizer.zero_grad()# 2. 计算梯度 - 反向传播loss.backward()# 3. 更新参数 - 根据梯度调整模型参数optimizer.step()# 关键点24:训练监控# 每隔5个批次输出训练信息ifi%5==0:# 将预测概率转换为类别out_label=out.argmax(dim=1)# 计算准确率acc=(out_label==label).sum().item()/len(label)print(f"轮次:{epoch}, 批次:{i}, 损失:{loss.item():.4f}, 准确率:{acc:.4f}")# 关键点25:模型保存# 每训练完一轮,保存一次参数torch.save(model.state_dict(),f"params/{epoch}_bert.pth")print(f"轮次{epoch}完成,参数保存成功!")# 定义设备信息DEVICE=torch.device("cuda"iftorch.cuda.is_available()else"cpu")关键分析:
EPOCH=6关键分析:
token=BertTokenizer.from_pretrained("bert-base-chinese路径")技术要点:
bert-base-chinese专门针对中文优化defcollate_fn(data):sents=[i[0]foriindata]label=[i[1]foriindata]data=token.batch_encode_plus(batch_text_or_text_pairs=sents,truncation=True,# 截断长文本max_length=512,# BERT最大长度限制padding="max_length",# 统一序列长度return_tensors="pt",# 返回PyTorch张量return_length=True# 返回实际长度)关键技术细节:
1. 序列长度处理
max_length=512,truncation=True2. 填充策略
padding="max_length"attention_mask区分真实token和填充3. 输出张量类型
return_tensors="pt"input_ids=data["input_ids"]# 词ID序列attention_mask=data["attention_mask"]# 注意力掩码token_type_ids=data["token_type_ids"]# 句子类型| 张量类型 | 作用 | 示例 |
|---|---|---|
input_ids | 文本的数字表示 | [101, 3928, 671, 102] |
attention_mask | 区分真实token和填充 | [1, 1, 1, 0, 0] |
token_type_ids | 区分句子A和B | [0, 0, 0, 1, 1] |
train_loader=DataLoader(dataset=train_dataset,batch_size=90,# 批次大小shuffle=True,# 随机打乱drop_last=True,# 丢弃不完整批次collate_fn=collate_fn# 自定义批处理)关键参数分析:
1. 批次大小选择
batch_size=902. 数据随机化
shuffle=True3. 批次完整性
drop_last=True# 模型实例化model=Model().to(DEVICE)# 优化器选择optimizer=AdamW(model.parameters())# 损失函数loss_func=torch.nn.CrossEntropyLoss()关键技术选择:
AdamW优化器优势:
forepochinrange(EPOCH):# 外层:轮次循环fori,batchinenumerate(train_loader):# 内层:批次循环# 1. 数据准备batch=[tensor.to(DEVICE)fortensorinbatch]# 2. 前向传播out=model(*batch[:-1])# 3. 损失计算loss=loss_func(out,batch[-1])# 4. 反向传播optimizer.zero_grad()loss.backward()optimizer.step()步骤1:梯度清零
optimizer.zero_grad()步骤2:反向传播
loss.backward().grad属性中步骤3:参数更新
optimizer.step()ifi%5==0:# 预测类别predictions=out.argmax(dim=1)# 计算准确率correct=(predictions==label).sum().item()total=len(label)acc=correct/totalprint(f"epoch:{epoch}, batch:{i}, loss:{loss.item():.4f}, acc:{acc:.4f}")监控指标说明:
torch.save(model.state_dict(),f"params/{epoch}_bert.pth")保存策略分析:
本文详细解析了一个完整的BERT模型训练流程,涵盖以下关键环节:
通过这个流程,可以训练一个中文情感分类的BERT模型。实际应用中,还需要考虑验证集评估、超参数调优、模型部署等更多环节。
核心要点总结:
这个训练框架不仅适用于情感分析任务,经过适当修改,也可以应用于其他文本分类、序列标注等自然语言处理任务。