1、什么是预训练模型?
预训练语言模型最早是在论文《 Dai & Le,2015,Semi-supervised Sequence Learning》 中提出的。起初在视觉领域使用的很多。后来,慢慢地也广泛应用于NLP任务当中。
1.1有什么好处?
使用预训练模型大大提升了在相关任务上的效果,同时降低了训练的难度。
无需从头开始构建模型来解决类似的问题,尽管需要进行一些微调,但节省了大量的时间和计算资源。
首先,在一个原始任务上预先训练一个初始模型,然后在目标任务上使用该模型,针对目标任务的特性,对该初始模型进行精调,从而达到提高目标任务的目的。在本质上,这是一种迁移学习的方法,在自己的目标任务上使用别人训练好的模型。对于文本语言来说,是有天然的标注特征的存在的,原因就在于文本可以根据之前的输入词语进行预测,而且文本大多是有很多词语,所以就可以构成很大的预训练数据,进而可以自监督(不是无监督,因为词语学习过程是依据之前词语的输出的,所以应该是自监督学习)的预训练。
对于nlp的下游任务,尽管它们的最终目标各不相同,但是它们也有着共同的、也是必须首先要做的东西,那就是要让模型理解文档中的单词和句子,具体说就是将文本中的无法直接计算的单词转变为可以计算的向量或者矩阵等形式,并且这些数字化的向量要能够比较好地反映出对应单词在句子中的含义,这就nlp中预训练的目的。
1.2 为什么可行?
通常而言,预训练好的网络参数,尤其是底层的网络参数,若抽取出特征跟具体任务越无关,越具备任务的通用性,所以这是为何一般用底层预训练好的参数初始化新任务网络参数的原因。而高层特征跟任务关联较大,实际可以不用使用,或者采用Fine-tuning用新数据集合清洗掉高层无关的特征抽取器。
从现在的大趋势来看,使用某种模型预训练一个语言模型看起来是一种比较靠谱的方法。从之前AI2的 ELMo,到 OpenAI的fine-tune transformer,再到Google的这个BERT,全都是对预训练的语言模型的应用。
2、预训练模型的三个关键技术
2.1、第一个关键技术是 Transformer
它在 NLP 各个任务中都取得了优异的性能,它是预训练语言模型的核心网络。给定一句话或是一个段落作为输入,首先将输入序列中各个词转换为其对应的词向量,同时加上每一个词的位置向量,体现词在序列的位置。然后将这些词向量输入到多层 Transformer 网络中,通过自注意力(self-attention)机制来学习词与词之间的关系,编码其上下文信息,再通过一个前馈网络经过非线性变化,输出综合了上下文特征的各个词的向量表示。每一层 Transformer 网络主要由 Multi-head self-attention 层(多头自注意力机制)和前馈网络层两个子层构成。Multi-head self-attention 会并行地执行多个不同参数的 self-attention,并将各个 self-attention 的结果拼接作为后续网络的输入,self-attention 机制会在后面中做详细介绍。此后,我们得到了蕴含当前上下文信息的各个词的表示,然后网络会将其输入到前馈网络层以计算非线性层次的特征。在每一层 Transformer 网络中,会将残差连接(residual connection)把自注意力机制前或者前馈神经网络之前的向量引入进来,以增强自注意力机制或者前馈网络的输出结果向量。并且还做一个 layer normalization,也就是通过归一化把同层的各个节点的多维向量映射到一个区间里面,这样各层节点的向量在一个区间里面。这两个操作加入在每个子层后,可更加平滑地训练深层次网络。Transformer 可以用于编码,也可以用于解码。所谓解码就是根据一个句子的输入得到一个预想的结果,比如机器翻译(输入源语言句子,输出目标语言句子),或者阅读理解(输入文档和问题,输出答案)。解码时,已经解码出来的词要做一个自注意力机制,之后和编码得到的隐状态的序列再做一个注意力机制。这样可以做 N 层,然后通过一个线性层映射到词表的大小的一个向量。每个向量代表一个词表词的输出可能性,经过一个softmax 层得到每个词的输出概率。接下来介绍一下 self-attention 机制,以一个 head 作为示例。假定当前输入包含三个词,给定其输入词向量或是其上一层 Transformer 网络的输出,将其通过三组线性变换,转换得到三组 queries、keys 和 values 向量。Query 和 key 向量用来计算两两词之间的得分,也就是其依赖关系,这个得分会同其对应的 value 向量做加权和,以得到每个词综合上下文信息的表示。给定当前第一个词的 query 向量,其首先同各个词的 key 向量通过点积操作得到这两个词的得分,这些得分用来表示这两个词的依赖或是相关程度。这些得分之后会根据 query 等向量的维度做一定比例的缩放,并将这些得分通过 softmax 操作做归一化。之后,各个得分会同其相对应的 value 向量相乘得到针对第一个词加权的各个 value 向量,这些加权的 value 向量最终相加以得到当前第一个词的上下文表示。在得到第一个词的上下文表示后,给定第二个词的 query 向量,我们会重复之前的操作,计算当前 query 向量同各个词 key 向量的得分,对这些得分做 softmax 归一化处理,并将这些得分同其对应的 value 向量做加权和,以得到其编码上下文信息的表示。
2.2、第二个关键技术是自监督学习
在预训练的模型中,AR(自回归)LM 和 AE(自动编码器)是最常用的自监督学习方法,其中,自回归 LM 旨在利用前面的词序列预测下个词的出现概率(语言模型)。自动编码器旨在对损坏的输入句子,比如遮掩了句子某个词、或者打乱了词序等,重建原始数据。通过这些自监督学习手段来学习单词的上下文相关表示。
2.2.1、自回归
根据上文内容预测下一个可能跟随的单词,就是常说的自左向右的语言模型任务,或者反过来也行,就是根据下文预测前面的单词,这种类型的LM被称为自回归语言模型。(GPT,ELMO)GPT 就是典型的自回归语言模型。ELMO尽管看上去利用了上文,也利用了下文,但是本质上仍然是自回归LM,这个跟模型具体怎么实现有关系。ELMO是做了两个方向(从左到右以及从右到左两个方向的语言模型),但是是分别有两个方向的自回归LM,然后把LSTM的两个方向的隐节点状态拼接到一起,来体现双向语言模型这个事情的。所以其实是两个自回归语言模型的拼接,本质上仍然是自回归语言模型。
自回归语言模型有优点有缺点,缺点是只能利用上文或者下文的信息,不能同时利用上文和下文的信息,当然,貌似ELMO这种双向都做,然后拼接看上去能够解决这个问题,因为融合模式过于简单,所以效果其实并不是太好。它的优点,其实跟下游NLP任务有关,比如生成类NLP任务,比如文本摘要,机器翻译等,在实际生成内容的时候,就是从左向右的,自回归语言模型天然匹配这个过程。而Bert这种DAE模式,在生成类NLP任务中,就面临训练过程和应用过程不一致的问题,导致生成类的NLP任务到目前为止都做不太好。
2.2.3、自编码
自回归语言模型只能根据上文预测下一个单词,或者反过来,只能根据下文预测前面一个单词。相比而言,Bert通过在输入X中随机Mask掉一部分单词,然后预训练过程的主要任务之一是根据上下文单词来预测这些被Mask掉的单词,如果你对Denoising Autoencoder比较熟悉的话,会看出,这确实是典型的DAE的思路。那些被Mask掉的单词就是在输入侧加入的所谓噪音。类似Bert这种预训练模式,被称为DAE LM。
这种DAE LM的优缺点正好和自回归LM反过来,它能比较自然地融入双向语言模型,同时看到被预测单词的上文和下文,这是好处。缺点是啥呢?主要在输入侧引入[Mask]标记,导致预训练阶段和Fine-tuning阶段不一致的问题,因为Fine-tuning阶段是看不到[Mask]标记的。DAE吗,就要引入噪音,[Mask] 标记就是引入噪音的手段,这个正常。
XLNet的出发点就是:能否融合自回归LM和DAE LM两者的优点。就是说如果站在自回归LM的角度,如何引入和双向语言模型等价的效果;如果站在DAE LM的角度看,它本身是融入双向语言模型的,如何抛掉表面的那个[Mask]标记,让预训练和Fine-tuning保持一致。当然,XLNet还讲到了一个Bert被Mask单词之间相互独立的问题。
2.3、第三个关键技术就是微调
在做具体任务时,微调旨在利用其标注样本对预训练网络的参数进行调整。以我们使用基于 BERT(一种流行的预训练模型)为例来判断两个句子是否语义相同。输入是两个句子,经过 BERT 得到每个句子的对应编码表示,我们可以简单地用预训练模型的第一个隐节点预测分类标记判断两个句子是同义句子的概率,同时需要额外加一个线性层和 softmax 计算得到分类标签的分布。预测损失可以反传给 BERT 再对网络进行微调。当然也可以针对具体任务设计一个新网络,把预训练的结果作为其输入。
3、策略
目前主要有两种预训练语言模型用于下游任务的方法:feature-based(以ELMo为例)和fine-tuning(以BERT为例)
Feature-based
指使用预训练语言模型训练出的词向量作为特征,输入到下游目标任务中。
Fine-tuning
指在已经训练好的语言模型的基础上,加入少量的 task-specific parameters【只改变较少的任务相关的层与参数】,然后在新的语料上重新训练来进行微调【直接对下游任务训练整个原来的语言模型??能说清楚具体是什么样的操作吗?】。
4、预训练模型分类
应用场景将预训练模型分为三类:
4.1、多用途NLP模型
多用途模型在NLP领域里一直为人们所关注。这些模型为提供了许多令人感兴趣的NLP应用 - 机器翻译、问答系统、聊天机器人、情感分析等。这些多用途NLP模型的核心是语言建模的理念。
简单来说,语言模型的目的是预测语句序列中的下一个单词或字符,在我们了解各模型时就会明白这一点。
ULMFiT
使用ULMFiT模型和Python 的fastai库进行文本分类(NLP)教程
https://www.analyticsvidhya.com/blog/2018/11/tutorial-text-classification-ulmfit-fastai-library/?utm_source=blog&utm_medium=top-pretrained-models-nlp-article
ULMFiT的预训练模型论文
https://www.paperswithcode.com/paper/universal-language-model-fine-tuning-for-text
其他研究论文
https://arxiv.org/abs/1801.06146
Transformer
谷歌官方博文
https://ai.googleblog.com/2017/08/transformer-novel-neural-network.html
Transformer预训练模型论文《Attention Is All You Need》
https://www.paperswithcode.com/paper/attention-is-all-you-need
其他研究论文
https://arxiv.org/abs/1706.03762
BERT(Google)
谷歌官方博文
https://ai.googleblog.com/2018/11/open-sourcing-bert-state-of-art-pre.html
BERT预训练模型论文
https://www.paperswithcode.com/paper/bert-pre-training-of-deep-bidirectional#code
其他研究论文
https://arxiv.org/pdf/1810.04805.pdf
Transformer-XL
谷歌的官方博客文章
https://ai.googleblog.com/2019/01/transformer-xl-unleashing-potential-of.html
Transformer-XL的预训练模型
https://www.paperswithcode.com/paper/transformer-xl-attentive-language-models
研究论文
https://arxiv.org/abs/1901.02860
GPT-2(OpenAI)
OpenAI的官方博客文章
https://openai.com/blog/better-language-models/
GPT-2的预训练模型
https://github.com/openai/gpt-2
研究论文
https://d4mucfpksywv.cloudfront.net/better-language-models/language-models.pdf
4.2、词嵌入NLP模型
使用的大多数机器学习和深度学习算法都无法直接处理字符串和纯文本。这些技术要求将文本数据转换为数字,然后才能执行任务(例如回归或分类)。
因此简单来说, 词嵌入(word embedding)是文本块,这些文本块被转换成数字以用于执行NLP任务。词嵌入(word embedding)格式通常尝试使用字典将单词映射到向量。
对词嵌入的直观理解:从计算向量到Word2Vec
ELMo
循序渐进的NLP指南,了解ELMo从文本中提取特征
https://www.analyticsvidhya.com/blog/2019/03/learn-to-use-elmo-to-extract-features-from-text/?utm_source=blog&utm_medium=top-pretrained-models-nlp-article
预训练模型的GitHub存储库
https://github.com/allenai/allennlp/blob/master/tutorials/how_to/elmo.md
研究论文
https://arxiv.org/pdf/1802.05365.pdf
Flair
Flair不是一个词嵌入(word embedding),而是它的组合。我们可以将Flair称为结合了GloVe、BERT与ELMo等嵌入方式的NLP库。Zalando Research的优秀员工已经开发了开源的Flair。
Flair的预训练模型
https://github.com/zalandoresearch/flair
4.3、其他预训练模型
StanfordNLP
提到扩展NLP使其不局限于英语,这里有一个已经实现该目的的库——StanfordNLP。其作者声称StanfordNLP支持超过53种语言。
StanfordNLP是一系列经过预先训练的最先进的NLP模型的集合。这些模型不仅是在实验室里进行测试——作者在2017年和2018年的CoNLL竞赛中都使用了这些模型。在StanfordNLP中打包的所有预训练NLP模型都是基于PyTorch构建的,可以在你自己的注释数据上进行训练和评估。
StanfordNLP的预训练模型
https://github.com/stanfordnlp/stanfordnlp
拓展:
自监督学习:https://blog.csdn.net/sdu_hao/article/details/104515917