一、BERT介绍
BERT(Bidirectional Encoder Representations from Transformers)是一种预训练的自然语言处理模型,由Google于2018年发布。BERT模型的核心是Transformer编码器,它可以在大规模语料库上进行无监督预训练,然后通过微调在各种NLP任务上进行微调。BERT模型是一种双向的深度学习模型,它可以同时考虑上下文中的所有单词,从而更好地理解句子的含义。BERT模型已被证明在多项NLP任务上取得了最佳结果,包括问答、文本分类、命名实体识别等。
-
BERT是一种基于深度神经网络的自然语言理解模型,它可以从大规模的无标注文本中学习语言的语义和结构。
-
BERT的创新之处在于它使用了双向的Transformer编码器,可以同时考虑左右两个方向的上下文信息,从而捕捉到更丰富的语言特征。
-
BERT的预训练任务包括MLM和NSP,分别用于学习词汇和句子级别的表示。MLM是一种完形填空任务,它随机地将输入文本中的一些词替换为特殊符号[MASK],然后让模型预测被遮盖的词。NSP是一种二分类任务,它给定两个句子,让模型判断它们是否是连续的。
-
BERT在多种自然语言处理任务上都取得了显著的提升,例如问答、情感分析、命名实体识别、文本分类等。BERT不仅提高了模型的性能,也简化了模型的微调过程,只需要在预训练模型的顶部添加少量的任务相关层,就可以适应不同的任务。
-
BERT还催生了许多基于它改进或扩展的模型,例如RoBERTa、ALBERT、XLNet、ELECTRA等。这些模型在不同方面对BERT进行了优化或创新,例如增加数据量、减少参数量、改变预训练任务等。
二、BERT的基本原理
2.1、微调 BERT
BERT的预训练和微调过程。除了输出层,预训练和微调时使用的是相同的模型结构。同一个预训练模型的参数可以用来初始化不同的下游任务的模型。在微调时,所有的参数都会被微调。[CLS]是一个特殊的符号,它会被添加在每个输入样本的前面,[SEP]是一个特殊的分隔符,它可以用来分隔不同的句子(例如问题/答案)。
简单地说,图1展示了BERT如何从大量的无标注文本中学习语言知识,然后再根据不同的任务进行微调。BERT使用了多层的Transformer编码器作为模型结构,它可以同时考虑左右两个方向的上下文信息。BERT还使用了两个预训练任务,分别是Masked Language Model(MLM)和Next Sentence Prediction(NSP),用于学习词汇和句子级别的表示。
- Masked Language Model(MLM)
MLM 是一种预训练任务,目的是让模型学习双向的语言表示。具体做法是,在一个句子中,随机地将一些词用 [MASK] 符号替换,然后让模型预测被替换的词是什么。这样,模型就需要利用上下文的信息来理解句子的含义。为了减少预训练和微调阶段的差异,MLM 还会有一定概率将被选中的词替换为一个随机词或 保持不变。
- Next Sentence Prediction(NSP)
NSP 是另一种预训练任务,目的是让模型学习两个句子之间的关系。具体做法是,给模型输入两个句子,然后让模型判断这两个句子是否是连续的。这样,模型就需要理解句子之间的逻辑和语义关联。NSP 有助于提升一些需要处理多句输入的下游任务,例如问答和自然语言推理。
通过这两个任务,BERT可以学习到通用的语言知识,然后通过在预训练模型的顶部添加少量的任务相关层,就可以适应不同的下游任务,例如问答、情感分析、命名实体识别、文本分类等。
在 BERT 的论文里介绍,BERT 也是用到了 SQuAD 数据集作为一个微调的示例,原本 BERT 里面的分类头,第一个 classification 是输出了 Next Sentence Prediction 的结果,也就是说,它给我们带来的是句子A和句子B是不是关联的上下文,在每一个句子里,又做一些 MLM 的任务,但是SQuAD 跟它这个头就不一样了,我们需要聚焦的是一个找答案的任务,这里最关键的是,你要给我几个分类器,在答案这块标记出来。所谓的微调 BERT 实际上就是微调输出头里面的参数,让它能够对具体问题给出具体的答案。
关于 BERT 的微调,存在两种可能性:
-
第一种可能性它只微调分类输出头,就是保持 Pre-training BERT 大量的参数都不变,因为微调不需要重新去训练那么多参数的大模型,也没有那么多的计算资源,也没有那么多时间,BERT 内部很多参数不用去关注,只需要聚焦于分类输出头。
-
另外一种可能性在微调的过程中把 BERT 整体的参数也进行微调,一般来讲不必这么做,因为对大多数的任务来说,微调分类输出已经够了。可是具体任务具体分析,有些情况下在任务比较复杂的时候,需要整体的去调整 BERT 本身,把原始 BERT 里的参数也进行调整,以适应我们新的需求。
具体怎么来选择,可以根据实际情况来进行尝试对比微调后的效果进行决策。
三、基于 Pytorch 微调 BERT 实现问答任务
在未经过任何训练之前的原始 BERT 理论上是无法来完成问答任务的,因为它只能完成两种任务,一种是 MLM,一种就是 NSP,它并没有经过问答任务的训练。如果要 BERT 支持问答任务,我们就要用SQuAD数据集去微调 BERT,然后再用微调后的 BERT 去完成一个问答任务。
3.1、Stanford QA Dataset
SQuAD(Stanford Question Answering Dataset)数据集是斯坦福大学发布的一个常用于问答任务的标准数据集,它是从维基百科里面抽取出来很多的问题和很多的答案,它每一个问题之后都接一个文本段,例如:
-
问题:What kind of animals are visible in Yellowstone?
-
文本段 (Context):Yellowstone National Park is home to a variety of animals. Some of the park's larger mammals include the grizzly bear, black bear, gray wolf, bison, elk, moose, mule deer, and white-tailed deer.
-
答案:grizzly bear, black bear, gray wolf, bison, elk, moose, mule deer, and white-tailed deer.
它的答案有一个特点,答案必须要包含在文本段里,所以它其实是一个抽取类型的任务,并不是让你重新组织问题的答案,而是你只要在这个文本段中找到答案词,就成功了。但是这个答案词呢,可能是一个词,也有可能是很多词的组合。简单来说,SQuAD数据集让你从一个大的文本里抽取出来几个相邻的文字来代表问题的答案。
3.2、数据集特征提取
将SQuAD 2.0数据集的训练示例转换为BERT模型的输入特征,并将这些特征保存到磁盘上,减少重复计算,后续直接加载数据集即可。
import pickle
from transformers.data.processors.squad import SquadV2Processor, squad_convert_examples_to_features
from transformers import BertTokenizer
# 初始化SQuAD Processor, 数据集, 和分词器
processor = SquadV2Processor()
train_examples = processor.get_train_examples('SQuAD')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
# 将SQuAD 2.0示例转换为BERT输入特征
train_features = squad_convert_examples_to_features(
examples=train_examples,
tokenizer=tokenizer,
max_seq_length=384,
doc_stride=128,
max_query_length=64,
is_training=True,
return_dataset=False,
threads=1
)
# 将特征保存到磁盘上
with open('SQuAD/training_features.pkl', 'wb') as f:
pick

BERT是一种由Google发布的预训练语言模型,基于Transformer编码器,擅长于理解句子的双向上下文。通过MaskedLanguageModel(MLM)和NextSentencePrediction(NSP)任务学习语言表示。微调BERT时,通常只调整输出层以适应特定任务,如问答、文本分类等。文章还介绍了如何在PyTorch中微调BERT实现问答任务和文本分类,以及如何加载和保存模型。




最低0.47元/天 解锁文章
645

被折叠的 条评论
为什么被折叠?



