文章目录
- 一、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}) (st−1,st,st+1),输入值 s t s_{t} st,输出值 ( s t − 1 , s t + 1 ) (s_{t−1},s_{t+1}) (st−1,st+1),具体模型结构如下图:
图中
<
e
o
s
>
<eos>
<eos> 表示句子的结尾。在这里:
- s t s_{t} st: IcouldseethecatonthestepsstIcouldseethecatonthesteps
- s t − 1 s_{t-1} st−1:Igotbackhomest−1Igotbackhome
- s t + 1 s_{t+1} st+1:Thiswasstrangest+1Thiswasstrange
具体展开应该是这个样子的:
二、模型(encoder-decoder)
skip-thought模型的神经网络结构是在机器翻译中最常用的 Encoder-Decoder 架构,而在 Encoder-Decoder 架构中所使用的模型是GRU模型。因此在训练句子向量时同样要使用到词向量,编码器输出的结果为句子中最后一个词所输出的向量。具体模型实现的公式如下:
1、编码器:
公式和GRU网络中的公式一模一样。
h
t
h_{t}
ht表示
t
t
t 时刻的隐层的输出结果。
2、解码器:
这里有两个解码器,一个解码器用来预测句子 S i − 1 S_{i-1} Si−1,即前一句, 而另一个解码器用来预测句子 S i + 1 S_{i+1} Si+1,即后一句。下面的公式是用来解码后一句 S i + 1 S_{i+1} Si+1的。不过 S i − 1 S_{i-1} Si−1解码与这类似
其中
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}^{<t},h_{i})+\sum_{t}logP(w_{i-}^{t}|w_{i-1}^{<t},h_{i}) t∑logP(wi+1t∣wi+1<t,hi)+t∑logP(wi−t∣wi−1<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} v∈Vw2v, v ′ ∈ V r n n v′∈V_{rnn} v′∈Vrnn 。
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
- 首先,我们必须添加一个字符去标识序列的开始,定义另一个字符去标识序列的结束。我们分别用“[START]”和“[END]”来表示。
[START] Mary had a little lamb whose fleece was white as snow [END]
- 下一步,我们以“[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, ?
- 最后,模型会学习到正确的序列,或者正确的序列统计属性。
但是,当生成的序列与训练期间模型看到的不同时(即遇到了训练集中不存在的数据),该方法就会导致在实践中使用时模型效果不好 |
参考资料
- 论文:https://arxiv/pdf/1506.06726v1.pdf
- 博客:http://sanyam5.github.io/my-thoughts-on-skip-thoughts/
- 代码:https://github/sanyam5/skip-thoughts
更多推荐
Skip-Thought Vector学习笔记
发布评论