ELMo预训练词向量模型
引言
Word Embedding:词嵌入。最简单的理解就是:将词进行向量化表示,抽象成为数学描述,然后可以进行建模,应用到很多自然语言处理的下游任务中。之前用语言模型做 Word Embedding 比较火的是 word2vec 和 glove,在大规模训练语料上使用 word2vec 或者 glove,可以学习得到每个单词的 Word Embedding 表示。但该类方法无法解决一词多义的问题,同一个词在不同的上下文中可能表示不同的意思,但是在 Word Embedding 中一个词只有一个固定的向量表示,这导致两种不同的上下文信息都会编码到相同的 Word Embedding 空间里去。如何根据句子上下文来进行单词的 Word Embedding 表示,ELMo 提供了解决方案。
NAACL-2018上的工作《Deep contextualized word representations》提出了 ELMo(Embedding from Language Models),提出了一个使用无监督的双向语言模型进行预训练,得到一个 context dependent 的词向量预训练模型,并且这个模型可以很容易地 plug in 到现有的模型当中。
ELMo 认为一个预训练的词表示应该能够包含丰富的句法和语义信息,并且能够对多义词进行建模。而传统的词向量(例如 word2vec)是上下文无关的。例如下面 'apple' 的例子,这两个 'apple' 根据上下文意思是不同的,但是在 word2vec 中,只有 apple 一个词向量,无法对一词多义进行建模。
Example:
1.Jobs was the CEO of apple.
2.He finally ate the apple.
ELMo原理
在 EMLO 中,使用的是一个双层双向的 LSTM 模型,由一个前向和一个后向语言模型构成,目标函数就是取这两个方向语言模型的最大似然。下图展示的是其预训练过程,训练的任务目标是根据单词 的上下文去正确预测单词 , 之前的单词序列 Context-before 称为上文,之后的单词序列Context-after 称为下文。图中左端的前向双层 LSTM 代表正方向编码器,输入的是从左到右顺序除了预测单词 外的上文 Context-before;右端的反向双层 LSTM 代表反方向编码器,输入的是从右到左的逆序的句子下文 Context-after。使用该网络结构和大规模语料可以进行语言模型的预训练。
下图为 ELMo 前向预训练过程中的一个步骤:
给定一个长度为 的序列 ,对于每个token ,以及它的历史 token 序列 和后续 token 序列 :
对于前向的 LSTM 语言模型:
对于后向的 LSTM 语言模型:
双向语言模型(biLM)将前向和后向语言模型联合起来,并最大化前后向语言模型的联合似然函数:
其中
为输入层 token 的 embedding 表示; 为 softmax 输出层参数; 为双层双向 LSTM 模型参数。
在预训练好语言模型后,如何给下游任务使用呢?上图展示了下游任务的使用过程。对于句子 ,可以先将其作为预训练好的 ELMo 网络的输入,这样句子 中每个单词在 ELMo 网络中都能获得对应的三个 Embedding:初始词向量 ,第一层前向 LSTM 输出向量 和反向 LSTM 输出向量 ,第二层前向 LSTM 输出向量 和反向 LSTM 输出向量 。假设 ELMo 是 个双向 LSTM 的堆叠,对于句子中的每个单词,一共有 个表征(representations):
第 k 个单词的词向量可以表示为:
其中 是 softmax 归一化权重, 为任务模型对 ELMo 词向量的 scale 系数。实际应用时最简单的可使用各层向量的平均,或仅使用最高层的表示来作为 ELMo 模型输出的词向量。
ELMo效果
多个任务上均有提升
一词多义
前面我们提到静态 Word Embedding 无法解决一词多义的问题,那么 ELMo 引入上下文动态调整单词的 embedding 后多义词问题解决了吗?解决了,而且比我们期待的还要好。下图给了个例子,对于 Glove 训练出的 Word Embedding,多义词比如 play,根据它的 embedding 找出的最接近的其它单词大多数集中在体育领域,这很明显是因为训练数据包含 play 的句子中体育领域的数量明显占据优势;而使用 ELMo,根据上下文动态调整后的 embedding 不仅能够找出对应“演出”的相同语义句子,而且还可以保证找出的句子中 play 对应的词性也是相同的,这是超出期待之处。之所以会这样,是因为我们上面提到过,第一层LSTM编码了很多句法信息。
词义消歧
词性标注
中文ELMo预训练模型
哈工大社会计算与信息检索研究中心 HIT-SCIR 提供了中文简体语料的 ELMo 预训练模型,代码和模型地址:https://github.com/HIT-SCIR/ELMoForManyLangs
使用示例:
from elmoformanylangs import Embedder
e = Embedder('/path/to/your/model/')
sents = [['今', '天', '天氣', '真', '好', '阿'],
['潮水', '退', '了', '就', '知道', '誰', '沒', '穿', '褲子']]
# the list of lists which store the sentences
# after segment if necessary.
e.sents2elmo(sents)
# will return a list of numpy arrays
# each with the shape=(seq_len, embedding_size)
Embedder 类的参数如下:
class Embedder(model_dir='/path/to/your/model/', batch_size=64):
model_dir:中文 ELMo 预训练语言模型的路径 batch_size:模型推理时一个 batch 内的句子个数,默认为64
sents2elmo 函数的参数如下:
def sents2elmo(sents, output_layer=-1):
sents:句子列表 output_layer:the target layer to output 0 for the word encoder 1 for the first LSTM hidden layer 2 for the second LSTM hidden layer -1 for an average of 3 layers. (default) -2 for all 3 layers
总结
优点:
ELMo 可以根据上下文语境来推断每个词对应的表示,比较好的解决一词多义问题。 ELMo 建立语言模型的时候,可以运用类似的超大语料库去学习,学习好后,再应用到具体任务中去。
缺点:
在特征抽取器选择方面,ELMo 使用了 LSTM 而不是 Transformer,Transformer 提取特征的能力强于 LSTM。 ELMo 采取双向拼接融合特征的能力可能比 Bert 一体化的融合特征方式弱。