【传知代码】BERT论文解读及情感分类实战-论文复现

文章目录

  • 概述
  • 原理介绍
    • BERT模型架构
    • 任务1 Masked LM(MLM)
    • 任务2 Next Sentence Prediction (NSP)
    • 模型输入
    • 下游任务微调
    • GLUE数据集
    • SQuAD v1.1 和 v2.0
    • NER
  • 情感分类实战
    • IMDB影评情感数据集
    • 数据集构建
    • 模型构建
  • 核心代码
    • 超参数设置
    • 训练结果
    • 注意事项
  • 小结

本文涉及的源码可从BERT论文解读及情感分类实战该文章下方附件获取

概述

本文将先介绍BERT架构和技术细节,然后介绍一个使用IMDB公开数据集情感分类的完整实战(包含数据集构建、模型训练微调、模型评估)

IMDB数据集分为25000条训练集和25000条测试集,是情感分类中的经典公开数据集,这里使用BERT模型进行情感分类,测试集准确率超过93%

BERT(Bidirectional Encoder Representations from Transformers)是一种基于Transformer架构的双向编码器语言模型,它在自然语言处理(NLP)领域取得了显著的成果。以下是BERT的架构和技术细节,以及使用BERT在IMDB公开数据集上进行情感分类的实战介绍。

  • BERT架构和技术细节
  1. 双向编码器:BERT模型通过联合考虑所有层中的左侧和右侧上下文来预训练深度双向表示,这使得BERT能够在预训练阶段捕获更丰富的语言特征。
  2. 预训练任务
    • 掩码语言模型(MLM):BERT随机掩蔽词元并使用来自双向上下文的词元以自监督的方式预测掩蔽词元。在预训练任务中,BERT将随机选择15%的词元作为预测的掩蔽词元,其中80%的时间用特殊的<MASK>词元替换,10%的时间替换为随机词元,剩下的10%保持不变。
    • 下一句预测(NSP):为了帮助理解两个文本序列之间的关系,BERT在预训练中考虑了一个二元分类任务——下一句预测。在生成句子对时,有一半的时间它们确实是连续的句子,另一半的时间第二个句子是从语料库中随机抽取的。
  3. 模型微调:预训练的BERT模型可以通过添加少量额外的输出层来微调,从而适应广泛的任务,如问答和语言推断,而无需对模型架构进行大量特定任务的修改。
  • 使用BERT在IMDB数据集上进行情感分类的实战
  1. 数据集:IMDB公开数据集分为25000条训练集和25000条测试集,用于情感分类任务。
  2. 模型训练与微调
    • 加载预训练的BERT模型。
    • 对原始数据进行预处理,使其符合BERT模型的输入要求。
    • 在训练集上训练BERT模型,进行微调以适应情感分类任务。
  3. 模型评估
    • 在测试集上评估模型的性能,计算准确率等指标。
    • 报告测试集准确率超过93%的结果。

BERT模型在多个自然语言处理任务上取得了新的最先进结果,包括情感分类任务。使用BERT模型进行情感分类能够取得较好的效果,尤其是在拥有足够数据量和计算资源的情况下。

原理介绍

BERT模型架构

在这里插入图片描述

BERT模型就是transformer的encoder堆叠而成,只是训练方式是有所讲究。
BERT能够在下游任务微调,模型结构也只需要改变输出层即可方便地适配下游任务。
[CLS]是添加在每个输入示例前面的一个特殊符号,用于整体信息的表示
[SEP]是一个特殊的分隔符标记(例如分隔问题/答案)

BERT不使用传统的从左到右或从右到左的语言模型来预训练。相反,是使用两个无监督任务预训练BERT。

任务1 Masked LM(MLM)

直观地说,我们有理由相信深度双向模型严格地比从左到右模型或从左到左模型和从右到左模型的简单结合更强大。不幸的是,标准条件语言模型只能从左到右或从右到左进行训练,因为双向条件反射允许每个单词间接地“看到自己”,并且该模型可以在多层上下文中预测目标单词。

为了训练深度双向表示,只需随机屏蔽一定百分比的输入令牌,然后预测那些屏蔽的令牌。文章将此过程称为“masked LM”(MLM)。在这种情况下,被屏蔽的单词的最终隐藏向量被馈送到词汇表上的输出softmax中,然后得出预测。

文章随机屏蔽每个序列中15%的单词。然后只预测被屏蔽的单词。

尽管这能够获得双向预训练模型,但缺点是在预训练和微调之间造成了不匹配,因为[MASK]在微调过程中不会出现。为了缓解这种情况,我们并不总是用实际的[MASK]替换“屏蔽”单词。训练数据生成器随机选择15%的单词用于预测。在这些单词中,使用
(1)80%概率的替换为[MASK],即需要进行预测。 这是最常见的掩盖策略,模型需要学习根据上下文来预测原本的词汇,这样的训练方式使得模型能够更好地理解词汇在不同上下文中的含义。
(2)10%概率的替换为随机单词。 这种策略增加了训练数据的多样性,迫使模型不仅仅依赖于特定的掩盖词汇来做出预测。这种随机性有助于模型学习到更加鲁棒的上下文表示,因为它不能简单地记忆或依赖于特定的掩盖词汇。
(3)10%概率单词不变。 这种策略保留了原始词汇,不进行掩盖,这有助于模型学习到词汇本身的表示,同时也为模型提供了一些直接从输入中学习的机会,而不是完全依赖于上下文推断。

任务2 Next Sentence Prediction (NSP)

许多重要的下游任务,如问答(QA)和自然语言推理(NLI),都是基于理解两句之间的关系,而语言建模并不能直接捕捉到这一点。为了训练一个理解句子关系的模型,文章让模型在下一个句子预测任务上进行预训练,该任务可以从任何单语语料库中轻松生成。

具体而言,当为每个预训练示例选择句子A和B时,50%的概率B是A后面的下一个句子(标记为Is Next),50%的概率B是来自语料库的随机句子(标记为Not Next)。

模型输入

在这里插入图片描述

Token Embeddings就是词的嵌入层表示,只不过句子开头要加[CLS]不同句子之间要加[SEP]。

[CLS]的用处如下:
句子表示:在预训练阶段,[CLS]标记的最终隐藏状态(即经过Transformer最后一层的输出)被用作整个输入序列的聚合表示(aggregate sequence representation)。这意味着[CLS]的表示捕捉了整个序列的上下文信息。

分类任务:在微调阶段,尤其是在句子级别或序列级别的分类任务中,[CLS]的最终隐藏状态被用来作为分类的输入特征。例如,在情感分析、自然语言推断或其他类似的任务中,[CLS]的输出向量会被送入一个额外的线性层(分类层),然后应用softmax函数来预测类别。

问答任务:在问答任务中,[CLS]也可以用来进行答案的预测。例如,在SQuAD问答任务中,模型会输出答案的开始和结束位置的概率分布,而[CLS]的表示有助于模型理解问题和段落之间的关系。

[SEP]用处如下:

分隔句子:
当BERT处理由多个句子组成的句子对时(例如,在问答任务中的问题和答案),[SEP]标记用来明确地分隔两个句子。它允许模型区分序列中的不同部分,尤其是在处理成对的句子时,如在自然语言推断或问答任务中。

输入表示:
在构建输入序列时,句子A(通常是第一个句子或问题)会以[CLS]标记开始,接着是句子A的单词,然后是[SEP]标记,然后是句子B(通常是第二个句子或答案)的单词…
通过在句子之间插入[SEP],模型可以明确地知道序列的结构,从而更好地处理和理解输入的文本。

位置嵌入:
与[CLS]类似,[SEP]也有一个对应的嵌入向量,这个向量是模型学习到的,并且与[CLS]的嵌入向量不同。这个嵌入向量帮助模型理解[SEP]标记在序列中的位置和作用。

注意力机制:
在Transformer模型的自注意力机制中,[SEP]标记使得模型能够区分来自不同句子的标记,这对于模型理解句子间关系的任务至关重要。

