Skip-Thought Vector学习笔记

文章目录

    • 一、skip-thought思想及结构
    • 二、模型(encoder-decoder)
        • 1、编码器:
        • 2、解码器:
        • 3、损失函数:
    • 三、 词汇扩展:
    • 四、训练模型技巧
    • 参考资料

一、skip-thought思想及结构

  skip-thought模型结构借助了skip-gram的思想。在skip-gram中,是以中心词来预测上下文的词;在skip-thought同样是利用中心句子来预测上下文的句子,其数据的结构可以用一个三元组表示 ( s t − 1 , s t , s t + 1 ) (s_{t−1},s_{t},s_{t+1}) (st1,st,st+1),输入值 s t s_{t} st,输出值 ( s t − 1 , s t + 1 ) (s_{t−1},s_{t+1}) (st1,st+1),具体模型结构如下图:

Skip-Thought Vector学习笔记_第1张图片
图中 < e o s > <eos> 表示句子的结尾。在这里:

  • s t s_{t} st: IcouldseethecatonthestepsstIcouldseethecatonthesteps
  • s t − 1 s_{t-1} st1:Igotbackhomest−1Igotbackhome
  • s t + 1 s_{t+1} st+1:Thiswasstrangest+1Thiswasstrange

具体展开应该是这个样子的:
Skip-Thought Vector学习笔记_第2张图片

二、模型(encoder-decoder)

  skip-thought模型的神经网络结构是在机器翻译中最常用的 Encoder-Decoder 架构,而在 Encoder-Decoder 架构中所使用的模型是GRU模型。因此在训练句子向量时同样要使用到词向量,编码器输出的结果为句子中最后一个词所输出的向量。具体模型实现的公式如下:

1、编码器:

Skip-Thought Vector学习笔记_第3张图片
  公式和GRU网络中的公式一模一样。 h t h_{t} ht表示 t t t 时刻的隐层的输出结果。

2、解码器:

  这里有两个解码器,一个解码器用来预测句子 S i − 1 S_{i-1} Si1,即前一句, 而另一个解码器用来预测句子 S i + 1 S_{i+1} Si+1,即后一句。下面的公式是用来解码后一句 S i + 1 S_{i+1} Si+1的。不过 S i − 1 S_{i-1} Si1解码与这类似

Skip-Thought Vector学习笔记_第4张图片
  其中 C r C_{r} Cr, C z C_{z} Cz, C C C 分别用来对重置门,更新门,隐层进行向量偏置的。重置门、更新门和隐层中都考虑了Encoder输出的隐层信息 h i h_{i} hi

3、损失函数:

  目标函数就是decoder中预测前一句的损失函数与预测后一句的损失函数之和。

∑ t l o g P ( w i + 1 t ∣ w i + 1 < t , h i ) + ∑ t l o g P ( w i − t ∣ w i − 1 < t , h i ) \sum_{t}logP(w_{i+1}^{t}|w_{i+1}^{tlogP(wi+1twi+1<t,hi)+tlogP(witwi1<t,hi)

三、 词汇扩展:

  词汇扩展主要是为了弥补我们的 Decoder 模型中词汇不足的问题。具体的做法就是:

1)我们用 V w 2 v V_{w2v} Vw2v 表示我们训练的词向量空间,用 V r n n V_{rnn} Vrnn 表示我们模型中的词向量空间,在这里 V w 2 v V_{w2v} Vw2v 是远远大于 V r n n V_{rnn} Vrnn 的。

2)引入一个矩阵 W W W来构建一个映射函数:f: V r n n V_{rnn} Vrnn−> V w 2 v V_{w2v} Vw2v 。使得有 v ′ = W v v′=Wv v=Wv ,其中 v ∈ V w 2 v v∈V_{w2v} vVw2v, v ′ ∈ V r n n v′∈V_{rnn} vVrnn

3)通过映射函数就可以将任何在 V w 2 v V_{w2v} Vw2v 中的词映射到 V r n n V_{rnn} Vrnn 中。

四、训练模型技巧

  在代码实现中主要要注意的是用到了Teacher Forcing方法。Teacher Forcing是一种用来快速而有效地训练循环神经网络模型的方法,这种方法以上一时刻的输出作为下一时刻的输入,是一种能够解决缓慢收敛和不稳定的方法。在训练时,Teacher forcing是通过使用第 t t t 时刻的来自于训练集的期望输出 y ( t ) y(t) y(t)作为下一时刻的输入 x ( t + 1 ) x(t+1) x(t+1),而不是直接使用网络的实际输出。

示例:
  给定的如下输入序列.我们需要训练模型,使得在给定序列中上一个单词的情况下,来得到序列中的下一个单词。

Mary had a little lamb whose fleece was white as snow
  1. 首先,我们必须添加一个字符去标识序列的开始,定义另一个字符去标识序列的结束。我们分别用“[START]”和“[END]”来表示。
[START] Mary had a little lamb whose fleece was white as snow [END]
  1. 下一步,我们以“[START]”作为输入,让模型生成下一个单词。想象一下模型生成了单词“a”,但我们期望的是“Mary”
X,						yhat
[START],				a

简单地,我们能够将“a”作为生成序列中剩余子序列的输入。

X,						yhat
[START], a,				?

  你可以看到模型偏离了预期轨道,并且会因为它生成的每个后续单词而受到惩罚。这使学习速度变慢,且模型不稳定。
相反,我们可以使用Teacher forcing。

在第一步中,当模型生成“a”作为输出时,在计算完损失后,我们能够丢掉这个这个输出,而已“Mary作为”生成序列中剩余子序列的输入。

X,						yhat
[START], Mary,			?

然后,我们反复去处理每一个输入-输出对。

X,						yhat
[START], 				?
[START], Mary,			?
[START], Mary, had,		?
[START], Mary, had, a,	?
  1. 最后,模型会学习到正确的序列,或者正确的序列统计属性。
但是,当生成的序列与训练期间模型看到的不同时(即遇到了训练集中不存在的数据),该方法就会导致在实践中使用时模型效果不好

参考资料

  • 论文:https://arxiv.org/pdf/1506.06726v1.pdf
  • 博客:http://sanyam5.github.io/my-thoughts-on-skip-thoughts/
  • 代码:https://github.com/sanyam5/skip-thoughts

你可能感兴趣的:(自然语言处理)