NAACL2018:高级词向量(ELMo)详解(超详细) 经典

非常厉害的论文,性能非常强大

介绍

之前的glove以及word2vec的word embedding在nlp任务中都取得了最好的效果,,现在几乎没有一个NLP的任务中不加word embedding。我们常用的获取embedding方法都是通过训练language model,将language model中预测的hidden state做为word的表示,给定N个tokens的序列(t1,t2,...,tn), 前向language model就是通过前k-1个输入序列(t1,t2,...,tk)的hidden表示, 预测第k个位置的token, 反向的language model就是给定后面的序列, 预测之前的。然后将language model的第k个位置的hidden输出做为word embedding。之前的做法的缺点是对于每一个单词都有唯一的一个embedding表示, 而对于多义词显然这种做法不符合直觉, 而单词的意思又和上下文相关, ELMo的做法是我们只预训练language model,而word embedding是通过输入的句子实时输出的, 这样单词的意思就是上下文相关的了,这样就很大程度上缓解了歧义的发生

在此之前的 Word Embedding 本质上是个静态的方式,所谓静态指的是训练好之后每个单词的表达就固定住了,以后使用的时候,不论新句子上下文单词是什么,这个单词的 Word Embedding 不会跟着上下文场景的变化而改变,所以对于比如 Bank 这个词,它事先学好的 Word Embedding 中混合了几种语义,在应用中来了个新句子,即使从上下文中(比如句子包含 money 等词)明显可以看出它代表的是「银行」的含义,但是对应的 Word Embedding 内容也不会变,它还是混合了多种语义。这是为何说它是静态的,这也是问题所在

ELMo用到上文提到的双向的language model,给定N个tokens (t1, t2,…,tN), language model通过给定前面的k-1个位置的token序列计算第k个token的出现的概率:

p(t_1, t_2, ..., t_N) = \prod_{k=1}^N p(t_k|t_1, t_2, ..., t_{k-1})

后向的计算方法与前向相似:

p\left(t_{1}, t_{2}, \ldots, t_{N}\right)=\prod_{k=1}^{N} p\left(t_{k} | t_{k+1}, t_{k+2}, \ldots, t_{N}\right)

biLM训练过程中的目标就是最大化:

\sum_{k=1}^{N}\left(\log p\left(t_{k} | t_{1}, \ldots, t_{k-1} ; \Theta_{x}, \vec{\Theta}_{L S T M}, \Theta_{s}\right)+\log p\left(t_{k} | t_{k+1}, \ldots, t_{N} ; \Theta_{x}, \stackrel{\leftarrow}{\Theta}_{L S T M}, \Theta_{s}\right)\right)

ELMo对于每个token t_k , 通过一个L层的biLM计算出2L+1个表示:

R_k = \{x_k^{LM}, \overrightarrow{h}_{k,j}^{LM}, \overleftarrow{h}_{k, j}^{LM} \vert j=1, ..., L\} = \{h_{k,j}^{LM} \vert j=0,..., L\}

其中 x_k^{LM} 是对token进行直接编码的结果(这里是字符通过CNN编码), \mathbf{h}_{k, 0}^{L M} 代表 x_k^{LM} h_{k,j}^{LM} = [\overrightarrow{h}_{k,j}^{LM}; \overleftarrow{h}_{k, j}^{LM}] 是每个biLSTM层输出的结果。在实验中还发现不同层的biLM的输出的token表示对于不同的任务效果不同.最上面一层的输出 \overrightarrow{\mathbf{h}}_{k, L}^{L M} 是用softmax来预测下面一个单词 t_{k+1}

应用中将ELMo中所有层的输出R压缩为单个向量, ELMo_k = E(R_k;\Theta _\epsilon),最简单的压缩方法是取最上层的结果做为token的表示: E(R_k) = h_{k,L}^{LM} ,更通用的做法是通过一些参数来联合所有层的信息:

E L M o_{k}^{t a s k}=E\left(R_{k} ; \Theta^{t a s k}\right)=\gamma^{t a s k} \sum_{j=0}^{L} s_{j}^{t a s k} h_{k, j}^{L M}

其中 \mathbf{s}^{\operatorname{tas} k} 是一个softmax出来的结果, γ是一个任务相关的scale参数,我试了平均每个层的信息和学出来 \mathbf{s}^{\operatorname {task}} 发现学习出来的效果会好很多。 文中提到γ在不同任务中取不同的值效果会有较大的差异, 需要注意, 在SQuAD中设置为0.01取得的效果要好于设置为1时。

文章中提到的Pre-trained的language model是用了两层的biLM, 对token进行上下文无关的编码是通过CNN对字符级进行编码, 然后将三层的输出scale到1024维, 最后对每个token输出3个1024维的向量表示。 这里之所以将3层的输出都作为token的embedding表示是因为实验已经证实不同层的LM输出的信息对于不同的任务作用是不同的, 也就是所不同层的输出捕捉到的token的信息是不相同的。

参考:ELMoELMo