预训练和微调:
在预训练阶段,[SEP]帮助模型学习如何处理成对的句子,这在NSP(Next Sentence Prediction)任务中尤为重要。在微调阶段,[SEP]继续用于分隔句子对,使得模型能够适应各种需要处理成对文本的下游任务。

Segment Embeddings 用于标记是否属于同一个句子。

Position Embeddings 用于标记词的位置信息

下游任务微调

BERT能够轻松地适配下游任务,此时使用已经预训练好的BERT模型就能花很少的资源和时间得到很不错地结果,而不需要我们从头开始训练BERT模型。

接下来就看一下BERT在不同数据集是怎么使用的

GLUE数据集

GLUE(General Language Understanding Evaluation)基准测试是一组不同的自然语言理解任务的集合。任务描述如下:

MNLI(Multi-Genre Natural Language Inference):给定一对句子,预测第二个句子是否是第一个句子的蕴含、矛盾或中立。
QQP(Quora Question Pairs):判断Quora上的两个问题是否语义等价。
QNLI(Question Natural Language Inference):基于斯坦福问答数据集的二分类任务,判断问题和句子是否包含正确答案。
SST-2(Stanford Sentiment Treebank):电影评论中句子的情感分类任务。
CoLA(Corpus of Linguistic Acceptability):判断英语句子是否语法正确。
STS-B(Semantic Textual Similarity Benchmark):判断句子对在语义上的相似度。
MRPC(Microsoft Research Paraphrase Corpus):判断句子对是否语义等价。
RTE(Recognizing Textual Entailment):文本蕴含任务,与MNLI类似,但训练数据更少。
WNLI(Winograd NLI):自然语言推理数据集,但由于构建问题,该数据集的结果未被考虑。

在这里插入图片描述

对于多个句子的,输入形式就是[CLS]+句子1+[SEP]+句子2+…
对于单个句子的就是[CLS]+句子
然后最后一层输出的[CLS]用来接个全连接层进行分类,适配不同任务需要。

SQuAD v1.1 和 v2.0

SQuAD(Stanford Question Answering Dataset)是问答任务的数据集,包括SQuAD v1.1和SQuAD v2.0两个版本。任务描述如下:

SQuAD v1.1:给定一个问题和一段文本,预测答案在文本中的位置。
SQuAD v2.0:与SQuAD v1.1类似,但允许问题没有答案,使问题更具现实性。

在这里插入图片描述

对于SQuAD v1.1,输入格式为[CLS]+问题+[SEP]+段落信息
因为这个数据集就是问题能够在段落中找到答案,构造一个得分,得分最大的作为预测值,具体如下:
首先引入S和E两组可训练参数,用于计算答案的开始和结束文章

在这里插入图片描述

NER

对于命名实体识别的任务,BERT实现起来也是非常简单。

在这里插入图片描述

只需要对最后一层的每个单词预测对于的实体标记即可。

情感分类实战

IMDB影评情感数据集

IMDb Movie Reviews数据集是一个用于情感分析的标准二元分类数据集,它包含来自互联网电影数据库(Internet Movie Database,简称IMDB)的50,000条评论,这些评论被标记为正面或负面。

评论数量和平衡性:数据集包含50,000条评论,其中正面和负面评论的数量是相等的,即各占一半。

评分标准:评论是基于10分制的评分进行分类的。负面评论的评分在0到4分之间,而正面评论的评分在7到10分之间。

评论选择:为了确保数据集中的评论具有高度的两极性,选择了评分差异较大的评论。每部电影最多只包含30条评论。

在这里插入图片描述

可以看一下榜单,目前在paperwithcode上最高是96.68%,看这模型的名字就不太好惹,但是我们这里简单使用BERT接个全连接进行二分类,也能达到93%

数据集构建

