TensorFlow 实战(八)
原文zh.annas-archive.org/md5/63f1015b3af62117a4a51b25a6d19428译者飞龙协议CC BY-NC-SA 4.0附录 C自然语言处理C.1 环游动物园遇见其他 Transformer 模型在第十三章我们讨论了一种强大的基于 Transformer 的模型称为 BERT双向编码器表示来自 Transformer。但 BERT 只是一波 Transformer 模型的开始。这些模型变得越来越强大更好要么通过解决 BERT 的理论问题要么重新设计模型的各个方面以实现更快更好的性能。让我们了解一些流行的模型看看它们与 BERT 的不同之处。C.1.1 生成式预训练GPT模型2018故事实际上甚至早于 BERT。OpenAI 在 Radford 等人的论文“通过生成式预训练改善语言理解”中引入了一个模型称为 GPTmng.bz/1oXV。它的训练方式类似于 BERT首先在大型文本语料库上进行预训练然后进行有区分性的任务微调。与 BERT 相比GPT 模型是一个Transformer 解码器。它们的区别在于GPT 模型具有从左到右或因果的注意力而 BERT 在计算自注意力输出时使用双向即从左到右和从右到左注意力。换句话说GPU 模型在计算给定单词的自注意力输出时只关注其左侧的单词。这与我们在第五章讨论的掩码注意力组件相同。因此GPT 也被称为自回归模型而 BERT 被称为自编码器。此外与 BERT 不同将 GPT 适应不同的任务如序列分类、标记分类或问题回答需要进行轻微的架构更改这很麻烦。GPT 有三个版本GPT-1、GPT-2 和 GPT-3每个模型都变得更大同时引入轻微的改进以提高性能。注意 OpenAITensorFlowgithub.com/openai/gpt-2。C.1.2 DistilBERT2019跟随 BERTDistilBERT 是由 Hugging Face 在 Sanh 等人的论文“DistilBERT, a distilled version of BERT: Smaller, faster, cheaper and lighter”arxiv.org/pdf/1910.01108v4.pdf中介绍的模型。DistilBERT 的主要焦点是在保持性能相似的情况下压缩 BERT。它是使用一种称为知识蒸馏mng.bz/qYV2的迁移学习技术进行训练的。其思想是有一个教师模型即 BERT和一个更小的模型即 DistilBERT试图模仿教师的输出。DistilBERT 模型相比于 BERT 更小只有 6 层而不是 BERT 的 12 层。DistilBERT 模型是以 BERT 的每一层的初始化为基础进行初始化的因为 DistilBERT 恰好有 BERT 层的一半。DistilBERT 的另一个关键区别是它只在掩码语言建模任务上进行训练而不是在下一个句子预测任务上进行训练。注意 Hugging Face 的 Transformershuggingface.co/transformers/model_doc/distilbert.xhtml。C.1.3 RoBERT/ToBERT2019RoBERT递归 BERT和 ToBERT基于 BERT 的 Transformer是由 Pappagari 等人在论文“Hierarchical Transformer Models for Long Document Classification”arxiv.org/pdf/1910.10781.pdf中介绍的两个模型。这篇论文解决的主要问题是 BERT 在长文本序列例如电话转录中的性能下降或无法处理。这是因为自注意力层对长度为 n 的序列具有 O(n²) 的计算复杂度。这些模型提出的解决方案是将长序列分解为长度为 k 的较小段有重叠并将每个段馈送到 BERT 以生成汇集输出即 [CLS] 标记的输出或来自任务特定分类层的后验概率。然后堆叠 BERT 为每个段返回的输出并将其传递给像 LSTMRoBERT或较小 TransformerToBERT这样的递归模型。注意 Hugging Face 的 Transformershuggingface.co/transformers/model_doc/roberta.xhtml。C.1.4 BART2019BART双向和自回归 Transformer由 Lewis 等人在“BART去噪序列到序列预训练用于自然语言生成、翻译和理解”arxiv.org/pdf/1910.13461.pdf中提出是一个序列到序列模型。我们在第 11 和 12 章中已经讨论了序列到序列模型BART 也借鉴了这些概念。BART 有一个编码器和一个解码器。如果你还记得第五章Transformer 模型也有一个编码器和一个解码器可以视为序列到序列模型。Transformer 的编码器具有双向注意力而 Transformer 的解码器具有从左到右的注意力即是自回归的。与原始 Transformer 模型不同BART 使用了几种创新的预训练技术文档重建来预训练模型。特别地BART 被训练成为一个去噪自编码器其中提供了一个有噪声的输入并且模型需要重建真实的输入。在这种情况下输入是一个文档一系列句子。这些文件使用表 C.1 中列出的方法进行损坏。表 C.1 文档损坏所采用的各种方法。真实文档为“I was hungry. I went to the café.”下划线字符_代表遮蔽标记。方法描述例子记号遮蔽句子中的记号随机遮蔽。我饿了。我去了 _ 咖啡馆。记号删除随机删除记号。我饿了。我去了咖啡馆。句子排列更改句子顺序。我去了咖啡馆。我饿了。文档旋转旋转文档以便文档的开头和结尾发生变化。咖啡馆。我饿了。我去了文本补齐使用单一遮蔽标记遮蔽跨度标记。一个长度为 0 的跨度将插入遮蔽标记。我饿了。我 _ 去了咖啡馆。使用损坏逻辑我们生成输入到 BART 的数据目标就是没有损坏的真实文档。初始时已经损坏的文档被输入到编码器然后解码器被要求递归地预测出真实的序列同时使用先前预测出的输出作为下一个输入。这类似于第十一章使用机器翻译模型预测翻译的方法。模型预训练后你可以将 BART 用于 Transformer 模型通常用于的任何 NLP 任务。例如可以按以下方式将 BART 用于序列分类任务例如情感分析把记号序列例如电影评论输入到编码器和解码器中。在给解码器输入时在序列末尾添加一个特殊记号例如[CLS]。我们在使用 BERT 时将特殊记号添加到序列开头。通过解码器得到特殊标记的隐藏表示结果并将其提供给下游分类器以预测最终输出例如积极/消极的预测结果。如果要将 BART 用于序列到序列的问题例如机器翻译请按照以下步骤进行将源序列输入编码器。向目标序列的开头和结尾分别添加起始标记例如[SOS]和结束标记例如[EOS]。在训练时使用除了最后一个标记以外的所有目标序列标记作为输入使用除了第一个标记以外的所有标记作为目标即teacher forcing来训练解码器。在推理时将起始标记提供给解码器作为第一个输入并递归地预测下一个输出同时将前一个输出件作为输入即自回归。注意 Hugging Face’s Transformers:mng.bz/7ygy。C.1.5 XLNet (2020)XLNet 是由杨飞等人在 2020 年初发布的论文 “XLNet: Generalized Autoregressive Pretraining for Language Understanding” 中推出的。它的主要重点是捕捉基于自编码器模型例如 BERT和自回归模型例如 GPT两种方法的优点这很重要。作为自编码器模型BERT 具有的一个关键优势是任务特定的分类头包含了由双向上下文丰富化的标记的隐藏表示。正如你所想像的那样了解给定标记之前和之后的内容能够得到更好的下游任务效果。相反地GPT 只关注给定单词的左侧来生成表示。因此GPT 的标记表示是次优的因为它们只关注左侧上下文的单向 注意力。另一方面BERT 的预训练方法涉及引入特殊标记 [MASK]。虽然这个标记出现在预训练的上下文中但它在微调的上下文中从未出现过造成了预训练和微调之间的差异。BERT 中存在一个更为关键的问题。BERT 假设掩盖标记是单独构建的即独立假设这在语言建模中是错误的。换句话说如果你有句子 “I love [MASK][1] [MASK][2] city”第二个掩盖标记是独立于 [MASK][1] 的选择而生成的。这是错误的因为要生成一个有效的城市名称必须在生成 [MASK][2] 之前先了解 [MASK][1] 的值。然而GPT 的自回归性质允许模型先预测 [MASK][1] 的值然后使用其与其左侧的其他单词一起生成城市的第一个单词的值然后生成第二个单词的值即上下文感知。XLNet 将这两种语言建模方法融合为一体因此你可以从 BERT 使用的方法中得到双向上下文以及从 GPT 的方法中得到上下文感知。这种新方法被称为置换语言建模。其思想如下。考虑一个长度为 T 的单词序列。对于该序列有 T!种排列方式。例如句子“Bob 爱猫”将有 3! 3 × 2 × 1 6 种排列方式Bob loves cats Bob cats loves loves Bob cats loves cats Bob cats Bob loves cats loves Bob如果用于学习的语言模型的参数在所有排列中共享我们不仅可以使用自回归方法来学习它还可以捕获给定单词的文本两侧的信息。这是论文中探讨的主要思想。注意 Hugging Face 的 Transformersmng.bz/mOl2。C.1.6 Albert2020Albert 是 BERT 模型的一种变体其性能与 BERT 相媲美但参数更少。Albert 做出了两项重要贡献减少模型大小和引入一种新的自监督损失有助于模型更好地捕捉语言。嵌入层的因式分解首先Albert 对 BERT 中使用的嵌入矩阵进行了因式分解。在 BERT 中嵌入是大小为 V × H 的度量其中 V 是词汇表大小H 是隐藏状态大小。换句话说嵌入大小即嵌入向量的长度与最终隐藏表示大小之间存在紧密耦合。然而嵌入例如 BERT 中的 WordPiece 嵌入并不是设计用来捕捉上下文的而隐藏状态是在考虑了标记及其上下文的情况下计算的。因此增大隐藏状态大小 H 是有意义的因为隐藏状态比嵌入更能捕获标记的信息性表示。但是由于存在紧密耦合这样做会增加嵌入矩阵的大小。因此Albert 建议对嵌入矩阵进行因式分解为两个矩阵V × E 和 E × H从而解耦嵌入大小和隐藏状态大小。通过这种设计可以增加隐藏状态大小同时保持嵌入大小较小。跨层参数共享跨层参数共享是 Albert 中引入的另一种减少参数空间的技术。由于 BERT 中的所有层以及 Transformer 模型一般从顶部到底部都具有统一的层参数共享是微不足道的。参数共享可以通过以下三种方式之一实现在所有自注意子层之间在所有完全连接的子层之间在自注意和完全连接的子层之间分开Albert 将跨层共享所有参数作为默认策略。通过使用这种策略Albert 实现了 71%到 86%的参数减少而不会显著影响模型的性能。句序预测而非下一句预测论文的作者最终认为BERT 中基于下一句预测的预训练任务所增加的价值是值得怀疑的这一点得到了多项先前研究的支持。因此他们提出了一种新的、更具挑战性的模型主要关注语言的一致性句子顺序预测。在这个模型中模型使用一个二元分类头来预测给定的一对句子是否是正确的顺序。数据可以很容易地生成正样本是按照顺序排列的相邻句子而负样本则是通过交换两个相邻句子生成的。作者认为这比基于下一句预测的任务更具挑战性导致比 BERT 更具见解的模型。备注 TFHub: (tfhub.dev/google/albert_base/3)。Hugging Face 的 Transformers: (mng.bz/5QM1)。C.1.7 Reformer (2020)Reformer 是最近加入 Transformer 家族的模型之一。Reformer 的主要思想是能够扩展到包含数万个标记的序列。Reformer 在 2020 年初由 Kitaev 等人在论文“Reformer: The Efficient Transformer”中提出arxiv.org/pdf/2001.04451.pdf。防止普通 Transformer 被用于长序列的主要限制是自注意力层的计算复杂性。它需要对每个词查看所有其他词以生成最终的表示这对含有 L 个标记的序列具有 O(L²) 的复杂性。Reformer 使用局部敏感哈希LSH将这种复杂性降低到 O(L logL)。LSH 的思想是为每个输入分配一个哈希具有相同哈希的输入被认为是相似的并被分配到同一个桶。这样相似的输入就会被放在同一个桶中。为此我们需要对自注意力子层进行若干修改。自注意力层中的局部敏感哈希首先我们需要确保 Q 和 K 矩阵是相同的。这是必要的因为其思想是计算查询和键之间的相似性。这可以通过共享 Q 和 K 的权重矩阵的权重来轻松实现。接下来需要开发一个哈希函数可以为给定的查询/键生成哈希使得相似的查询/键共享-qk获得相似的哈希值。同时需要记住这必须以可微的方式完成以确保模型的端到端训练。使用了以下哈希函数h(x)argmax([xR;-xR])其中R 是大小为[d_model, b/2]的随机矩阵用于用户定义的 b即桶的数量x 是形状为[b, L, d_model]的输入。通过使用这个散列函数您可以得到批处理中每个输入标记在给定位置的桶 ID。要了解更多关于这个技术的信息请参考原始论文“Practical and Optimal LSH for Angular Distance” by Andoni et al.arxiv.org/pdf/1509.02897.pdf。根据桶 ID共享的 qk 项被排序。然后排序后的共享的 qk 项使用固定的块大小进行分块。更大的块大小意味着更多的计算即会考虑更多单词来给定标记而较小的块大小可能意味着性能不佳即没有足够的标记可供查看。最后自注意力的计算如下。对于给定的标记查看它所在的相同块以及前一个块并关注这两个块中具有相同桶 ID 的单词。这将为输入中提供的所有标记产生自注意力输出。这样模型不必为每个标记查看每个其他单词可以专注于给定标记的子集单词或标记。这使得模型可伸缩到长达几万个标记的序列。注意 Hugging Face’s Transformers:mng.bz/6XaD。