ELMO小谈

现在谈EMLO,倒是有点食之微味,弃之可惜的意思。2018年,BERT的横空出世撼动了NLP的半壁江山,nlper无不知晓,多项刷榜记录让多数奋战在一线钻研算法的工程师们一刹那觉得自己的努力也仅仅只是感动了自己而已,自然而然,BERT的风光掩盖了ELMO。

但是,我个人觉得,从word2vec,glove到ELMO,BERT,ELMO算是一个比较精彩的转折点吧,有着承前启后的作用,于是,今天就来小谈下ELMO。

为什么出现了ELMO?

在word2vec的时代,词向量是上下文无关的,然而在语言中一词多义的现象是很常见的,比如may,有可能的意思,也有五月的意思;apple,是可以吃的苹果,还是那个apple公司,完全取决于语境。在答案选择领域,那么多复杂的模型,无非不就是为了获得句子的语义信息,句子由词组成,细微处看,就是在摸索词之间的联系与含义,如果一个词没有根据下游任务改变自己的能力,那么往往就需要外界力量去推动她来展示不同层面的意思,而这个外界力量就是那些复杂的模型结构。那么,何不追本溯源,从一开始就让词向量拥有可以根据不同下游任务而变换的能力呢?ELMO因此诞生。

双向语言模型

  • 前向语言模型:

  • 后向语言模型:

那么其损失函数语言模型标准的最大化似然函数:

上面的双向语言模型其实就是统计语言模型的一个近似,什么是统计语言模型呢?统计语言模型就是通过统计方法计算一个句子的概率的模型。以前向语言模型为例,我们可以根据这个概率公式来计算下一个词出现的概率。比如“the cat sat on the mat”,我们可以根据“the cat sat on the”来预测下一个词是“mat”的概率,有种完形填空的味道。

ELMO要点

一、模型结构

从图的结构上来看,我们可以很清晰的看到ELMO模型的主要结构就是L层的双向LSTM,对于L层的双向lstm语言模型,一共会有有2L+1个representations。在多层模型中,浅层往往蕴含的是句法,语法信息,而高层蕴含的是语义信息,因此你可以选择ELMO中各层的输出作为最后的输出,也可以将各层的输出进行综合作为最后的输出。

上面2个公式就可以很好的说明了整个流程:ELMO 经过 L 层的双向语言模型, 然后将字符级表示, 每层的隐层输出组合起来, 形成一个2L + 1 个向量。是不同层的参数经过softmax结果(也就是说),值得一提的是, 缩放因子是考虑到双向语言模型中的每一层的输出具有不同的分布,其某种程度上相当于在 Weighting 前对每一层的向量做 Layer Normalization。 论文中有提到,如果将每层向量提前做Normalization, 也能够有所帮助[1]。

论文的作者有预训练好的ELMo模型,同时LSTM的层数L=2,我们以2层的ELMO来具体看ELMO的结构。

  1. E1:word embedding部分,这个部分可以用wrod2vec或者glove来得到上下文无关general embedding。文中使用的Jozefowicz的CNN-BIG-LSTM[2].
  2. L=2,作者用2层的bilstm进行encoder,同时将每一层lstm得到的hidden state(隐状态) 作为每个词的上下文相关的word vectors.
  3. 1+2*2 = 5,现在总共有5个上下文相关的word vectors,那么将词向量进行线性组合,针对不同的任务,不同层的向量做相应的权重加和。

二、模型精髓

  1. ELMO的各层参数实际上就是为各种有监督的下游任务准备的,因此ELMO可以被认为是一种迁移学习(transfer learning)。
  2. 通过这样的迁移策略,那些对词义消歧有需求的任务就更容易通过训练给第二隐层一个很大的权重,而对词性、句法有明显需求的任务则可能对第一隐层的参数学习到比较大的值(实验结论)。总之,这样便得到了一份”可以被下游任务定制“的特征更为丰富的词向量。[3]

三、ELMO缺点

  • lstm是串行机制,训练时间长,从这一点来看ELMO注定成为不了大哥
  • 相比于Transformer,lstm提取特征的能力还是不够的,我觉得未来lstm可能会被淘汰,毕竟屁股决定脑袋,时间为上!

四、ELMO词向量使用方式

论文中提到, 使用ELMO 有两种方式:

  • 将 ELMO 的向量 与 Word2Vec等普通词向量进行连接,连接的方式可以有多种多样
  • 将 ELMO 的向量与上下文表示层的  (通过 LSTM/Transformer处理传统词向量得到) 进行连接, 连接的方式同样有多种多样。

论文中还提到, 适当的 Dropout 或者在损失中加入L2正则是有帮助的。

五、ELMO实践

搬运一下!

有三种方法可以使用预训练好的elmo模型。

一、elmo官方allenNLP发布的基于pytorch实现的版本[4];

二、elmo官方发布的基于tensorflow实现的版本[5];

三、tensorflow-hub中google基于tensorflow实现的elmo的版本[6]。

本节内容介绍第三个版本,tensorflow-hub

下面看代码的简单上手使用,大家可能需要先安装tensorflow_hub。

import tensorflow_hub as hub

# 加载模型
elmo = hub.Module("https://tfhub.dev/google/elmo/2", trainable=True)
# 输入的数据集
texts = ["the cat is on the mat", "dogs are in the fog"]
embeddings = elmo(
texts,
signature="default",
as_dict=True)["default"]

上述代码中,hub.Module加载模型,第一次会非常慢,因为要下载模型,甚至可能要科学上网。该模型是训练好的模型,也就是lstm中的参数都是固定的。下面的代码是另一种实现,我们可以看到区别在于输入的数据格式不一样!

elmo = hub.Module("https://tfhub.dev/google/elmo/2", trainable=True)

# 另一种方式输入数据
tokens_input = [["the", "cat", "is", "on", "the", "mat"],
["dogs", "are", "in", "the", "fog", ""]]
# 长度,表示tokens_input第一行6一个有效,第二行5个有效
tokens_length = [6, 5]
# 生成elmo embedding
embeddings = elmo(
inputs={
"tokens": tokens_input,
"sequence_len": tokens_length
},
signature="tokens",
as_dict=True)["default"]

EMLO可以以batch的形式训练,但是我在测试上面方法的时候发现有2个问题!

  1. batch_size设置的太大的话,内存直接爆炸
  2. 因为调用的是elmo的网址,然而在测试的时候我的pc老是掉线,因此很恼火,所以我采用了第二种方式训练了

目前还在跑模型,总结用法后会放上来,如果感兴趣,请关注我的 github 以及我的 知乎专栏

 

Reference:

1.ELMO: Deep contextualized word representations

2.Jozefowicz R, Vinyals O, Schuster M, et al. Exploring the limits of language modeling[J]. arXiv preprint arXiv:1602.02410, 2016.

3.NLP的游戏规则从此改写?从word2vec, ELMo到BERT

4.https://github.com/allenai/allennlp/blob/master/tutorials/how_to/elmo.md

5.https://github.com/allenai/bilm-tf

6.https://tfhub.dev/google/elmo/2

你可能感兴趣的:(NLP自然语言处理,检索式问答机器人)