ELMO,开启芝麻街自然语言处理新时代,后面还有BERT, ERNIE等新人物,不知道为什么这些人这么喜欢芝麻街,虽然ELMO出现时并没有像BERT一样引起轰动,但是它确实引起了一些新的思考。word2vec和Glove这两种词向量是固定的,对于同一个词,不管它的上下文是什么,所输出的向量都是一样的,这对于多义词来说很有问题,而ELMO就是采用语言模型的方法,获得中间层的输出作为这个在当前上下文中的表示,这解决了多义词难以表达的问题。

ELMO主要包含两个部分:

1. Char cnn embedding,根据char cnn embedding 生成word embedding,这个word embedding并不是最后的输出,它是类似模型中将word映射成向量的部分

2. 使用ELMO的主体模型bilstm语言模型生成上下文相关的word embedding

模型的总体架构如下图:

R语言两个向量逻辑运算 r语言两个向量合并_R语言两个向量逻辑运算

(图片来自devil_son1234博客)

1.1  char cnn embedding

R语言两个向量逻辑运算 r语言两个向量合并_语言模型_02

以上为这部分的模型图,Lookup Table中有262个元素,其中0-255是字符的unicode编码,256-261分别为(单词的开始)、(单词的结束)、 (句子的开始)、(句子的结束)、(单词补齐符)和(句子补齐符),根据官方的代码,在训练时Lookup Table中只有261个元素,有想详细了解的可以查看github上的源码。根据Lookup Table可以将字符映射成16维的向量,然后做一维卷积和最大池化,卷积核的数量分别为[32,32,64,128,256,512,1024]总共2048个,最后得到2048维的词向量,得到词向量后,还可以在加上highway层和linear映射层,highway层类似于lstm中的gate机制,linear映射层是为了将过长的词向量缩短,减少后续的计算量。

1.2 bilstm及输出的向量

模型结构如下:

R语言两个向量逻辑运算 r语言两个向量合并_github_03

通过char cnn embedding层得到的词向量输入到两层的bilstm中,为了防止梯度消失的问题,还加上了类似残差链接的方法,训练方法就是语言模型,通过上一个词得到下一个词,而使用时不需要模型最后的输出,需要的是两层bilstm的输出和最开始得到的词向量。

通过这些输出,对于每一个token都会得到2L+1个表征,如下:

R语言两个向量逻辑运算 r语言两个向量合并_R语言两个向量逻辑运算_04

L指bilstm的层数,一般为2.

对于这些表征做一个scalar mixer,公式为:

R语言两个向量逻辑运算 r语言两个向量合并_r语言中将两个向量合成一个向量_05

这两个参数都是作为参数来学习的,根据任务的不同会有不同的值。

总结:ELMO通过学习得到最终的输出的向量解决了之前的词向量难以解决的多义词问题,这些对于下游的任务的提升还是比较明显的,当然,在论文中还有很多细节性的东西,比如添加dropout和l2正则化,还有添加LayerNormalization等等。BERT版本后续会写。

参考:

https://www.mihaileric.com/posts/deep-contextualized-word-representations-elmo/

https://petrlorenc.github.io/ELMO/

https://github.com/allenai/bilm-tf/blob/master/README.md#whats-the-deal-with-n_characters-and-padding