参考:如何将ELMo词向量用于中文 | Weekly Review
参考:字符级卷积神经网络(Char-CNN)实现文本分类--模型介绍与TensorFlow实现_呜呜哈的博客-CSDN博客_charcnnc
参考:[nlp] Word2vec模型 skip-gram和CBOW区别_Trance95的博客-CSDN博客_skipgram和cbow区别
参考:从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史 - 知乎
总结
Skip - Gram : o(KV) k = 2*skip_window
CBOW : o(V)
【加速1】层次softmax (Huffman树) 时间复杂度o(v)/o(kv) -> o(log2v) 1.二叉2.高频深度浅
【加速2】负采样 (第二种)
Nce负采样 (在输入中做正负样本)negative sampling
当x作为中心词时 , 输入X=[正样本x , 若干个负样本],
把输出层替换为LR,(一个神经元+sigmoid),也就是将中间层的词向量通过LR做二分类 (标签y记录正类和负类),损失函数使用交叉熵损失。
可以理解为Nce通过输出层W2(300*1)权重共享,减少输出层权重的参数量。对比之前10000个输出单元的 softmax 分类,negative sampling转化为 k+1 个二分类问题,比softmax负采样更快。
Nce_loss是把激活放在交叉熵里,参见我的其他博客。
因为常用词会成为很多中心词的上下文词,所以采样上下文词时避免采样到常用词,因为我们想减少去学中心词和常用词上下文词的语义依赖,更关注于学到中心词和非常用词的上下文词的语义依赖。可以理解为是对常用的上下文词的降权,类似代价敏感的思想。
★ 负样本采样:采样非上下文词 (采样率:多采常用词)
对于负样本的采样概率: 越常见越容易被采样(多采常用词)。
★ 正样本采样:采样上下文词 (采样率:少采常用词)
skip-gram 中对于上下文词(标签)的采样概率 : 越常见越难被采样(少采常用词)。
目录
一、word2vec
word2vec是Google与2013年开源推出的一个用于获取word vecter的工具包,利用神经网络为单词寻找一个连续向量看空间中的表示。word2vec是将单词转换为向量的算法,该算法使得具有相似含义的单词表示为相互靠近的向量。
此外,它能让我们使用向量算法来处理类别,例如着名等式King−Man+Woman=Queen。
word2vec一般分为CBOW(Continuous Bag-of-Words)与Skip-Gram两种模型:
- Skip-Gram是给定input word来预测上下文。有negative sample(负采样)和Huffman(二次采样)两种加速算法;
- 而CBOW是给定上下文,来预测input word。
Embedding其实就是一个映射,将单词从原先所属的空间映射到新的多维空间中,也就是把原先词所在空间嵌入到一个新的空间中去。
1. CBOW
CBOW是给定上下文,来预测input word。
假设单词的向量空间维度为V,上下文单词个数为C,求解两个权重均值W和W’。对于上图的解释如下:
-
输入层:上下文单词的onehot形式;
-
隐藏层:将输入层所有onehot后的向量(行向量)乘以第一个权重矩阵W(所有的权重矩阵相同,即共享权重矩阵),然后相加求平均作为隐藏层向量。
-
输出层:将隐藏层向量乘以第二权重矩阵W‘,得到一个V维的向量,然后再通过激活函数(softmax)得到每一维词的概率分布,概率最大的位置所指示的单词为预测出的中间词;
-
一般使用使用的损失函数为交叉熵损失函数,采用梯度下降的方式来更新W和W’;这实际上是一个假任务,即我们需要的只是第一个权重矩阵W。得到第一个矩阵W之后,我们就能得到每个单词的词向量了。
-
假设我们现在的语料是这一个简单的只有四个单词的句子:
I drink coffee everyday
我们使用的window size设为2。
则训练这么一个句子,我们会需要训练4个batch,即句子中的单词个数的batch。
首先对单词onehot则可以得到
X_I = [1,0,0,0];X_drink = [0,1,0,0];X_coffee = [0,0,1,0] ; X_everyday = [0,0,0,1];
- 第一个batch:I为中心词,drink coffee和 everyday 为上下文,CBOW即使用单词drink , coffee来预测单词I,即输入为X_drink、X_coffee 和 X_everyday,输出为X_I,然后训练上述网络;
- 第二个batch:drink为中心词,I和 coffee everyday为上下文,即使用单词I和coffee everyday,即输入为X_I和X_coffee、X_everyday,输出为X_drink,然后训练上述网络;
- 第三个batch:coffee为中心词,I drink 和 everyday为上下文,同理训练网络;
- 第四个batch:everyday为中心词,drink coffee为上下文,同理训练网络。
2. Skip-gram
给定input word来预测上下文。
第一部分为建立模型,第二部分是通过模型获取嵌入词向量。
Word2Vec的整个建模过程实际上与自编码器(auto-encoder)的思想很相似,即先基于训练数据构建一个神经网络,当这个模型训练好以后,我们并不会用这个训练好的模型处理新的任务,我们真正需要的是这个模型通过训练数据所学得的参数,例如隐层的权重矩阵(单词向量矩阵)。基于训练数据建模的过程,我们给它一个名字叫“Fake Task”,意味着建模并不是我们最终的目的。
自编码器(auto-encoder):通过在隐层将输入进行编码压缩,继而在输出层将数据解码恢复初始状态,训练完成后,我们会将输出层“砍掉”,仅保留隐层。
二、glove
不仅依赖于本地统计信息(单词的本地上下文信息),而且还结合了全局统计信息(单词共现)来获取单词向量。
全局统计数据得出单词之间的语义关系的想法可以追溯到 潜在的语义分析(LSA——latent semantic analysis)。
LSA假设含义相似的单词将出现在相似的文本片段中(分布假设)。
分布假说(Vector Semantics): 两个词在语义上相似度越高,它们反过来在分布上越相似,因此,在相似的语言环境中,它们越倾向于出现。
the cat sat on mat.
词语前后是共现。
三、ELMo
3.1 关于ELMo
ELMo由AllenNLP提出,与word2vec或GloVe不同的是其 动态词向量 的思想,其本质即通过训练language model,对于一句话进入到language model获得不同的词向量。根据实验可得,使用了Elmo词向量之后,许多NLP任务都有了大幅的提高。
AllenNLP一共release了两份ELMo的代码,一份是Pytorch版本的,另一份是Tensorflow版本的。Pytorch版本的只开放了使用预训练好的词向量的接口,但没有给出自己训练的接口,因此无法使用到中文语料中。ELMo后由哈工大组用PyTorch重写了,并且提供了中文的预训练好的language model,可以直接使用。Tensorflow版本有提供训练的代码,因此本文记录如何将ELMo用于中文语料中。
Deep contextualized word representation:深层语境化的单词表示–emlo(Embedding from Language Models)
主要是根据当前词的上下文不同而生成对应词的词向量.
其主要阶段有两个:
1. 构建预训练的模型;
2. 将新生成的 wordembedding(三种向量加权得到的) 作为下游任务的输入.
由下到上:
第一层是单词最初的 wordembedding,这个用另外的一个语言模型学到的;
第二层是单词上下文的 wordembedding,主要获取的是句法特征 (词语搭配),这个是用双向 LSTM 获取而来的,最初需要进行随机初始化.
第三层是单词上下文的 wordembedding,主要获取的是语义特征 (例如.it 所指代的词具体是什么),也是双向 LSTM 获取而来的.最初需要进行随机初始化.
最后使用一个权重矩阵 (需要进行不断调整的),将三个向量进行加权(解决一词多义),得到一个下游任务的输入向量.
3.2 biLM(双向lstm)
文中采用了一种名为biLM的模型,该模型是一种“双向”的模型。 假设我们有一个包含N个单词的句子,可以把它表示为:t1,t2,…,tN,
那么从“前向”的角度来计算这个句子的概率的话,我们可以通过每个词语“之前的”词语来对其进行建模,具体而言如下公式所示:
从“后向”的角度来计算这个句子的概率的话,
“双向”模型,是兼顾前向和后向的概率的,用公式表示为:
每一层的双向结构如下图所示,每一个框代表lstm单元;
3.3 模型架构
emlo使用了两层的双向lstm,通过对每一层的隐藏状态线性组合(),构成最终的词向量。
而初始输入的词向量,作者推荐使用 字符卷积网络(char-CNN) 来生成。
当然为了加速训练,也可以在输入时直接使用word2vec或glove等传统词向量。
将emlo用于下游的任务,论文中提到了三种方式:
(1)和输入词向量x进行concat
(2)和最后一层的隐藏状态concat
(3)同时使用(1)和(2)
最后使用L2正则化,其中L2 项的系数 越大, 越有取各层平均值的意思, 越小, 越可以发挥各个层之间的不同带来的效果。 但是并不是说, 越小越好;
3.4 实验结果
模型在6个数据集上取得了当时的最好成绩:
对比实验:
作者对比了emlo模型中只使用最后一层和每层都使用(其中取值不同)的效果,其中每层都使用( = 0.001)效果最好;
作者还展示了emlo词向量再找同义词时的效果:
最后作者还通过一个实验尝试说明emlo词向量每层的h代表什么含义,即分别单独使用每层的隐藏状态进行词义消歧和词性标注任务,通过效果对比,说明了第一层的隐藏状态更能代表语法信息,第二层的隐藏状态更能代表语义信息;