# 定义数据集类
class SentenceDataset(Dataset):def __init__(self, sentences, labels, tokenizer, max_length=512):self.sentences = sentencesself.labels = labelsself.tokenizer = tokenizerself.max_length = max_lengthdef __len__(self):return len(self.sentences)def __getitem__(self, idx):# 对文本进行编码encoded = self.tokenizer.encode_plus(self.sentences[idx],add_special_tokens=True,max_length=self.max_length,return_token_type_ids=False,padding='max_length',truncation=True,return_attention_mask=True,return_tensors='pt')# 获取编码后的数据和注意力掩码input_ids = encoded['input_ids']attention_mask = encoded['attention_mask']# 返回编码后的数据、注意力掩码和标签return input_ids, attention_mask, self.labels[idx]

因为BERT是WordPiece嵌入的,所以需要使用他专门的切词工具才能正常使用,因此在数据预处理的过程中,可以切好词转化为bert字典中的id,这样直接喂入bert就能得到我们要的句子bert向量表示了,然后就可以用来分类了。

模型构建

使用transformers中预训练好的BERT模型(bert-base-uncased)
我们可以先来看一下bert模型的输入输出:

from transformers import BertTokenizer, BertModel# 初始化分词器和模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')sentences = ["Hello, this is a positive sentence."]# 对句子进行编码
encoded_inputs = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt', max_length=512)
outputs = model(**encoded_inputs)

在这里插入图片描述

可以看到分词器的输出encoded_inputs由三部分组成,维度都是[batch_size, seq_len]

在这里插入图片描述

可以看到bert模型的输出为:
outputs[0]是[batch_size, seq_len, hidden_size]
outputs[1]是[batch_size, hidden_size]
outputs[0]就是每个词的表示
outputs[1]就是[CLS],可以看成这句话的表示
对于我们的任务,就是实现情感分类,因此直接使用outputs[1]接全连接就行了

核心代码

# 定义一个简单的全连接层来进行二分类
class BertForSequenceClassification(nn.Module):def __init__(self, bert, num_labels=2):super(BertForSequenceClassification, self).__init__()self.bert = bert #BERT模型self.classifier = nn.Linear(bert.config.hidden_size, num_labels)def forward(self, input_ids, attention_mask):outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)pooled_output = outputs[1]logits = self.classifier(pooled_output)return logits

代码就是非常简洁,当然,如果想要更好地效果,可以直接加个LSTM、BiLSTM+Attention等来更好地进行语义编码,操作空间还是很大地。

超参数设置

在这里插入图片描述

batch_size=64 需要50多G显存才能跑起来,现存小的话可以开4
lr=2e-5就是微调大模型的常用学习率
epoch=2 其实结果已经很不错了,这可能就是微调的魅力
num_labels = 2因为数据集是二分类任务

因为这个实战是个简洁版本,所以超参数也设定的很少,代码也是很简洁,适合初学者参考学习

训练结果

在这里插入图片描述

可以看到测试集的准确率最高为93.56%
还是很不错的
不过我并没有固定随机种子
可能多跑几次能够还有望超越93.56%

注意事项

train_sentences, train_labels = get_data(r'./data/train_data.tsv')
test_sentences, test_labels = get_data(r'./data/test_data.tsv')
# 初始化BERT tokenizer
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
bert_model = BertModel.from_pretrained('bert-base-uncased').to(device)

模型和数据附件中都有,运行的适合需要将模型和数据的路径修改为自己的路径

小结

使用BERT在IMDB数据集上进行情感分类的实战取得了令人满意的结果。通过本次实战,我们深入了解了BERT模型的工作原理和训练方法,并获得了宝贵的实践经验。
在这里插入图片描述

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

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

相关文章

AIOps在线评测基准首阶段建设完成,面向社区发布真实运维数据!

本文根据必示科技算法研究员、产品总监聂晓辉博士在2024 CCF国际AIOps挑战赛线下宣讲会上的演讲整理成文。 2024年1月份OpenAIOps社区成立&#xff0c;随着越来越多的社区成员加入&#xff0c;各项工作在有条不紊的推进中。在线评测基准系统&#xff08;AIOps Live Benchmark&a…

积鼎CFDPro水文水动力模型,专为中小流域洪水“四预”研发的流体仿真技术

