五、ELMo
论文《Deep contextualized word representations》认为,高质量的词表征应该包含丰富的句法和语义信息,并且能够对多义词进行建模(传统的词向量如word2vec是上下文无关的)。ELMo 分为两个阶段:在大型语料库上预训练一个深度双向语言模型 biLM,然后将LM各层作为新特征补充到下游任务中。这个LM是预训练过的双向耦合 coupled LSTM,词向量是其内部状态的函数。深层LM能够捕获不同类型的上下文信息,其中语法信息在较低的层次上表现得更好--词性POS标注,而语义信息 word meaning/sense 在较高的层次上表现得更好--词义消歧,这与 MT encoder 是一致的。
模型的输入可以是单词 token,也可以是字符。给定N个 token 的序列 ,前向&后向LM计算序列的条件概率公式为:
假设输入 token 的表征 (通过 token embedding 或字符CNN得到)到L层 LSTM,在每个位置k,每个前向 LSTM 层输出一个 context-sensitive 表征 , j =1, ..., L。LSTM 顶层的输出 在通过一个 softmax 层后用于预测下一个 token 。
最大化前向&后向的对数似然,将前、后向 token embedding的参数 和 softmax 层的参数 绑定 tie 在一起,同时保持两个方向上 LSTM 参数的分离(在方向上共享了一些参数的权重,而不是像以前模型那样参数完全独立)。
对于每个 token ,一个L层的 biLM 需要计算 2L+1 个表征的集合:
其中 ,每个 biLSTM 层中 。为了被包含在下游模型中,ELMo 将R折叠成一个向量:
在最简单的情况下,ELMo 只选择LM最顶层
更一般地,计算所有 biLM 层的权重:
其中 是 softmax 归一化权重,标量 可用于整个 ELMo 向量的缩放。
为了将 ELMo 添加到有监督模型,首先冻结 biLM 的权重,然后将合并的向量 作为任务 RNN 的输入。对于有些任务(如SNLI, SQuAD),将 ELMo 向量同时包含在 RNN 的输出中 可以进一步提升效果。
biLM 的两个方向联合训练,为每个 token 提供3层表征 L=2,第一层是上下文无关的2048 字符 n-gram 卷积输入+2个 highway 层,再通过线性映射为512维;第二三层的 LSTM 有4096个单元512维度,使用适量的 dropout;从第一层到第二层添加残差连接;对loss添加 正则 ELMo 的权重,使得权重接近所有 biLM 层的平均值。
ELMo 对6个基准 NLP 任务均有提升
正则项中的λ值较大时如=1,会将权重降至各层的简单平均值;较小时如=0.001,对权重惩罚较小,大多数情况采用较小的λ。表2比较了3个任务分别使用基准模型、ELMo 最后一层、所有层以及不同λ的结果。表3表明对于 SQuAD、SNLI 等任务,在 biRNN 的输入和输出中都包含 ELMo 效果最好,一个可能的解释是它们在 biRNN 之后都使用了注意力层,所以在这个层引入ELMo 可以直接关注biLM的内部表征。而对于 SRL 来说,特定任务的上下文表征可能比来自 biLM 的表征更重要。
ELMo项目代码见 https://blog.csdn.net/sinat_26917383/article/details/81913790
六、OpenAI GPT
自然语言理解包括很多任务,如文本蕴含、问答、语义相似度和文档分类。虽然不带标记的语料库很丰富,但是对特定任务的标记数据很少,难以充分地训练监督模型,因此论文《Improving Language Understanding by Generative Pre-Training》提出使用半监督学习的方法,先在大语料库上无监督预训练模型,然后再针对特定任务使用有标记的数据进行微调。
1、无监督的预训练阶段
对于无监督的语料tokens ,k是上下文窗口的大小,Θ是神经网络的参数,最大化对数似然:
考虑到LSTM处理长序列效果不佳的情况,使用 multi-layer Transformer decoder 作为语言模型(实验模型结构参考《Generating Wikipedia by Summarizing Long Sequences》,是 local attention (L) 层 & memory-compressd attention (M) 层交替的5层网络 LMLML,还可以加入一个mixture of experts (MoE) 层(Shazeer et al.,2017 来增加网络的容量)。
MoE 层由 n 个 “expert networks” E1, ..., En 和一个门控网络G组成,输出 y 是一个稀疏的n维向量,与输入x维度相同,
虽然 expert 数量很多,但是只需计算其中 不等于0的一小部分。当 expert 数量特别大时,可以使用 two-level hierarchical MoE 来减少分支因素 branch factor。
回到 GPT 模型,其对输入上下文 tokens 使用 multi-head self-attention,后接 position-wise 前馈层,产生 tokens 的输出分布如下,其中 是 tokens 的上下文向量,n为层数, 是 token embedding 矩阵, 是位置嵌入矩阵。
2、有监督的微调阶段
对特定任务的有标记的数据集C,每句话由一系列输入 tokens 和对应标记y组成,输入预训练的模型获得最终 transformer 的激活值 ,然后经过一个参数为 的线性输出层得到y的预测值。
目标函数为:
作者发现将语言建模作为微调的辅助目标有助于监督模型的泛化,并加速收敛,λ为权重。
对于文本分类任务,可以直接微调模型,如前所述。
对于问题回答或文本蕴涵 等含有结构化输入的任务,由于预训练是在连续文本序列上进行的,因此需要使用遍历式 traversal-style 方法,将结构化输入转换为预训练模型可以处理的有序序列,同时这种输入转换可以避免任务对模型架构进行大的改动,转换包括添加随机初始化的开始和结束 tokens(,
对于文本蕴涵任务,将前提 premise 和假设 hypothesis 标记序列的中间使用分隔符 delimiter 标记 $ 连接起来。
对于文本相似度任务,需要进行比较的两个序列是没有顺序关系的,因此修改输入序列使其包含两种顺序(中间带有分隔符),分别经过 Transformer 后将两个序列的表征 对应元素相加,再输入到线性输出层。
对于QA和常识推理 Commonsense Reasoning 任务,给定一个上下文文档z、一个问题q和一组可能的答案 ,将文档和问题与每个可能的答案使用分隔符连接起来 ,将k种组合独立处理后通过 softmax 层输出答案的分布。
3、实验
论文模型预训练时包含很长的连续文本,使其能够根据长期的信息进行调整。与之相对的是使用 ELMo 作为 benchmark,训练时打乱句子顺序以破坏长期结构。
模型结构类似 Transformer,训练一个带有 masked self-attention heads(768维状态和12 heads)的12层 decoder-only transformer。使用内部状态3072维的 position-wise FFN。采用 Adam 优化器,其学习率在前2000次更新中从0线性增加到2.5e-4,之后余弦退火 cosine anneal 到0。每个 batch 含64个随机连续序列,每个序列有512个 tokens,训练100个 epoch。由于 LayerNorm 的广泛使用,初始化采用 N(0, 0.02)。使用字节对编码bytepair encoding BPE词表,其中包含40000个 merges 和残差、embedding。Attention dropout 率为0.1,并采用《Decoupled Weight Decay Regularization》中提出的修正L2正则,权重衰减为0.01。
def adam(params, grads, lr, schedule, t_total, b1=0.9, b2=0.999, e=1e-8, l2=0,
vector_l2=False, max_grad_norm=-1, **kwargs):
"""
adam with weight decay fix
"""
t = tf.Variable(0, dtype=tf.float32, trainable=False)
tt = t+1
updates = [t.assign(tt)]
if max_grad_norm > 0:
grads, _ = tf.clip_by_global_norm(grads, max_grad_norm)
for p, g in zip(params, grads):
if p is None or g is None:
print("can't train", p.name, g)
else:
if isinstance(g, tf.IndexedSlices):
g = tf.convert_to_tensor(g)
m = tf.Variable(p*0, dtype=tf.float32, trainable=False)
v = tf.Variable(p*0, dtype=tf.float32, trainable=False)
lrt = lr*tf.sqrt(1-b2**tt)/(1-b1**tt)
lrt *= schedule(t/t_total)
mt = b1*m + (1-b1)*g
vt = b2*v + (1-b2)*g*g
if (len(p.get_shape()) > 1 or vector_l2) and l2 > 0:
pt = p - lrt * (mt / (tf.sqrt(vt) + e) + l2*p)
else:
pt = p - lrt * (mt / (tf.sqrt(vt) + e))
updates.extend([m.assign(mt), v.assign(vt), p.assign(pt)])
return tf.group(*updates)
激活函数为 Gaussian Error Linear Unit:,约等于 或 。
对于 Position Embeddings,学习位置嵌入而不是使用原 Transformer 中的正弦公式版本。GPT 代码见 https://github.com/openai/finetune-transformer-lm
七、BERT
现有两种将预训练的表征应用于下游任务的策略:(1)feature-based 基于特征的方法:例如 ELMo,将经过独立训练的两个左右单向 LSTM 串联,把预训练表征附加到特定任务;(2)fine-tuning 微调的方法:例如 OpenAI GPT,使用从左到右的单向 Transformer,通过微调预训练参数来训练下游任务。
论文《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》认为以上两种单向/拼接单向模型严重限制了预训练表征的能力,因而提出了双向深度Transformer 编码器的语言模型 BERT。与 GPT、ELMo 不同,BERT 真正融合了左右的上下文,在所有层中都使用双向的 Transformer。代码见 https://github.com/google-research/bert
两个句子嵌入的测评工具
(1)SentEval(Facebook):An Evaluation Toolkit for Universal Sentence Representations https://github.com/facebookresearch/SentEval SentEval包括:
(2)GLUE(Google):General Language Understanding Evaluation https://gluebenchmark.com/ GLUE包括:
GLUE benchmark 包括下列数据集
单句任务
(1)CoLA:The Corpus of Linguistic Acceptability 二分类任务,用于预测一个英语句子在语义上是否是可接受的。
(2)SST-2:The Stanford Sentiment Treebank 二分类任务,用于电影评论的情感分析。
相似度和释义任务
(3)MRPC:Microsoft Research Paraphrase Corpus 由在线新闻源提取的句子对组成,人工标注其中的句子对在语义上是否等价。
(4)QQP:Quora Question Pairs 是一个二分类任务,目的是判断两个Quora上的问题是否表达的是一样的意思。
(5)STS-B:The Semantic Textual Similarity Benchmark 用1到5的分数来表示两句话在语义上的相似程度。
推理任务
(6)MNLI:Multi-Genre Natural Language Inference 是一个大规模众包蕴涵分类任务,给定一对句子,预测第二个句子相对于第一个句子是蕴涵 entailment、矛盾 contradiction 还是中性 neutral 的关系。
(7)QNLI:Question Natural Language Inference 是 SQuAD 的二分类任务版本,正例是包含正确答案的 (问题,句子) 对,负例是不包含答案的、来自同一段落的 (问题,句子)。
(8)RTE:Recognizing Textual Entailment 类似 MNLI,但是只是对蕴含关系的二分类判断,而且数据集更小。
(9)WNLI:Winograd NLI 是阅读理解任务,系统阅读一个带有代词的句子,并从选项列表中选择该代词的指代物。GLUE 指出这个数据集的构建存在一些问题,每个提训练过的系统性能都比预测大多数类的65.1基线精度差。
1、模型结构
BERT 模型使用多层双向 Transformer encoder,令层数 / Transformer 块表示为 L,隐状态大小为 H,self-attention head 个数为 A,将前馈网络 filter 大小设为4H,论文中主要报告了两种实验模型:
:L=12, H=768, A=12,参数总量 1.1亿
:L=24, H=1024, A=16,参数总量 3.4亿
为了便于对比, 与 OpenAI GPT 的模型大小相同。
2、输入表征
输入表征通过对相应 token、segment 和 position embeddings 来构造,如下图所示,具体是:
(1)Input:每个序列的第一个 token 始终是特殊的分类嵌入 [CLS],最终隐藏状态(即 Transformer 的输出)对应于这个 token 被用作分类任务的聚合序列表征 aggregate sequence representation。对于非分类任务,这个向量将被忽略。
(2)Token Embeddings:使用30,000个 tokens 的 WordPiece embeddings,用 # # 表示分割 word pieces。
(3)Segment Embeddings:句子对被打包成一个序列,使用特殊标记 [SEP] 或 将句子编号 A, B 等嵌入其内部每个 token 中。
(4)Position Embeddings:学习位置嵌入而不是使用公式,支持最长512个 tokens 的序列。
3、预训练任务
(1)Masked LM
标准的条件语言模型只能从左到右或从右到左进行训练,因为双向模型会使每个单词在多层上下文中间接地“窥探”到需要预测的词,从而将导致预测任务失去意义。
为了训练深度双向表示,受完形填空任务的启发,使用 MLM 随机遮盖一定比例的输入 token,然后仅预测那些被遮盖的 token。虽然这种方法可以训练双向模型,但是有两个缺点:
a. 预训练阶段使用 [MASK] token,而微调阶段没有 [MASK],二者不匹配 。为了解决这个问题,随机选择15%的 token,例如对句子 my dog is hairy 选择 hairy,然后对其中:
这样做的原因是如果句子中的某个 token 100%的时间都被 [MASK],那么在 fine-tuning 的时候模型就会有一些从未见过的单词。使用随机替换的原因是 Transformer 要保持对每个输入的分布式上下文表征,否则模型就会记住这个 [MASK] 就是 token ‘hairy’,随机替换会给模型增加一点噪声,但是因为此时模型不知道是哪个词被随机替换了,所以就迫使模型更好地学习每个词的词义。由于一个词被随机替换的概率只有15%*10%=1.5%,将不会损害模型的语言理解能力。
b. 由于每个 batch 中只预测15%的 token,所以模型收敛速度慢于从左到右的模型(预测每个 token),但是 MLM 模型对结果的改进将远远超过增加的训练成本。
(2)Next Sentence Prediction
为了使语言模型能够理解句子之间的关系,使用任意单语语料库预训练二值化 NSP,任务是判断句子B是否为句子A的下文。具体是,当为每个预训练示例选择句子A和B时,50%的时间B是A的下一个句子 IsNext,50%的时间B是语料库中的随机句子 NotNext。
4、预训练过程
预训练过程与现有的 LM 类似,使用文档级语料库 BooksCorpus (800M words) 和英语维基百科 (2,500M words) 以提取长的连续序列。生成输入序列时,从语料库中采样两个文本span A、B 作为“句子”,对它们采样后使得组合长度≤512。在 WordPiece tokenization 后使用15%的 MLM。训练 batch size 为256个序列(256 seqs* 512 tokens = 128,000 tokens / batch) 1,000,000步,在33亿个词的语料库训练大约40个 epoch。使用 Adam 优化器,学习率为1e-4,β1=0.9,β2=0.999,L2 weight decay = 0.01,学习率在前10,000步增大 warmup https://arxiv.org/pdf/1706.02677.pdf ,然后线性减小。所有层都使用0.1的 dropout。与 OpenAI GPT 相同,使用 GELU 激活函数。预训练时 MLM 和 NSP 是联合训练的,损失函数是平均 MLM 似然和平均 NSP 似然的总和。
5、微调阶段
在海量单语料库上训练完 BERT 之后,便可以将其应用到各种下游任务中了。下图展示了 BERT 在11个不同NLP任务中的模型,它们只需要在 BERT 的基础上再添加一个输出层便可以完成对特定任务的微调。其中Tok表示不同的 Token, E表示嵌入向量, Ti 表示第 i 个 Token 在经过 BERT 处理之后得到的特征向量。
对于 sequence-level 分类任务,BERT 微调很简单。为了获得输入序列的固定维度 pooled 表示,使用最终的隐藏状态 (即 Transformer 的输出)作为输入的第一个 token [CLS]。微调时唯一添加的参数是分类层权重矩阵 ,K为分类数量。使用softmax得到标签概率 ,。BERT 和W的所有参数都经过联合调整,以最大化正确标签的对数概率。对于 span-level 和 token-level 预测任务,需要稍微修改上述过程。
微调时大部分超参数与预训练相同,dropout 率始终为0.1,但 batch size,学习率和 epoch 数除外,作者提供了一些可能在所有任务中表现较好的超参数值:
• Batch size: 16, 32
• Learning rate (Adam): 5e-5, 3e-5, 2e-5
• Number of epochs: 3, 4
大数据集对超参数选择的敏感性远小于小数据集。微调的速度通常很快,因此可以简单地尝试上述所有超参数的组合,并选择在开发集上表现最佳的模型。
6、BERT 相对 GPT 的训练差异还有
(1)BERT 预训练的语料库比 GPT 多了 Wikipedia 的内容。
(2)GPT 只在微调时使用 [SEP] 和 [CLS];BERT 在预训练时学习 [SEP]、[CLS] 和 A/B segment 嵌入。
(3)GPT 使用 batch size 为32,000个字训练1M步;BERT 使用 batch size 为128,000个字训练1M步。
(4)GPT 在微调时使用的学习率均为5e-5;BERT 在微调使用特定于任务的学习率。
7、消融 Ablation Studies
即模型简化测试,去掉模型中部分模块,然后看模型性能是否发生变化。根据奥卡姆剃刀法则,如果简单和复杂的方法能达到一样的效果,那么简单的方法更可靠。Ablation Studies 就是为了研究模型中所提出的一些结构是否有效而设计的实验。
(1)预训练任务的影响
BERT 的核心主张之一是深度双向 MLM,作者实验了两个相同预训练数据、微调方案和 Transformer 超参数的 BERTBASE,其中:
a. 一个模型使用 MLM 训练,但不使用 NSP;
b. 另一个模型使用从左到右的单向 LTR LM,而不是 MLM,同样不使用 NSP。
实验结果表明,不使用 NSP 将严重影响 QNLI、MNLI 和 SQuAD 的性能。LTR 模型在所有任务上的性能都比MLM模型差,而如果为了改善结果将 LTR 与 RTL 拼接,则计算量加倍、且对QA任务不直观,比深度双向模型 less powerful -- 不能同时参考左侧或右侧的上下文。
(2)模型尺寸的影响
实验表明,更大的模型(#L, #H, #A)将显著提高模型的精度。
(3)训练步数的影响
与训练 BERTBASE 500k步相比,在训练1M步时 MNLI 的准确度提高了1.0%。这表明大量的预训练 128,000 words / batch * 1,000,000 steps 是很有必要的。
虽然 MLM 每批只预测15%的词,收敛速度慢于 LTR,但其精度从一开始就高于后者。
(4)基于特征的 BERT
基于特征的方法能够从预训练模型中提取固定特征,具有一定的优势。首先,并不是所有的NLP任务都可以很容易地用 Transformer encoder 结构表示,因此需要添加特定于任务的模型结构。其次,预先计算一次训练数据的 expensive representation,然后在此表示之上运行 less expensive 的实验,这是很 computational benefit 的。
为了验证 BERT 在基于特征的方法中的性能,在 CoNLL-2003 NER 任务中,生成类似于 ELMo 的预训练上下文表示。使用来自一个或多个层的激活,但不微调 BERT 的任何参数。这些上下文嵌入被用作分类层之前随机初始化的两层768维 biLSTM 的输入。结果表明 BERT 对于微调和基于特性的方法都是有效的。
八、Transformer-XL
论文《Transformer-XL:Attentive Language Models Beyond a Fixed-Length Context》 提出了一种超长 Transformer 的架构,能够在不破坏时间一致性的情况下学习不固定长度的依赖,并比原始 vanilla Transformer 显著提高了 evaluation 速度。
GitHub:https://github.com/kimiyoung/transformer-xl
模型将循环机制引入深度自注意力网络,不再从头计算每个新片段 segment 的隐藏状态,而是重复使用从之前的片段中获得的隐藏状态,这就在片段之间建立了循环连接,因此可以对超长期依赖进行建模,同时也解决了上下文碎片化的问题(context fragmentation:使用连续的符号块而不考虑句子或其他语义边界创建的固定长度片段,缺乏必要的上下文信息,不能很好的预测最初的几个符号,导致无效的优化和较差的性能)。设两个长度为 L 的连续片段分别为 和 ,第 个片段 产生的第 n 层隐藏状态序列为 ,产生片段 的公式如下所示,其中函数 SG(·) 表示 stop-gradient,[hu ◦ hv] 表示两个隐序列沿长度维度串联,与标准 Transformer 相比,关键区别在于 key 和 value 是根据扩展上下文 得到的,因此 是之前片段的缓存(图2 a中的绿色路径)。
(extended context)
(query, key, value vectors)
(self-attention + feed-forward)
将这种循环机制应用于语料库的每两个连续片段,即在隐藏状态中创建片段级循环,因此所使用的有效上下文可以超出两个片段的范围。但是注意到 和 之间的循环依赖关系会逐段下移一层,这与传统 RNN-LM 中的同层递归不同。因此,最大可能的依赖长度关于层数和片段长度线性增长(图2 b中的阴影区域),这类似于 truncated Back Propagation Trough Time BPTT,但与之不同的是,本文的方法缓存一系列隐藏状态而不是最后一个隐藏状态,并与相对位置编码技术一起使用。
模型对隐藏状态的相对位置而不是绝对位置进行编码,将 bias 信息注入注意力得分而不是静态地将其合并到初始嵌入中,这样可以在不造成时间混乱的情况下实现状态的重复使用。例如对于 query ,attends on key ,只需要知道二者的相对位置,如对于 来说就是 i - j。创建相对位置编码 ,其中第 i 行 表示 i 在两个位置之间的相对距离。
下面分别是标准 Transformer 和相对位置计算 和 之间的注意力分数公式,参数的不同之处有:
(1)替换(b)、(d)中所有 key 的绝对位置嵌入 为 , 是没有可学习参数的正弦曲线编码矩阵(见 Attention is all your need)。
(2)使用可训练参数 替换(c)中的 query ,由于 query 对于所有位置都相同的,因此对不同单词的 attentive bias 应保持相同。同样地,使用可训练参数 替换(d)中的 。
(3)将两个权重矩阵 和 分开,以分别生成基于内容的 key 和基于位置的 key。
使用新的参数后,每个 item 都具有直观含义:(a) 表示基于内容的地址 content-based addressing,(b) 捕获依赖于内容的位置偏差 a content-dependent positional bias,(c) 表示全局内容偏差,(d) 编码全局位置偏差。
N 层单头 Transformer-XL 的计算流程如下:
定义 为词嵌入序列,使用简单方法计算 A 时需要对所有 (i, j) 对计算 ,计算量为序列长度的平方。附录B介绍了一种可以将计算量降低到序列长度的方法,此处略过。
九、GPT-2
论文《Language Models are Unsupervised Multitask Learners》提出的 GPT-2 是 GPT 的升级版本,其最大的区别在于模型规模更大,训练数据更多,GPT 是12层的 Transformer,BERTLARGE 是24层的 Transformer,GPT-2 则为48层单向 Transformer,共有15亿个参数。训练数据是一个称为WebText的数据集,该数据集做了一些简单的数据清理,且覆盖领域十分广阔,论文中指出规模大的模型必须要用更多的数据才能收敛,并且实验结果表明目前模型仍然处于一个欠拟合的情况。在预训练阶段,GPT-2 采用了多任务的方式,每个任务都要保证其损失函数能收敛,不同的任务共享主体 Transformer 参数,该方案借鉴微软的 MT-DNN,这样能进一步的提升模型的泛化能力,因此即使在无监督 -- 没有微调的情况下依旧有非常不错的表现。
参考资料
https://www.cnblogs.com/robert-dlut/p/9824346.html
ELMo代码 https://blog.csdn.net/sinat_26917383/article/details/81913790
https://blog.csdn.net/pipisorry/article/details/84951508
https://blog.csdn.net/dQCFKyQDXYm3F8rB0/article/details/87484501
https://blog.csdn.net/u012526436/article/details/87882985