大模型工程师学习日记(十五):Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析)

news2025/3/10 9:59:23

1. datasets 库核心方法

1.1. 列出数据集 使用 d atasets 库,你可以轻松列出所有 Hugging Face 平台上的数据集:

from datasets import list_datasets
 # 列出所有数据集
all_datasets = list_datasets()
 print(all_datasets)

1.2. 加载数据集 你可以通过 load_dataset 方法加载任何数据集:

from datasets import load_dataset
 # 加载GLUE数据集
dataset = load_dataset("glue", "mrpc")
 print(dataset)

1.3. 加载磁盘数据 你可以加载本地磁盘上的数据:

from datasets import load_from_disk
 # 从本地磁盘加载数据集
dataset = load_from_disk("./my_dataset")
 print(dataset)

2. 分词工具与文字编码 2.1. 加载字典和分词工具 你可以使用 AutoTokenizer 自动加载分词工具:

from transformers import AutoTokenizer
 # 加载中文BERT模型的分词器
tokenizer = AutoTokenizer.from_pretrained("bert-base-chinese")

2.1. 批量编码句子 使用分词器,你可以批量对文本进行编码:

# 批量编码句子
sentences = ["我爱自然语言处理", "Hugging Face 很强大"]
 encoded_inputs = tokenizer(sentences, padding=True, truncation=True, 
return_tensors="pt")
 print(encoded_inputs)

3. 模型微调的基本概念与流程

微调是指在预训练模型的基础上,通过进一步的训练来适应特定的下游任务。BERT 模型通过预训练来 学习语言的通用模式,然后通过微调来适应特定任务,如情感分析、命名实体识别等。微调过程中,通 常冻结 BERT 的预训练层,只训练与下游任务相关的层。本课件将介绍如何使用 BERT 模型进行情感分 析任务的微调训练。

4. 加载数据集 情感分析任务的数据通常包括文本及其对应的情感标签。使用 Hugging Face 的 datasets 库可以轻松地 加载和处理数据集

from datasets import load_dataset
 # 加载数据集
dataset = load_dataset('csv', data_files="data/ChnSentiCorp.csv")
 # 查看数据集信息
print(dataset)

4.1 数据集格式

Hugging Face 的 datasets 库支持多种数据集格式,如 CSV、JSON、TFRecord 等。在本案例中,使用 CSV 格式,CSV 文件应包含两列:一列是文本数据,另一列是情感标签。

4.2 数据集信息

加载数据集后,可以查看数据集的基本信息,如数据集大小、字段名称等。这有助于我们了解数据的分 布情况,并在后续步骤中进行适当的处理。

5. 制作 Dataset 加载数据集后,需要对其进行处理以适应模型的输入格式。这包括数据清洗、格式转换等操作。

加载数据集后,需要对其进行处理以适应模型的输入格式。这包括数据清洗、格式转换等操作。
from datasets import Dataset
 # 制作 Dataset
 dataset = Dataset.from_dict({
 'text': ['位置尚可,但距离海边的位置比预期的要差的多', '5月8日付款成功,当当网显示5月10
日发货,可是至今还没看到货物,也没收到任何通知,简不知怎么说好!!!', '整体来说,本书还是不错
的。至少在书中描述了许多现实中存在的司法系统方面的问题,这是值得每个法律工作者去思考的。尤其是让
那些涉世不深的想加入到律师队伍中的年青人,看到了社会特别是中国司法界真实的一面。缺点是:书中引用
了大量的法律条文和司法解释,对于已经是律师或有一定工作经验的法律工作者来说有点多余,而且所占的篇
幅不少,有凑字数的嫌疑。整体来说还是不错的。不要对一本书提太高的要求。'],
 'label': [0, 1, 1]  # 0 表示负向评价,1 表示正向评价
})
 # 查看数据集信息
print(dataset)

5.1 数据集字段

在制作 Dataset 时,需定义数据集的字段。在本案例中,定义了两个字段: text (文本)和 label (情感标签)。每个字段都需要与模型的输入和输出匹配。

5.2 数据集信息

制作 Dataset 后,可以通过 dataset.info 等方法查看其大小、字段名称等信息,以确保数据集的正确 性和完整性。

6. vocab 字典操作

在微调 BERT 模型之前,需要将模型的词汇表(vocab)与数据集中的文本匹配。这一步骤确保输入的 文本能够被正确转换为模型的输入格式。

from transformers import BertTokenizer
 # 加载 BERT 模型的 vocab 字典
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
 # 将数据集中的文本转换为 BERT 模型所需的输入格式
dataset = dataset.map(lambda x: tokenizer(x['text'], return_tensors="pt"), 
batched=True)
 # 查看数据集信息
print(dataset)

6.1 词汇表(vocab)

BERT 模型使用词汇表(vocab)将文本转换为模型可以理解的输入格式。词汇表包含所有模型已知的单 词及其对应的索引。确保数据集中的所有文本都能找到对应的词汇索引是至关重要的。

6.2 文本转换

使用 tokenizer 将文本分割成词汇表中的单词,并转换为相应的索引。此步骤需要确保文本长度、特殊 字符处理等都与 BERT 模型的预训练设置相一致。

7. 下游任务模型设计

在微调 BERT 模型之前,需要设计一个适应情感分析任务的下游模型结构。通常包括一个或多个全连接 层,用于将 BERT 输出的特征向量转换为分类结果。

from transformers import BertModel
 import torch.nn as nn
 class SentimentAnalysisModel(nn.Module):
 def __init__(self):
 super().__init__()
 self.bert = BertModel.from_pretrained('bert-base-chinese')
 self.drop_out = nn.Dropout(0.3)
 self.linear = nn.Linear(768, 2)  # 假设情感分类为二分类
def forward(self, input_ids, attention_mask):
 _, pooled_output = self.bert(
 input_ids=input_ids,
 attention_mask=attention_mask,
 return_dict=False
 )
 output = self.drop_out(pooled_output)
 return self.linear(output)

7.1 模型结构

下游任务模型通常包括以下几个部分: BERT 模型:用于生成文本的上下文特征向量。 Dropout 层:用于防止过拟合,通过随机丢弃一部分神经元来提高模型的泛化能力。 全连接层:用于将 BERT 的输出特征向量映射到具体的分类任务上。

7.2 模型初始化

使用 接层。初始化时,需要根据下游任务的需求,定义合适的输出维度。 BertModel.from_pretrained() 方法加载预训练的 BERT 模型,同时也可以初始化自定义的全连

8. 自定义模型训练

模型设计完成后,进入训练阶段。通过数据加载器(DataLoader)高效地批量处理数据,并使用优化器 更新模型参数

from torch.utils.data import DataLoader
 from transformers import AdamW
 # 实例化 DataLoader
 data_loader = DataLoader(dataset, batch_size=16, shuffle=True)
 # 初始化模型和优化器
model = SentimentAnalysisModel()
 optimizer = AdamW(model.parameters(), lr=5e-5)
 # 训练循环
for epoch in range(3):  # 假设训练 3 个 epoch
 model.train()
 for batch in data_loader:
 optimizer.zero_grad()
 outputs = model(input_ids=batch['input_ids'], 
attention_mask=batch['attention_mask'])
 loss = nn.CrossEntropyLoss()(outputs, batch['labels'])
 loss.backward()
 optimizer.step()

8.1 数据加载

使用 DataLoader 实现批量数据加载。 DataLoader 自动处理数据的批处理和随机打乱,确保训练的高 效性和数据的多样性。

8.2 优化器

AdamW 是一种适用于 BERT 模型的优化器,结合了 Adam 和权重衰减的特点,能够有效地防止过拟合。

8.3 训练循环

训练循环包含前向传播(forward pass)、损失计算(loss calculation)、反向传播(backward pass)、参数更新(parameter update)等步骤。每个 epoch 都会对整个数据集进行一次遍历,更新 模型参数。通常训练过程中会跟踪损失值的变化,以判断模型的收敛情况。

9. 最终效果评估与测试

在模型训练完成后,加载模型训练权重测试其效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2312628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

子数组、子串系列(典型算法思想)—— OJ例题算法解析思路

一、53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 算法代码&#xff1a; class Solution { public:int maxSubArray(vector<int>& nums) {// 1. 创建 dp 表// dp[i] 表示以第 i 个元素结尾的子数组的最大和int n nums.size();vector<int> dp(n…

Windows编程----进程的当前目录

进程的当前目录 Windows Api中有大量的函数在调用的时候&#xff0c;需要传递路径。比如创建文件&#xff0c;创建目录&#xff0c;删除目录&#xff0c;删除文件等等。拿创建文件的CreateFile函数做比喻&#xff0c;如果我们要创建的文件路径不是全路径&#xff0c;那么wind…

AVL树的介绍及实现

文章目录 &#xff08;一&#xff09;AVL的概念&#xff08;二&#xff09;AVL树的实现1.AVL树的结构2.AVL树的插入3.AVL树的查找 &#xff08;三&#xff09;检查一棵树是否是AVL树 &#xff08;一&#xff09;AVL的概念 AVL树是一棵高度平衡的二叉搜索树&#xff0c;通过控制…

快速生成viso流程图图片形式

我们在写详细设计文档的过程中总会不可避免的涉及到时序图或者流程图的绘制&#xff0c;viso这个软件大部分技术人员都会使用&#xff0c;但是想要画的好看&#xff0c;画的科学还是比较难的&#xff0c;现在我总结一套比较好的方法可以生成好看科学的viso图(图片格式)。主要思…

【极光 Orbit•STC8A-8H】03. 小刀初试:点亮你的LED灯

【极光 Orbit•STC8H】03. 小刀初试&#xff1a;点亮你的 LED 灯 七律 点灯初探 单片方寸藏乾坤&#xff0c;LED明灭见真章。 端口配置定方向&#xff0c;寄存器值细推敲。 高低电平随心控&#xff0c;循环闪烁展锋芒。 嵌入式门初开启&#xff0c;从此代码手中扬。 摘要 …

OSPF报文分析

OSPF报文分析 组播地址 224.0.0.0&#xff5e;224.0.0.255为预留的组播地址&#xff08;永久组地址&#xff09;&#xff0c;地址224.0.0.0保留不做分配&#xff0c;其它地址供路由协议使用&#xff1b; 224.0.1.0&#xff5e;238.255.255.255为用户可用的组播地址&#xff08;…

MySql性能(9)- mysql的order by的工作原理

全字段排序rowid排序全字段排序和rowid排序 3.1 联合索引优化 3.2 覆盖索引优化优先队列算法优化建议 5.1 修改系统参数 5.2 优化sql 1. 全字段排序 CREATE TABLE t ( id int(11) NOT NULL,city varchar(16) NOT NULL, name varchar(16) NOT NULL, age int(11) NOT NULL,addr v…

爬虫案例七Python协程爬取视频

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Python协程爬取视频 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 爬虫案例七协程爬取视频 提示&#xff1a;以下是本篇文章正文…

智慧城市智慧社区项目建设方案

一、项目背景 在全球化进程加速的今天&#xff0c;城市化问题日益凸显&#xff0c;传统的城市管理模式已难以满足现代社会对高效、智能化管理的需求。智慧城市和智慧社区的概念应运而生&#xff0c;其核心目标是通过信息技术手段&#xff0c;提升城市资源的利用效率&#xff0…

RabbitMQ高级特性--消息确认机制

目录 一、消息确认 1.消息确认机制 2.手动确认方法 二、代码示例 1. AcknowledgeMode.NONE 1.1 配置文件 1.2 生产者 1.3 消费者 1.4 运行程序 2.AcknowledgeMode.AUTO 3.AcknowledgeMode.MANUAL 一、消息确认 1.消息确认机制 生产者发送消息之后&#xff0c;到达消…

Java EE 进阶:Spring IoCDI

IOC的简单介绍 什么是Spring&#xff1f;Spring是一个开源的框架&#xff0c;让我们的开发更加的简单&#xff0c;我们可以用一句更加具体的话来概括Spring&#xff0c;就是Spring是一个包含众多工具方法的IOC容器。 简单介绍一下IOC&#xff0c;我们之前说过通过ReqestContr…

Java数据结构第二十期:解构排序算法的艺术与科学(二)

专栏&#xff1a;Java数据结构秘籍 个人主页&#xff1a;手握风云 目录 一、常见排序算法的实现 1.1. 直接选择排序 1.2. 堆排序 1.3. 冒泡排序 1.4. 快速排序 一、常见排序算法的实现 1.1. 直接选择排序 每⼀次从待排序的数据元素中选出最小的⼀个元素&#xff0c;存放在…

【算法day5】最长回文子串——马拉车算法

最长回文子串 给你一个字符串 s&#xff0c;找到 s 中最长的 回文 子串。 https://leetcode.cn/problems/longest-palindromic-substring/description/ 算法思路&#xff1a; class Solution { public:string longestPalindrome(string s) {int s_len s.size();string tmp …

《如何排查Linux系统平均负载过高》

【系统平均负载导读】何为系统平均负载&#xff1f;假设一台云服务主机&#xff0c;突然之间响应用户请求的时间变长了&#xff0c;那么这个时候应该如何去排查&#xff1f;带着这个问题&#xff0c;我们对“平均负载”展开深入的探讨和研究。 何为Linux系统的平均负载&#xf…

基于DeepSeek实现PDF嵌入SVG图片无损放大

1. PDF中效果图 2. 询问Deepseek进行代码书写&#xff0c;不断优化后结果 /*** SVG工具类&#xff0c;用于生成价格趋势的SVG图表*/ public class SvgUtils {// SVG画布尺寸private static final int WIDTH 800;private static final int HEIGHT 500;private static final i…

整型的不同类型和溢出

一、整数的不同类型 不同编程语言中的整数类型主要通过以下两个维度区分&#xff1a; 1. 存储大小 字节数&#xff1a;决定整数能表示的范围&#xff08;如 1字节8位&#xff09;。 常见类型&#xff1a; byte&#xff08;1字节&#xff09;、short&#xff08;2字节&#x…

使用express创建服务器保存数据到mysql

创建数据库和表结构 CREATE DATABASE collect;USE collect;CREATE TABLE info (id int(11) NOT NULL AUTO_INCREMENT,create_date bigint(20) DEFAULT NULL COMMENT 时间,type varchar(20) DEFAULT NULL COMMENT 数据分类,text_value text COMMENT 内容,PRIMARY KEY (id) ) EN…

小程序 wxml 语法 —— 41列表渲染 - 进阶用法

这一节讲解列表渲染的两个进阶用法&#xff1a; 如果需要对默认的变量名和下标进行修改&#xff0c;可以使用 wx:for-item 和 wx:for-item&#xff1a; 使用 wx:for-item 可以指定数组当前元素的变量名使用 wx:for-index 可以指定数组当前下标的变量名 将 wx:for 用在 标签上&…

python语言总结(持续更新)

本文主要是总结各函数&#xff0c;简单的函数不会给予示例&#xff0c;如果在平日遇到一些新类型将会添加 基础知识 输入与输出 print([要输出的内容])输出函数 input([提示内容]如果输入提示内容会在交互界面显示&#xff0c;用以提示用户)输入函数 注释 # 单行注释符&…

FPGA学习篇——Verilog学习5(reg,wire区分及模块例化)

1 何时用reg&#xff0c;何时用wire&#xff1f; 这个我找了一些网上的各种资料&#xff0c;大概说一下自己的理解&#xff0c;可能还不太到位... wire相当于一根线&#xff0c;是实时传输的那种&#xff0c;而reg是一个寄存器&#xff0c;是可以存储数据的&#xff0c;需要立…