水动力模型与水文模型是水利工程与水文学研究中不可或缺的两大工具。水动力模型着重于流体运动的动力学机制&#xff0c;通过一系列方程组捕捉水流的时空变化&#xff0c;而概念性水文模型则侧重于流域尺度的水文循环过程&#xff0c;利用物理概念与经验关系进行近似模拟。两者…

Windows系统部署YOLOv5 v6.1版本的训练与推理环境保姆级教程

文章目录 一 概述二 依赖环境(prerequisites)2.1 硬件环境2.2 软件环境 三 环境安装3.1 创建并激活虚拟环境3.2 安装Pytorch与torchvision3.3 校验Pytorch安装3.4 下载 YOLOv5 v6.1 源码3.5 安装 YOLOv5 依赖3.6 下载预训练模型3.7 安装其他依赖3.8 测试环境安装3.9 测试训练流…

jupyter notebook更改位置

1.找到jupyer的配置文件 一般在c盘用户的.jupter文件夹下 2. 用记事本打开这个配置文件&#xff0c;定位到c.NotebookApp.notebook_dir /path_to_your_directory 替换你的位置 3.找到jupyer图标的位置&#xff0c;打开属性 添加要存放的位置在目标文件的末尾&#xff0c;重新…

一个全面了解Xilinx FPGA IP核的窗口:《Xilinx系列FPGA芯片IP核详解》(可下载)

随着摩尔定律的逐渐放缓&#xff0c;传统的芯片设计方法面临着越来越多的挑战。而FPGA以其并行处理能力和可编程性&#xff0c;为解决复杂问题提供了新的途径。它允许设计者在同一个芯片上实现多种不同的功能模块&#xff0c;极大地提高了资源的利用率和系统的综合性能。 FPGA…

HCIA-ARP

ARP的由来 ARP这一种协议它会是在我们HCIA中第一个需要完全掌握的一个协议&#xff0c;不然对于数据通讯来说大家都会一直觉得很绕圈 协议栈&#xff0c;网线&#xff0c;网卡&#xff0c;它们组成了我们最小的数据通信的小脉络注&#xff1a;可以了解ARP攻击&#xff08;冒充访…

文献解读-群体基因组第二期|《中国人群中PAX2新生突变的检测及表型分析:一项单中心研究》

关键词&#xff1a;应用遗传流行病学&#xff1b;群体测序&#xff1b;群体基因组&#xff1b;基因组变异检测&#xff1b; 文献简介 标题&#xff08;英文&#xff09;&#xff1a;Detection of De Novo PAX2 Variants and Phenotypes in Chinese Population: A Single-Cente…

new CCDIKSolver( OOI.kira, iks ); // 创建逆运动学求解器

demo案例 new CCDIKSolver(OOI.kira, iks); 在使用某个特定的库或框架来创建一个逆运动学&#xff08;Inverse Kinematics, IK&#xff09;求解器实例。逆运动学在机器人学、动画和计算机图形学等领域中非常重要&#xff0c;它用于根据期望的末端执行器&#xff08;如机器人的…

建设现代智能工业-智能化、数字化、自动化节能减排

建设现代智能工业-智能化节能减排 遵循“一体化”能源管理(Integrated Energy Management)的设计宗旨&#xff0c;集成城市各领域(如工业.交通、建筑等&#xff09;的能源生产和消费信息&#xff0c;面向城市政府、企业、公众三类实体&#xff0c;提供“一体化”的综合能源管理…

uniapp h5项目切换导航栏及动态渲染按钮颜色

1.效果图 2.html,动态渲染按钮样式---三元判断 <!-- 切换栏 --><view class"statusList"><block v-for"(item,index) in list" :key"index"><view class"swiper-tab-list" :class"current item.id?activ…

CEEMDAN +组合预测模型(CNN-Transfromer + XGBoost)

注意&#xff1a;本模型继续加入 组合预测模型全家桶 中&#xff0c;之前购买的同学请及时更新下载! 往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 VMD CEEMDAN 二次分解&#xff0c;Transformer-BiGRU预测模…

