ELMo词向量

2019-06-29  本文已影响0人  Luuuuuua

ELMo词向量出自于论文《Deep contextualized word representations》

什么是ELMo?

ELMo的全称是Embeddings from Language Models,中文意思是基于语言模型的词向量,它是一个上下文词向量/动态词向量,同一单词在不同的上下文中具有不同的含义,而ELMo词向量能表示出这种不同。
实现过程可以简单描述为:将不同的句子输入模型,模型会实时产生上下文词向量。

ELMo是如何实现的?

  1. 构建一个双向语言模型,给定一个包含N个tokens(t_1,t_2,...,t_N)的序列
    前向语言模型,给定前面的tokens(t_1,t_2,...,t_{k-1})求下一个token是t_k的概率:
    p(t_1,t_2,...,t_N)=\prod_{k=1}^{N}p(t_k|t_1,t_2,...,t_{k-1})
    反向语言模型,与前向语言模型相反,知道后边的token,求前面的token:
    p(t_1,t_2,...,t_N)=\prod_{k=1}^{N}p(t_k|t_{k+1},t_{k+2},...,t_N)
    那么,双向语言模型可以表示为:
    \sum_{k=1}^N \log (p(t_k|t_1,t_2,...,t_{k-1};\Theta_x;\stackrel{\rightarrow}\Theta_{LSTM},\Theta_s)+p(t_k|t_{k+1},t_{k+2},...,t_N);\Theta_x; \stackrel{\leftarrow} \Theta_{LSTM},\Theta_s)
    其中,\Theta_x是输入层单词表示的参数,\Theta_{LSTM} 是LSTM参数,\Theta_s是Softmax层的参数。

  2. 结合网络各层的双向语言模型的表达
    对于tokent_k,通过一个由L层双向语言模型构成的网络,可以得到2L+1个表示:
    R_k=\{x_k^{LM},\stackrel{\rightarrow}h_{k,j}^{LM},\stackrel{\leftarrow} h_{k,j}^{LM}|j=1,2,...,L\} =\{h_{k,j}^{LM}|j=0,1,...,L\}
    h_{k,0}^{LM}是对token直接编码的结果(可以使用word2vec,Glove,或者将字符通过CNN进行编码),h_{k,j}^{LM}是每个biLSTM层输出的结果。
    在下游任务中,可以组合不同层的单词的表示进行使用:
    ELMo_k^{task}=E(R_k,\Theta^{task})=\gamma^{task}\sum_{j=0}^{L}s_j^{task}h_{h,j}^{LM}
    其中,\gamma^{task}是任务相关的scale参数,不同的任务要设置不同的数值,s_j是一个softmax的结果,可以在训练的过程中学习。

ELMo是如何训练的?

网络结构共三层

ELMo和Glove的区别

实践参考代码

哈工大改写的多国语言版:https://github.com/HIT-SCIR/ELMoForManyLangs

Pytorch版ELMo(Allennlp)

from allennlp.commands.elmo import ElmoEmbedder
elmo = ElmoEmbedder(options_file='../data/elmo_options.json', weight_file='../data/elmo_weights.hdf5', cuda_device=0)
context_tokens = [['I', 'love', 'you', '.'], ['Sorry', ',', 'I', 'don', "'t", 'love', 'you', '.']]
elmo_embedding, elmo_mask = elmo.batch_to_embeddings(context_tokens)
print(elmo_embedding)
print(elmo_mask)

1. 导入ElmoEmbedder类
2. 实例化ElmoEmbedder. 3个参数分别为参数配置文件, 预训练的权值文件, 想要用的gpu编号, 这里两个文件我是直接下载好的, 如果指定系统默认自动下载会花费一定的时间, 下载地址
   
    DEFAULT_OPTIONS_FILE = "https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_options.json"
    DEFAULT_WEIGHT_FILE = "https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5"
    
3. 输入是一个list的token序列, 其中外层list的size即内层list的个数就是我们平时说的batch_size, 内层每个list包含一个你想要处理的序列(这里是一句话, 你可以一篇文章或输入任意的序列, 因为这里预训练的模型是在英文wikipidia上训的, 所以输入非英文的序列肯定得到的结果没什么意义).
4. 通过batch_to_embeddings对输入进行计算的到tokens的embedding结果以及我们输入的batch的mask信息(自动求mask)

    Variable containing:
    ( 0  , 0  ,.,.) = 
      0.6923 -0.3261  0.2283  ...   0.1757  0.2660 -0.1013
     -0.7348 -0.0965 -0.1411  ...  -0.3411  0.3681  0.5445
      0.3645 -0.1415 -0.0662  ...   0.1163  0.1783 -0.7290
               ...             ⋱             ...          
      0.0000  0.0000  0.0000  ...   0.0000  0.0000  0.0000
      0.0000  0.0000  0.0000  ...   0.0000  0.0000  0.0000
      0.0000  0.0000  0.0000  ...   0.0000  0.0000  0.0000
      
            ⋮  

    ( 1  , 2  ,.,.) = 
     -0.0830 -1.5891 -0.2576  ...  -1.2944  0.1082  0.6745
     -0.0724 -0.7200  0.1463  ...   0.6919  0.9144 -0.1260
     -2.3460 -1.1714 -0.7065  ...  -1.2885  0.4679  0.3800
               ...             ⋱             ...          
      0.1246 -0.6929  0.6330  ...   0.6294  1.6869 -0.6655
     -0.5757 -1.0845  0.5794  ...   0.0825  0.5020  0.2765
     -1.2392 -0.6155 -0.9032  ...   0.0524 -0.0852  0.0805
    [torch.cuda.FloatTensor of size 2x3x8x1024 (GPU 0)]

    Variable containing:
        1     1     1     1     0     0     0     0
        1     1     1     1     1     1     1     1
    [torch.cuda.LongTensor of size 2x8 (GPU 0)]

输出两个Variable, 第一个是2*3*8*1024的embedding信息, 第二个是mask. 
其中2是batch_size, 3是两层biLM的输出加一层CNN对character编码的输出, 8是最长list的长度(对齐), 1024是每层输出的维度
mask的输出2是batch_size, 8实在最长list的长度, 第一个list有4个tokens, 第二个list有8个tokens, 所以对应位置输出1.

参考资料
http://shomy.top/2019/01/01/elmo-1/
https://cstsunfu.github.io/2018/06/ELMo/
https://blog.csdn.net/sinat_26917383/article/details/81913790

上一篇 下一篇

猜你喜欢

热点阅读