欢迎光临 x-algo
关注算法在工业界应用
Hi, 这是一个关注大数据算法在工业界应用的网站

无监督词向量/句向量:W2v/Glove/Swivel/ELMo/BERT

Word2Vec

详细实现和理论看这里使用Tensorflow实现word2vec模型, 三层的神经网络 ,通过nce采样优化. 本质上语言模型, 极大似然估计.

tf提供的nce_loss,, 负采样效率高, 就是不对softmax中所有的分母反向传播. 使用nce_loss, 编号必须按照词频降序, 是使用默认log  uniform分布采样的前提.

这里负采样的假设是词频是指数级别递减的, tf提供的负采样的函数 tf.nn.nce_loss会选择性的进行最后一层的矩阵乘法从而提高效率.

Glove

融合传统的矩阵分解和local window context方法.通过统计共现, 将数据变为一个共现矩阵. 时间复杂度得到了很好的提高.可以对高频/低频的共现进行了更好的权重控制.

类似word2vec最后生成两个矩阵 \(W_{in}\)\(W_{out}\) , 如果count矩阵是对称的,最终输出的两个 \(W\) 也应该是一样的. 论文中将两个矩阵加到一起得到一个新矩阵, 用这个矩阵作为最终的embedding会有性能的提升.

由于没有负采样,Glove学出来的embeding并没有约束未观察到的词和当前词的关系.

核心的损失函数为:

9.2.19

论文:https://nlp.stanford.edu/projects/glove/

Swivel

swivel的tf实现

方法的特点:

  • 为分布式训练/学习而设计
  • word2vec本质是对PMI回归,可以干脆不用滑动窗口, 直接对目标进行矩阵分解好了,将复杂度变为和语料大小无关.
  • 采用共现矩阵,将矩阵分块,加快训练速度
  • 共现矩阵一般比较稀疏,这也是Glove的缺点,针对没有观察到的共现做优化
  • 通过piecewise loss对未观察到的共现进行建模
  • 本质是count-base的模型,对每一个cell的PMI进行"回归"

核心损失函数为: 9.2.20

如何处理没有观测到的样本呢?

例如有一对词从来没有共现过:

  1. 如果每一个词本身出现的频率较高.那就倾向于认为两个词是真的没有相关性.
  2. 相反的,如果两个词本身出现的频率就不高,可以认为语料是不充分的.这个时候就倾向于"不知道"两个词是否相关,惩罚也要小一些.

反应到loss上面就是合页损失函数的拐点不一样.

9.2.21

上面的线为 \(log(1+e^{x-2})\) ,下面的为 \(log(1+e^{x-100})\) ,

整体上的loss为分段的loss,如下:

9.2.23

 

ELMo

  1. 本质还是一个语言模型,在6个NLP的任务上效果明显
  2. 结构上和以前的不同,w2v/Glove/Swivel都可以看做是一个三层的神经网络.本文使用的是一个双向的LSTM
  3. 整个网络中,在word embedding和softmax层共享参数,两个LSTM分开训练.
  4. 对每一个词,网络产出2L+1组embedding结果(输入embedding +每层BiLSTM输出),实际对下游的任务可以拿2L+1个向量组合作为输入

语言模型:

9.2.24

损失函数:

9.2.25

模型的输出:

对每一个词输出就是2L+1个词向量,一种组合方式就是加权加到一起.

实际中加到一起之前, 可以先在同层做一下归一化,类似BN的操作,抵消每一层输出分布差异带来的区别.公式表示为:

9.2.26

当然也可以直接拼接的方式,拼接好之后送入到RNN中即可; 送入RNN的时候,可以在输入层,也可以在输出层(可以自由使用).

实现:https://github.com/allenai/bilm-tf

OpenAI GPT

  1. 进行预训练的结构变为transformer networks, 替换LSTM, 实现捕获更远距离的"依赖"
  2. 不使用auxiliary objective, 不想引入新的参数, 只使用少量参数进行fine-tune也可以得到很好的效果
  3. 核心是通过无监督的数据,学习一个高容量的embedding
  4. 类似图像fine-tune的做法,只在最后一层进行.
  5. 因为是语言模型,transform内部使用masked self attention,因为看不到下一个词.

还是一个语言模型,内部结构为Transformer结构:

9.2.24

其中 \(W_e\) 是对word的embedding,可以看到最后输出层的判别矩阵也是用的这个embedding.

一般进行fine-tune就是最后一层加上一个线性的分类器.

9.2.25

对于各种任务,处理方式如下图:

9.2.26

可以看到,对于QA问题,属于上图中的"Multiple Choice"类型, 处理的时候先对输入进行预处理,将Q和不同的Answer组成不同的输入序列.使用结束符号进行分割.后面接入线性的分类器.

官方地址:https://blog.openai.com/language-unsupervised/

BERT

  1. 传统语言模型假设生成的过程是从左到右,只可以看到左边的词,其实对于大多数任务(Classifier/QA)都是可以看到整个文本的
  2. 通过Mask的方式,设计可以看到两边的预训练目标.(其实在MaskGAN中已经这么用过),文本中Mask的比例略显随意
  3. 通过构造一个二分类模型,预测给定的下语句是否为真.这个目标是为了对QA这类问题后面fine-tune提高性能.(对QA的场景,这里可以理解为,有一些时候,下一句是上一句的"答案")

 

模型结构对比图:

9.2.27

 

输入的组成图:

9.2.28

其中Token Embedding中,如果是分类任务,就添加一个开始符号.做最后一层的fine-tune的时候也根据任务类型进行考虑.

Segment Embedding 用来表示子序列是不是同一个句子, 例如QA中属于Q这一部分还是A这一部分.对于只有一种句子类型的人物, 只是用 \(E_A\) 就可以了.

Position Embedding 是针对位置生成的embedding, 和以前的人物类似,本文中作者使用最长长度为512.

对于不同的任务是怎么进行fine-tune呢?下图是BERT使用的方式:

9.2.29

Github:https://github.com/google-research/bert

未经允许不得转载:大数据算法 » 无监督词向量/句向量:W2v/Glove/Swivel/ELMo/BERT

评论 抢沙发

*

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

关注大数据算法在工业界应用

本站的GitHub关于本站