CS224N(13)-词向量的上下文表征及预训练
Contextual Word Representations and Pretraining
一、Word Representations
在2018年之前,我们使用的词向量表征技术主要有三个:Word2Vec、Glove、FastText。但是这三个方法都普遍存在在一些问题,就是无法解决一次多义的问题,即对于同一个词无论上下文的单词是否相同,训练出来的词向量都是一样的。
通常我们训练词向量的时候,首先会初始化所有的词向量,并且在训练过程中不断地改变这些向量的值,需要注意的是训练的目标是我们自己定义的任务,而词向量仅仅是副产物而已。
当我们手中的语料不足时训练出来的词向量效果不会很理想,这是用通常会使用他人已经训练好的词向量,并且以预训练的词向量来作为初始值,在训练过程中冻结或者微调。
我们训练好的词向量是不可能涵盖所有词的(这里主要有两个原因,一是训练语料中本来就不存在这些词,二是这些词在训练语料中出现次数过少),这就会存在一个未登录词的问题,遇到这个问题的时候我们怎么处理呢?
首先,最简单和最普遍的解决方法就是将所有未登录的词映射为<UNK>,并且为它训练一个词向量。但是这种方法存在缺点,它把这些未登录词都视为相同,不能区分它们的区别。
为了解决上面的方法存在的问题,人们开始考虑训练字符集别的词向量。
除此之外还有一些其他的方法:
1.如果测试时的<unk>单词出现在未受监督的单词嵌入中,请使用测试时的向量。
2.对于其他单词,只需给它们分配一个随机向量,将它们添加到词汇表中即可。
3.将事物折叠成单词类(如未知数字、大写的事物等),并为每个类设置一个<unk class>
二、ELMO
下面我们来看下这个神经网络:
在一个NLM中,我们快速地通过LSTM层获得单词向量(可能只在语料库上训练)。这些LSTM层被训练来预测下一个单词。但是这些语言模型在每个位置都产生了上下文特定的单词表示!
下面来介绍一些经典的模型:
1、Peters et al. (2017): TagLM – “Pre-ELMo”
论文地址:https://arxiv.org/pdf/1705.00108.pdf
核心思想:通过上下文中获取单词的含义,但只在task-labeled的小任务(例如,NER)上使用RNN来进行训练。
算法的核心步骤如下:
1.预训练词向量和语言模型
2.在输入序列中准备好单词嵌入和语言模型嵌入。
3.在序列标记模型中同时使用单词嵌入和语言模型嵌入。
该模型结构图如下:
论文得出的结论如下:
1、通过对语言模型观察我们得出:使用有监督数据集来训练的语言模型效果甚微,使用双向语言模型仅对向前有利,网络结构越复杂效果越好。
2、通过对任务特定BILSTM观察可知:仅使用lm嵌入来预测并不好,仅在标签数据上使用bilstm进行标记
2、Also in the air: McCann et al. 2017: CoVe
论文地址:https://arxiv.org/pdf/1708.00107.pdf
网络结构示意图如下:
核心思想是使用经过训练的序列模型为其他NLP模型提供上下文。
使用两层的LSTM来为seq2seq+attention编码器的提供双下文
结果:产生的COVE向量在各种任务上都优于Glove向量。
但是,结果并不像其他幻灯片中描述的简单NLM那样强大,因此最后被舍弃。
3、Peters et al. (2018): ELMo: Embeddings from Language
Models
ELMO是第一个使用双向语言模型来获得词向量的方法。
论文名称及地址:
Deep contextualized word representations. NAACL 2018.
https://arxiv.org/abs/1802.05365
网络结构图:
ELMO是词向量或上下文词向量的突破性算法:它使用长上下文而非上下文窗口学习词向量(此处,整个句子可能更长),使用双向的深层NLM进行训练并使用其所有层进行预测。
我们来简要介绍下这个模型:首先,它训练了一个双向的语言模型,其次,其性能很好并且模型不大:使用2个bilstm层,使用字符级的CNN建立初始单词表示(2048 char n-gram过滤器和2个HighWay层,512 dim投影),使用4096 dim hidden/cell lstm状态,512dim投影到下一个输入,使用残差链接,连接token输入和输出(SoftMax)的参数,并将这些参数连接在正向和反向语言模型之间。
ELMO用于学习特定任务的双向语言模型表示的组合,这是首次仅使用LSTM堆栈顶层的模型,ELMO的任务可以简单表示为:
:根据任务衡量ELMO的总体效用;
:Softmax归一化混合物模型权重
在使用双向语言模型获得词向量后,我们在下游任务中使用词向量时,冻结有监督模型中的ELMO部分,并且将EMLO的权重根据不同的任务来连接不同的模型中。
模型中的两个bilstm nlm层具有不同的用途/含义,
1、较低层学习的是较低级别的语法等。
2、高层次学习的是语义。
三、ULMfit
论文名称及地址:
Howard and Ruder (2018) Universal Language Model Fine-tuning for Text Classification.
https://arxiv.org/pdf/1801.06146.pdf
ULMfit主要是使用迁移学习来进行文本分类:
迁移学习示意图:
算法的核心思想:
1.在大的通用域语料库上训练语言模型
2.在目标任务数据上调整语言模型
3.作为目标任务的分类器进行微调
模型结构图如下:
UMLfit使用大小合理的“1-gpu”语言模型,由于是利用别人预训练好的模型进行迁移学习,因此模型通常不大。
在语言模型微调过程中非常小心,每层采用不同的学习率,即倾斜三角形学习率(STLR)策略,开始学习率逐渐增大大,后面逐渐变小。
在学习分类器时逐步解冻并且采用STLR策略,分类时使用串联的方法
近年预训练语言模型发展历程:
四、transformer:
transformer的出现主要是为了利用纯attention来解决RNN系列网络无法并行的问题。
transformer网络概况:
我们从图中可以看到:它是一个没有使用循环神经网络的Seq2Seq编码器解码器模型。最初应用于使用并行语料库进行机器翻译并预测每个单词的翻译。
最终的成本/误差函数是SoftMax分类器顶部的标准交叉熵误差。
如果我们要详细地了解transformer,可以参考下面地资源:
http://nlp.seas.harvard.edu/2018/04/03/attention.html
这是一个使用pytorch在jupyter notebook上来解释transformer的教程。
接下来我们首先了解transformer中的attention部分。
1、attention:
inputs:一个查询q和一组键值(k-v)对。
Query, keys, values, and output都是向量。
输出是值的加权和,其中每个值的权重由查询的内部乘积和相应的键计算,查询和键具有相同的维数。
输出公式如下:
当我们遇到多个查询时,我们将它们使用堆栈的方法组成矩阵Q,那么上面这个公式就变为如下形式:
但是这个公式存在一个缺点:
因此这里进行了一个缩放处理:
示意图如下:
2、self-attention
接下来介绍一下self-attention,self-attention有什么特点呢?
1.输入词向量是查询、键和值。
2.词向量本身相互进行选择。
3.字向量stack=Q=K=V
1.Encoder self-attention
2.Decoder self-attention
缺点在于只有一种词的相互作用方式,下面我们来介绍一下Multi-head attention
3、Multi-head attention
其大概步骤如下:
1.首先通过W矩阵将q,k,v映射到h=8的低维空间
2.然后连接输出并通过线性层传输
其计算公式如下:
示意图如下:
与CNN和传统的Attention相比,Multi-head attention还是有很多特性的。
下面以这句话为例子:
The cat stuck out its tongue and licked its owner
当使用CNN处理这段话时,体现的是相对位置的不同线性变换,其示意图如下:
当使用普通的Attention时,体现的是权重的平均:
当使用Multi-Attention时,在输入和输出上具有不同线性变换的并行行Attention层:
4、transformer block
1.encoder
encoder结构部分的示意图如下:
在transformer中,每个块有两层,每层由一个Multihead attention和一个两层的采用ReLU激活函数的前馈神经网络组成。
其结构可以由下图表示:
这两个步骤中的每一个还具有:
Residual (short-circuit) connection 和 LayerNorm
LayerNorm(x + Sublayer(x))
layerNorm将输入更改为每个层和每个训练点的平均值0和方差1(并添加两个以上参数),公式表示如下:
在transformer中,encoder部分的每个块(共6个)中, Q=K=V且Q、K、V都来自上一层。并且实际上词向量的表示是字节对编码,除此之外,还添加了位置编码,因此不同位置的相同单词具有不同的整体表示。
positional encoding的计算公式如下:
2.decoder
结构示意图如下:
相对于encoder部分decoder对子层进行了一定的更改,
1.使用self-attention对先前生成的输出进行masked decoder
2.Encoder-Decoder Attention,查询来自前一个解码器层,键和值来自编码器的输出。
transformer的相关细节如下:
1.字节对编码
2.检查点平均
3.学习率变化的Adam优化器
4.在每一层训练过程中仅在在添加参擦连接之前使用dropout
5.标签平滑
6.使用带有beam search和长度惩罚的自动回归解码
五、BERT: Devlin, Chang, Lee, Toutanova (2018)
BERT (Bidirectional Encoder Representations from Transformers):
Pre-training of Deep Bidirectional Transformers for Language
Understanding
ELMO、GPT、BERT结构对比图:
BERT主要解决的是传统语言模型只使用左上下文或右上下文,但语言理解是双向的这一问题。图例如下:
BERT在工程上采用的技巧是:
1.在训练过程中随机mask掉15%的token,而不是把像cbow一样把每个词都预测一遍。最终的损失函数只计算被mask掉那个token。
Mask如何做也是有技巧的,如果一直用标记[MASK]代替(在实际预测时是碰不到这个标记的)会影响模型,所以随机mask的时候10%的单词会被替代成其他单词,10%的单词不替换,剩下80%才被替换为MASK。要注意的是Masked LM预训练阶段模型是不知道真正被mask的是哪个词,所以模型每个词都要关注。
2.在为了训练一个理解句子的模型关系,预先训练一个二进制化的下一句测任务,这一任务可以从任何单语语料库中生成。具体地说,当选择句子A和B作为预训练样本时,B有50%的可能是A的下一个句子,也有50%的可能是来自语料库的随机句子。
BERT sentence pair encoding
BERT中每个输入向量由下面几个组成:
token嵌入是单词片段
学习分段嵌入来表示每个句子
位置嵌入与其他Transformer架构是一样的
BERT model fine tuning
使用BERT训练好模型以后,我们在下游任务中使用它的时候,只需要根据当前的任务对它进行微调即可。
transformer在图形和语音方面的应用
1.transformer在图像方面的应用
总体结构图如下:
image transformer layer:
2.transformer在语音方面的应用
在语言方面,采用的是Multihead Attention和convolution的组合结构relative attention,对于一段音频来说可得到下面的表示:
传统anttention观察的部分:
relative anttention观察的部分: