2019年8月份参加达观杯信息抽取比赛时,研究过ELMO并取得第100名的成绩,最近又读到了ELMO的文章,对ELMO详细的回顾了一下并做个总结。
1.什么是ELMO
ELMO是"Embedding from Language Model"的简称,直接参考的论文是《Deep Contextualized Word Representation》。在ELMO之前,word embedding 本质上是静态的表示方式,也就是在词向量训练之后每个单词的表达就固定住了,这个单词的word embedding 不会随着上下文场景的变化而改变。缺点就是对于多义词(如英文中的Bank),在不同语言场景下表达的是同一个word embedding,这是不应该的。
ELMO的本质思想是,事先用语言模型学好一个单词的word embedding,此时多义词的word embedding是同一个表达,在句子中使用一个单词的word embedding时,此时单词已经具备了特定的上下文了,这时使用单词的上下文语义去调整单词的word embedding表示,这样经过调整后的word embedding更能表达在这个上下文中的具体含义,自然也就解决了多义词的问题。本质上ELMO是根据上下文动态调整word embedding。
2.ELMO的基本原理
ELMO采用了典型的两阶段过程:
- 第一个阶段是利用语言模型进行预训练---训练word embedding表达
- 第二个阶段是在做下游任务时,从预训练网络中提取出对应单词的网络各层的word embedding做为新特征补充到下游任务中
2.1 第一阶段:利用语言模型进行预训练
第一阶段模型总览(图片参考知乎张俊林老师的文章,《从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史》):
上图展示的是其预训练过程,它的网络结构采用双层双向LSTM,其中单词(token)特征这一块采用的是单词的embedding或者采用字符卷积得到其embedding表示(论文原文:via token embeddings or a CNN over characters)。
目前语言模型训练的任务目标是根据单词的上下文去正确预测单词
,
之前的单词序列Context-before称为上文,之后的单词序列Context-after称为下文。
上图中左端的前向双层LSTM代表正方向编码器,输入的是从左到右顺序的除了预测单词外的上文Context-before;右端的逆向双层LSTM代表反方向编码器,输入的是从右到左的逆序的句子下文Context-after;每个编码器的深度都是两层LSTM叠加。
注意:上述残差结构是在训练深层LSTM网络时常用的结构,简单做法是将LSTM层的输入加到输出上。
使用这个网络结构利用大量语料做语言模型任务就能预先训练好这个网络,如果训练好这个网络后,输入一个新句子,句子中每个单词都能得到对应的三个Embedding:
- 最底层是单词的word embedding
- 往上走第一层是双向LSTM对应单词位置的embedding,这层编码单词的句法信息更多些
- 再往上走是第二层LSTM中对应单词位置的embedding,这层编码单词的语义信息更多一些
也就是说,ELMO的预训练过程不仅学会单词的word embedding,还学会了一个双层双向的LSTM网络结构,而这两者后面都有用。
2.2 第二阶段:下游任务利用预训练好的embedding
第二阶段模型总览(图片参考知乎张俊林老师的文章,《从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史》):
以QA问题为例,展示下游任务如何利用预训练好的embedding:
- 对于问句X,我们可以先将句子X作为预训练好的ELMO网络的输入,这样句子X中每个单在ELMO网络中都能获得对应的三个embedding;
- 之后给予这个embedding中的每一个embedding一个权重a,这个权重可以学习得来,根据各自权重累加求和,将三个embedding整合成一个;
- 然后将整合后的这个embedding作为X句在自己任务的那个网络结构中对应单词的输入,以此作为补充的新特征给下游任务使用。
对于上图所示下游任务QA中的回答句子Y来说也是如此处理。因为ELMO给下游提供的是每个单词的特征形式,所以这一类预训练的方法被称为"Feature-based Pre-Training"。
3.ELMO的训练过程以及损失函数
ELMO的训练过程实际上指的是其第一阶段的预训练过程,第一阶段实际上就是在训练一个双向语言模型,假设给定一个序列,该序列含有N个token(),那么:
3.1 前向语言模型
前向语言模型通过在给定上文()(Context-before)的情况下对token
的概率建模来计算序列出现的概率:
- 许多主流的神经语言模型都会先给序列中的token计算一个上下文无关的token表示
,然后将它传递给L层前向LSTM。这样的话,在每个位置k,每个LSTM层输出一个上下文相关的表示
,其中
(在ELMO中L取2)
3.2 后向语言模型
后向语言模型与前向类似,但是它是“从后往前建模的”,通过在给定下文( )(Context-after)的情况下对token
的概率建模来计算序列出现的概率:
- 与前向语言模型类似,后向语言模型在每个位置
,每个LSTM层同样会输出一个上下文相关表示
,其中
- 注意:上述上下文无关的token表示
是前后向语言模型共享的
因此,由于ELMO结合了前后向语言模型,故其目标是同时最大化前后向语言模型的对数似然:
其中,
为token表示的参数(前后向语言模型共享)
为softmax分类的参数(前后向语言模型共享)
,
分别表示前后向语言模型LSTM层的参数
综上所述,ELMO的训练过程即为一个前后项语言模型的训练过程,通过上述则一目了然,而其损失函数即为简单的分类损失,取决于源码实现,不同源码中的实现略有不同。
4.ELMO预训练完成之后的使用
ELMO训练好之后,对于输入的句子序列中的每个token,一个L层(这里L取2)的双向语言模型就会得到 2L+1个表示,即为:
其中,为token的表示(即
),
为每个双向LSTM层得到的表示。
注意:这里是将整个句子输入到双向语言模型中(双向LSTM网络结构),正向和反向LSTM网络共享token embedding 的输入,源码中token embedding、正向、反向LSTM的hidden state均为512维度,一个长度为n_sentences的句子,经过ELMO预训练网络,最后得到的embedding维度为:(n_sentences,3,max_sentence_length,1024)
下游任务将所有的表示都利用起来,并给他们分配权重,即为:
其中,是经过softmax归一化之后的权重,标量参数
允许任务模型缩放整个ELMO向量。需要注意的是,
是一个超参数,实际上这个参数是经验参数,一定程度上能够增强模型的灵活性。总结起来整个为下游任务获取embedding的过程即为:
5.ELMO的优点
ELMo利用了深度上下文单词表征,该模型的优点:
- 引入双向语言模型,其实是 2 个单向语言模型(前向和后向)的集成
- 通过保存预训练好的 2 层 biLSTM,通过特征集成或 finetune 应用于下游任务
总结来说,通过上述结构,ELMo能够达到区分多义词的效果,每个单词(token)不再是只有一个上下文无关的embedding表示。
那么ELMo为什么有效呢?我认为主要原因有以下几点:
- 首先,ELMo的假设前提是一个词的词向量不应该是固定的,所以在多义词区分方面ELMo的效果必然比word2vec要好。
- 另外,ELMo通过语言模型生成的词向量是通过特定上下文的“传递”而来,再根据下游任务,对原本上下文无关的词向量以及上下文相关的词向量表示引入一个权重,这样既在原来的词向量中引入了上下文的信息,又能根据下游任务适时调整各部分的权重(权重是在网络中学习得来的),因此这也是ELMo有效的一个原因。
6. ELMO把三种不同的向量叠加的意义
因为通过ELMo模型,句子中每个单词都能得到对应的三个Embedding:
- 最底层是单词的Word Embedding;
- 往上走是第一层双向LSTM中对应单词位置的Embedding,这层编码单词的句法信息更多一些;
- 再往上走是第二层LSTM中对应单词位置的Embedding,这层编码单词的语义信息更多一些。
「需要注意的是,这里得到的结论是通过实验验证的,是在这样的模型设计中,能够得到上述结论,可能不同模型结构,得到的结论又是不一样的。」
ELMo把三种不同的向量叠加的意义主要体现在以下两个点:
- 一是之前很多方法都只用了最顶层LSTM的hidden state,但是通过实验验证,在很多任务中,将每一层hidden state融合在一起会取得更好的效果;
- 二是在上述实验中得到结论,每一层LSTM得到单词的embedding所蕴含的信息是不一样的,因此将所有信息融合起来,会让单词embedding的表达更丰富。
这样做能够起到区分多义词的效果,而且在论文展示的6个任务中都取得了SOTA的效果。