BERT论文解读及情感分类实战(论文复现)

news2024/11/26 18:44:09

BERT论文解读及情感分类实战(论文复现)

本文所涉及所有资源均在传知代码平台可获取

文章目录

    • BERT论文解读及情感分类实战(论文复现)
        • 简介
        • BERT文章主要贡献
        • BERT模型架构
        • 技术细节
        • 任务1 Masked LM(MLM)
        • 任务2 Next Sentence Prediction (NSP)
        • 模型输入
        • 下游任务微调
        • GLUE数据集
        • SQuAD v1.1 和 v2.0
        • NER
        • 情感分类实战
        • IMDB影评情感数据集
        • 数据集构建
        • 模型构建
        • 超参数设置
        • 训练结果
        • 注意事项

简介

本文将先介绍BERT架构和技术细节,然后介绍一个使用IMDB公开数据集情感分类的完整实战(包含数据集构建、模型训练微调、模型评估)IMDB数据集分为25000条训练集和25000条测试集,是情感分类中的经典公开数据集,这里使用BERT模型进行情感分类,测试集准确率超过93%

BERT文章主要贡献

这篇文章的主要贡献是提出了一种新的语言表示模型——BERT(Bidirectional Encoder Representations from Transformers)。BERT的核心创新点和贡献如下:

深度双向预训练表示:与以往的语言表示模型不同,BERT旨在通过联合考虑所有层中的左侧和右侧上下文来预训练深度双向表示。这使得BERT能够在预训练阶段捕获更丰富的语言特征。

简化的任务特定架构修改:预训练的BERT模型可以通过添加少量额外的输出层来微调(fine-tune),从而适应广泛的任务,如问答和语言推断,而无需对模型架构进行大量特定任务的修改。

多项自然语言处理任务的新最佳结果:BERT在十一个自然语言处理任务上取得了新的最先进结果,包括将GLUE基准的分数推高到80.5%(绝对提高了7.7个百分点),MultiNLI准确率提高到86.7%(提高了4.6个百分点),SQuAD v1.1问答测试的F1分数提高到93.2(提高了1.5个百分点),以及SQuAD v2.0测试的F1分数提高到83.1(提高了5.1个百分点)。

预训练任务的重要性:BERT通过使用“掩码语言模型”(Masked Language Model, MLM)和“下一句预测”(Next Sentence Prediction, NSP)任务来展示深度双向预训练的重要性。MLM任务通过随机掩盖输入中的一些标记,然后预测这些掩盖标记的原始词汇ID,从而使得模型能够融合左右上下文。NSP任务则通过预测两个文本片段之间的关系来训练模型理解句子间的关系

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 = sentences
        self.labels = labels
        self.tokenizer = tokenizer
        self.max_length = max_length

    def __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)

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

文章代码资源点击附件获取

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

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

相关文章

【web安全】——常见框架漏洞

1.ThinkPHP框架漏洞 thinkphp是一个国内轻量级的开发框架,采用phpapache,在更新迭代中,thinkphp也经常爆出各种漏洞,thinkphp一般有thinkphp2、thinkphp3、thinkphp5、thinkphp6版本,前两个版本已经停止更新&#xff…

【详细教程】如何使用YOLOv11进行图像与视频的目标检测

《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…

m4a怎么转换成mp3?音频转换MP3只需要这6个小工具!

m4a怎么转换成mp3?M4A和MP3是两种常见的音频格式,M4A通常使用AAC(高级音频编码)进行压缩,提供更高的音质和更小的文件体积,特别适合在Apple设备上使用。而MP3则以其高压缩比和广泛的兼容性著称,…

TM1618数码管控制芯片使用共阳极数码管过程中的问题和解决办法

控制芯片的基本了解 相比于不用控制芯片的电路:这里带2根电源线和3个信号线,共使用了5根线,但可以控制4个8段数码管显示。若是电路直接控制4个8段数码管需要84113个接口,这对于MCU的珍贵引脚简直是浪费。 这里不会出现余晖效应也…

大花蔷薇T2T基因组-60

Multi-omics analyzes of Rosa gigantea illuminate tea scent biosynthesis and release mechanisms 多组学分析揭示了大花蔷薇茶香合成及释放机制 摘要 玫瑰是一种全球广泛栽培的重要观赏作物,用于香水生产。然而,由于缺乏茶玫瑰的参考基因组&#x…

鸿蒙开发(NEXT/API 12)【穿戴设备传感器获取】手机侧应用开发

手机侧应用可以通过Wear Engine获取穿戴设备上的传感器信息,并通过打开、关闭命令控制获取传感器数据。 使用传感器相关接口前,需要向手机侧用户申请获取对应权限的授权 传感器类型申请权限ECG、PPG、HR[HEALTH_SENSOR]人体传感器ACC、GYRO、MAG[MOTIO…

汇编DEBUG程序调用

工具 系统:Windows 11 应用:DOSBox 0.74-3 下载安装教程:本人写的《DOSBox下载安装(Windows系统 DOSBox 0.74-3)》 https://blog.csdn.net/just_do_it_sq/article/details/142715182?spm1001.2014.3001.5501 相关文…

C++ 算法学习——1.3 深度优先搜索

深度优先搜索:简单讲就是搜到某条路尽头,再掉头回溯搜其他的路。此中重点是尽头的判断,和对走过的路进行标记。 一般采用递归的写法,模板大致如下: DFS(node,visited):if node is in visited:returnadd node to visi…

通用mybatis-plus查询封装(QueryGenerator)

结果如下图所示 java类代码分别如下 1 package com.hdx.contractor.util.mybatis;import com.hdx.contractor.common.user.SecurityUser; import com.hdx.contractor.common.user.UserDetail; import com.hdx.contractor.util.query.oConvertUtils; import lombok.extern.slf…

OpenHarmony(鸿蒙南向开发)——轻量系统芯片移植案例(一)

往期知识点记录: 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ 持续更新中…… 轻量带屏解决方案之恒玄芯片移植案例 本文章基于恒玄科技BES2600W…

【AI知识点】交叉验证(Cross-Validation)

交叉验证(Cross-Validation) 是机器学习中常用的一种模型评估方法,用于评估模型的性能和泛化能力。它通过在不同的训练集和验证集上多次训练和测试模型,从而有效地评估模型在未见数据上的表现,帮助防止模型的过拟合和欠…

【RTD MCAL 篇2】 K312 UART DMA

【RTD MCAL 篇2】 K312 UART DMA 一,文档简介二, 功能实现2.1 K312 MINIEVB硬件配置2.2 EB 配置2.2.1 Mcl module2.2.2 Mcu module2.2.3 Platform module2.2.4 Port module2.2.5 Uart module2.2.6 Rm module 2.3 main code 三,测试结果 一&am…

Clio——麻省理工学院增强机器人场景理解算法

概述 机器人感知长期以来一直受到现实世界环境复杂性的挑战,通常需要固定设置和预定义对象。麻省理工学院的工程师 已经开发了Clio这项突破性的系统可以让机器人直观地理解并优先考虑周围环境中的相关元素,从而提高其高效执行任务的能力。 了解对更智…

【Python】Marmir 使用指南:Python 驱动的电子表格生成器

Marmir 是一个由 Python 驱动的电子表格生成工具,专门用于将 Python 数据结构(如字典、列表等)转换为电子表格文件(如 Excel)。Marmir 的设计目标是提供比传统电子表格库(如 xlwt)更强大和灵活的…

ctf.bugku-备份是个好习惯

访问页面得到字符串 这串字符串是重复的; d41d8cd98f00b204e9800998ecf8427e 从前端、源码上看,除了这段字符串,没有其他信息;尝试解密,长度32位;各种解密方式试试; MD5免费在线解密破解_MD5在…

文件后缀名不见了怎么办?

有一天,突然有需要更改文件的后缀名,可奇怪的是文件只有名称,后缀不见了,这该如何修改呢? 第一步:打开此电脑,最上面一栏选择“查看” 第二步:将“文件扩展名”勾选上 第三步&…

会议时如何实现扫码签到?

如何实现扫码签到? 在现代活动管理中,签到环节是不可或缺的一部分。它不仅关系到活动的顺利进行,还涉及到参与者的体验。传统的签到方式往往耗时且效率不高,而随着技术的发展,扫码签到成为了一种高效且便捷的解决方案。…

用小学生可以理解的语言讲一下什么是大模型

好的,用小学生的语言来说,大模型就像是一个超级聪明的机器人老师,它懂得很多东西,可以帮助我们做很多事情。 1. **懂得很多**:大模型知道很多知识,就像一个巨大的图书馆,里面有很多书&#xff0…

【星汇极客】单片机竞赛之2024睿抗机器人大赛-火线速递赛道(持续更新)

前言 本人是一名嵌入式学习者,在大学期间也参加了不少的竞赛并获奖,包括但不限于:江苏省电子设计竞赛省一、睿抗机器人国二、中国高校智能机器人国二、嵌入式设计竞赛国三、光电设计竞赛国三、节能减排竞赛国三。 后面会经常写一下博客&…

归并排序:递归、非递归实现、文件排序(归并排序实现)

目录 归并排序递归实现 1.归并排序基本思想 2.归并排序单趟思路 3.代码思路步骤 3.1.归并排序实现思路步骤 3.2.总结 3.2.1.数组归并与链表归并的差异 (1)数组归并 (2)链表归并 (3)总结 3.2.2.归并排序的递归实现总结 4.归并排序递归实现代码 5.归并排序递归递归展…