ELMO 的本质思想是:我事先用语言模型学好一个单词的 Word Embedding,此时多义词无法区分,不过这没关系。在我实际使用 Word Embedding 的时候,单词已经具备了特定的上下文了,这个时候我可以根据上下文单词的语义去调整单词的 Word Embedding 表示,这样经过调整后的 Word Embedding 更能表达在这个上下文中的具体含义,自然也就解决了多义词的问题了。所以 ELMO 本身是个根据当前上下文对 Word Embedding 动态调整的思路。

ELMO 采用了典型的两阶段过程,第一个阶段是利用语言模型进行预训练;第二个阶段是在做下游任务时,从预训练网络中提取对应单词的网络各层的 Word Embedding 作为新特征补充到下游任务中。

上图展示的是其预训练过程,它的网络结构采用了双层双向 LSTM,目前语言模型训练的任务目标是根据单词 W_{i} 的上下文去正确预测单词 W_{i}W_{i} 之前的单词序列 Context-before 称为上文,之后的单词序列 Context-after 称为下文。图中左端的前向双层LSTM代表正方向编码器,输入的是从左到右顺序的除了预测单词外 W_{i} 的上文 Context-before;右端的逆向双层 LSTM 代表反方向编码器,输入的是从右到左的逆序的句子下文 Context-after;每个编码器的深度都是两层 LSTM 叠加。这个网络结构其实在 NLP 中是很常用的

使用这个网络结构利用大量语料做语言模型任务就能预先训练好这个网络,如果训练好这个网络后,输入一个新句子Snew,句子中每个单词都能得到对应的三个Embedding:最底层是单词的 Word Embedding,往上走是第一层双向LSTM中对应单词位置的 Embedding,这层编码单词的句法信息更多一些;再往上走是第二层LSTM中对应单词位置的 Embedding,这层编码单词的语义信息更多一些。也就是说,ELMO 的预训练过程不仅仅学会单词的 Word Embedding,还学会了一个双层双向的LSTM网络结构,而这两者后面都有用。

上面介绍的是 ELMO 的第一阶段:预训练阶段。那么预训练好网络结构后,如何给下游任务使用呢?上图展示了下游任务的使用过程,比如我们的下游任务仍然是 QA 问题,此时对于问句 X,我们可以先将句子 X 作为预训练好的 ELMO 网络的输入,这样句子 X 中每个单词在 ELMO 网络中都能获得对应的三个 Embedding,之后给予这三个 Embedding 中的每一个 Embedding 一个权重a,这个权重可以学习得来,根据各自权重累加求和,将三个 Embedding 整合成一个。

然后将整合后的这个 Embedding 作为 X 句在自己任务的那个网络结构中对应单词的输入,以此作为补充的新特征给下游任务使用。对于上图所示下游任务 QA 中的回答句子 Y 来说也是如此处理。

因为 ELMO给下游提供的是每个单词的特征形式,所以这一类预训练的方法被称为“Feature-based Pre-Training”。至于为何这么做能够达到区分多义词的效果,你可以想一想,其实比较容易想明白原因。

上面这个图是 TagLM 采用类似 ELMO 的思路做命名实体识别任务的过程,其步骤基本如上述 ELMO 的思路,所以此处不展开说了。TagLM 的论文发表在 2017 年的 ACL 会议上,作者就是 AllenAI 里做 ELMO 的那些人,所以可以将 TagLM 看做 ELMO 的一个前导工作。

前面我们提到静态 Word Embedding 无法解决多义词的问题,那么 ELMO 引入上下文动态调整单词的 embedding 后多义词问题解决了吗?解决了,而且比我们期待的解决得还要好。

上图给了个例子,对于 Glove 训练出的 Word Embedding 来说,多义词比如 play,根据它的 embedding 找出的最接近的其它单词大多数集中在体育领域,这很明显是因为训练数据中包含 play 的句子中体育领域的数量明显占优导致;而使用 ELMO,根据上下文动态调整后的 embedding 不仅能够找出对应的「演出」的相同语义的句子,而且还可以保证找出的句子中的 play 对应的词性也是相同的,这是超出期待之处。之所以会这样,是因为我们上面提到过,第一层 LSTM 编码了很多句法信息,这在这里起到了重要作用。

ELMO 经过这般操作,效果如何呢?实验效果见上图,6 个 NLP 任务中性能都有幅度不同的提升,最高的提升达到 25% 左右,而且这 6 个任务的覆盖范围比较广,包含句子语义关系判断,分类任务,阅读理解等多个领域,这说明其适用范围是非常广的,普适性强,这是一个非常好的优点。

那么站在现在这个时间节点看,ELMO 有什么值得改进的缺点呢?首先,一个非常明显的缺点在特征抽取器选择方面,ELMO 使用了LSTM而不是新贵 Transformer,Transformer 是谷歌在 17 年做机器翻译任务的“Attention is all you need”的论文中提出的,引起了相当大的反响,很多研究已经证明了 Transformer 提取特征的能力是要远强于LSTM的。如果 ELMO 采取 Transformer 作为特征提取器,那么估计 Bert 的反响远不如现在的这种火爆场面。另外一点,ELMO 采取双向拼接这种融合特征的能力可能比 Bert 一体化的融合特征方式弱,但是,这只是一种从道理推断产生的怀疑,目前并没有具体实验说明这一点。

编辑于 2019-04-21