【JAVA WEB实用与优化技巧】如何自己封装一个自定义UI的Swagger组件,包含Swagger如何处理JWT无状态鉴权自动TOKEN获取

目录 一、Swagger 简介1. 什么是 Swagger&#xff1f;2. 如何使用 Swagger3. Springboot 中swagger的使用示例1. maven 引入安装2. java配置 二、Swagger UI存在的缺点1.不够方便直观2.请求的参数没有缓存3.不够美观4.如果是JWT 无状态登录&#xff0c;Swagger使用起来就没有那…

STL-stack的使用及其模拟实现

在C标准库中&#xff0c;stack是一种容器适配器&#xff0c;它以后进先出的方式组织数据&#xff0c;其删除只能从容器的栈顶进行元素的插入与取出操作。 stack的使用 stack的构造函数 stack的成员函数 empty&#xff1a;判断栈是否为空back&#xff1a;返回当前栈中元素的数量…

推荐一个 Java 开源企业级新能源汽车智能共享充电桩管理平台

文末可获取 Orise 平台源码 01 Orise 智能充电桩管理平台 奥升( Orise ) 新能源汽车充电桩管理 Saas 云平台是一个集充电设备管理、用户充电管理、线上小程序内容管理于一体的综合管理平台。Orise充电桩平台支持高并发业务、业务动态伸缩、桩通信负载均衡&#xff0c;通过Docke…

Golang项目代码组织架构实践

Golang在项目结构上没有强制性规范&#xff0c;虽然这给了开发者很大的自由度&#xff0c;但也需要自己沉淀一套可行的架构。本文介绍了一种项目布局&#xff0c;可以以此为参考设计适合自己的 Golang 项目组织模式。原文: Golang Project Layout Go 有很多强制的或是约定俗成的…

收藏:六款好用的企业防泄密软件推荐

企业数据如同企业的生命线&#xff0c;保护数据安全免遭泄露变得至关重要。 面对日益复杂的网络安全威胁&#xff0c;一套高效的企业防泄密软件成为企业安全架构的基石。 以下是精心挑选的六款企业防泄密软件&#xff0c;它们在数据加密、访问控制、行为监控等方面表现出色&am…

lua vm 常识一: attempt to yield across a C-call boundary 的原因分析

使用 lua 的时候有时候会遇到这样的报错&#xff1a;“attempt to yield across a C-call boundary”。 1. 网络上的解释 可以在网上找到一些关于这个问题的解释。 1.1 解释一 这个 issue&#xff1a;一个关于 yield across a C-call boundary 的问题&#xff0c;云风的解释是…

轮廓系数(Average silhouette) | 最佳聚类数的判定

1.最佳分类个数 # 辅助确定最佳聚类数 4.7*2.6 factoextra::fviz_nbclust( t(DPAU_2), kmeans, method "silhouette")在2有下降拐点&#xff0c;但是样本较多时分成2类一般意义不大。 在7时也有下降拐点。 2.查看每个分类的轮廓系数 (1) pam k5 library(cluste…

【Paddle】Inplace相关问题:反向传播、影响内存使用和性能

【Paddle】Inplace相关问题&#xff1a;反向传播、影响内存使用和性能 写在最前面inplace 的好处有哪些&#xff1f;能降低计算复杂度吗在反向传播时&#xff0c;Inplace为什么会阻碍呢&#xff1f;“计算图的完整性受损”表达有误原地操作 sin_()为什么原地操作会阻碍反向传播…

活动会议邀请函制作易企秀源码系统 清爽的画面轻轻滑动自动翻页 带完整的前后端搭建教程

系统概述 在当今数字化时代&#xff0c;活动会议的组织和宣传变得至关重要。为了满足这一需求&#xff0c;活动会议邀请函制作易企秀源码系统应运而生。它不仅为用户提供了一个便捷、高效的工具&#xff0c;还具备一系列令人瞩目的特色功能&#xff0c;为活动会议的成功举办提…