二、用于预训练BERT的数据集

动手学深度学习笔记5.整合代码 二、用于预训练BERT的数据集 三、预训练BERT
一、BERT
在和GloVe中,每个词都是由一个固定的预训练向量表示,而不考虑词的上下文 。这些词嵌入模型都是与上下文无关的,无法解决一词多义或复杂语义的问题 。
随后,ELMo( from) 通过两个LSTM进行双向建模,学习到了词的上下文,从而解决了一词多义的问题 。具体来说,ELMo将来自预训练的双向LSTM的所有中间层表示组合为输出表示,然后,ELMo的表示将作为附加特征添加到下游任务的有监督模型中,例如通过将ELMo的表示和现有模型中词元的原始表示(例如GloVe)连结起来 。一方面,在加入ELMo表示后,冻结了预训练的双向LSTM模型中的所有权重 。另一方面,现有的监督模型是专门为给定的任务定制的 。
尽管ELMo显著改进了各种自然语言处理任务的解决方案,但每个解决方案仍然依赖于一个特定于任务的架构 。然而,为每一个自然语言处理任务设计一个特定的架构实际上并不是一件容易的事 。
GPT( Pre )模型为上下文的敏感表示设计了通用的任务无关模型 。GPT建立在解码器的基础上,预训练了一个用于表示文本序列的语言模型 。当将GPT应用于下游任务时,语言模型的输出将被送到一个附加的线性输出层,以预测任务的标签 。与ELMo冻结预训练模型的参数不同,GPT在下游任务的监督学习过程中可以对预训练解码器中的所有参数进行微调 。
然而,由于语言模型的自回归特性,GPT只能向前看(从左到右) 。在“i went to the bank tocash”(我去银行存现金)和“i went to the bank to sit down”(我去河岸边坐下)的上下文中,由于“bank”对其左边的上下文敏感,GPT将返回“bank”的相同表示,尽管它有不同的含义 。
1.BERT:把两个结合起来
ELMo对上下文进行双向编码,但使用特定于任务的架构;而GPT是任务无关的,但是从左到右编码上下文 。BERT(来自的双向编码器表示)结合了这两个模型的优点 。它对上下文进行双向编码,并且对于大多数的NLP任务只需要少量的架构改变 。通过使用预训练的编码器,BERT能够基于其双向上下文表示任何词元 。在下游任务的监督学习过程中,BERT在两个方面与GPT相似 。首先,BERT表示将被输入到一个添加的输出层中,根据任务的性质对模型架构进行最小的更改,例如预测每个词元与预测整个序列 。其次,对预训练编码器的所有参数进行微调,而额外的输出层将从头开始训练 。
从上下文敏感的ELMo到任务不可知的GPT和BERT,它们都是在2018年提出的 。BERT刷新了11种NLP任务的技术水平 。
2.BERT的输入表示
在NLP中,有些任务(如情感分析)以单个文本作为输入,而有些任务(如自然语言推断)以一对文本序列作为输入 。当输入为单个文本时,BERT输入序列是特殊类别词元“”、文本序列的标记、以及特殊分隔词元“”的连结 。当输入为文本对时,BERT输入序列是“”、第一个文本序列的标记、“”、第二个文本序列标记、以及“”的连结 。
下面的函数将一个句子或两个句子作为输入,然后返回BERT输入序列的标记及其相应的片段索引 。
import torchfrom torch import nnfrom d2l import torch as d2ldef get_tokens_and_segments(tokens_a, tokens_b=None):"""获取输入序列的词元及其片段索引"""tokens = [''] + tokens_a + ['']# 0和1分别标记片段A和Bsegments = [0] * len(tokens)if tokens_b:tokens += tokens_b + ['']segments += [1] * (len(tokens_b) + 1)return tokens, segments
3.编码器
BERT以编码器作为其双向架构 。类与中实现的类相似 。不同的是,使用词元嵌入、片段嵌入和可学习的位置嵌入的和作为其输入序列的嵌入 。