前言
cs224n 第九讲,讲解了机器翻译以及GRU、lstm。
机器翻译
传统机器翻译
传统机器翻译的目标就是找到条件概率最大的e:
e
^
=
a
r
g
m
a
x
e
p
(
e
∣
f
)
=
a
r
g
m
a
x
e
p
(
f
∣
e
)
p
(
e
)
\hat e=argmax_ep(e|f)=argmax_ep(f|e)p(e)
e^=argmaxep(e∣f)=argmaxep(f∣e)p(e)
其中f代表源文,e代表译文。在进行机器翻译时,
p
(
f
∣
e
)
p(f|e)
p(f∣e)是通过训练平行语料得到的翻译模型,
p
(
e
)
p(e)
p(e)是在非平行语料译文中得到的。如下图所示:
第一步:对齐
这一步就是上述的Translation Model的步骤,目的是找到源文中的词语应该对应翻译到译文中哪个词语,这一步中存在很多问题。
一个句子中源文和译文的词语并不完全对称,比如源文中没有译文某个词语对应的单词,更复杂的还有一对多的情况。如下图所示:
或者多对多、多对一的情况:
其他步骤
所以真正的对齐方式是源文中每个单词都有多个可能的对应译文单词:
最终从海量组合中选出最佳译文组合,所以这是一个最佳搜索的问题。
传统机器翻译
课程中讲到的传统机器翻译只是很小的一部分
- 跳过了大量重要的细节
- 传统机器翻译中有大量的人工特征工程
- 是一个相当复杂的系统
- 传统机器翻译时多个不同部分组合完成,需要多方协作,比如重新排序模型、语言模型等,这些都需要单独训练
深度学习来拯救
简单的RNN
直接用RNN接受源文,并预测译文。
图中红圈圈住的地方是Encoder的输出,作为Decoder的输入,这部分所代表的特征需要捕捉到整个源文短语的语义,但是RNN一般只能捕捉到五六个单词。
在这个模型中:
Encoder部分:
h
t
=
Φ
(
h
t
−
1
,
x
t
)
=
f
(
W
(
h
h
)
h
t
−
1
+
W
(
h
x
)
x
t
)
h_t=\Phi(h_{t-1},x_t)=f(W^{(hh)}h_{t-1}+W^{(hx)}x_t)
ht=Φ(ht−1,xt)=f(W(hh)ht−1+W(hx)xt)
Decoder部分:
h
t
=
Φ
(
h
t
−
1
)
=
f
(
W
(
h
h
)
h
t
−
1
)
h_t=\Phi(h_{t-1})=f(W^{(hh)}h_{t-1})
ht=Φ(ht−1)=f(W(hh)ht−1)
y
t
=
s
o
f
t
m
a
x
(
W
(
s
)
h
t
)
y_t=softmax(W^{(s)}h_t)
yt=softmax(W(s)ht)
最后,对于所有目标词最小化其交叉熵损失:
m
a
x
Θ
1
N
∑
n
=
1
N
l
o
g
p
Θ
(
y
(
n
)
∣
x
(
n
)
)
max_{\Theta}\frac{1}{N}\sum_{n=1}^Nlogp_{\Theta}(y^{(n)}|x^{(n)})
maxΘN1n=1∑NlogpΘ(y(n)∣x(n))
课程中提到的问题:
- 翻译模型会自主捕获语法或人类的语言直觉
- Decoder部分需要有一个终止单词“BA”,否则会一直输出译文
RNN扩展
1.对于encoder和decoder训练不同的权重
前后的颜色代表不同的权重矩阵
2.改变decoder的隐层输入
- 前一时刻隐层 h t − 1 h_{t-1} ht−1
- encoder最后的输出 c c c
- decoder的前一个预测结果
y
t
−
1
y_{t-1}
yt−1
所以decoder的函数变为:
h t = Φ ( h t − 1 , c , y t − 1 ) h_t=\Phi(h_{t-1},c,y_{t-1}) ht=Φ(ht−1,c,yt−1)
这里通过加上 y t − 1 y_{t-1} yt−1可以防止模型连续生成同一个单词。
3.深度RNN
- 使用双向Encoder
- 采用逆序输入,ABC->XY变成CBA->XY。这是因为A更倾向于被翻译成X,所以使得A与X更近一些,避免梯度消失导致A的语义影响变小影响输出。当然,C和Y的距离也就变远了。
- 主要的改进:GRU
主要思想:
- GRU这种单元在长依赖中可以让模型学习如何取舍当前记忆。
- 允许错误信息流转,基于输入,这些错误信息会想不同的方向以不同的强度传递
update gate:
z t = σ ( W ( z ) x t + U ( z ) h t − 1 ) z_t=\sigma(W^{(z)}x_t+U^{(z)}h_{t-1}) zt=σ(W(z)xt+U(z)ht−1)
reset gate:
r t = σ ( W ( r ) x t + U ( r ) h t − 1 ) r_t=\sigma(W^{(r)}x_t+U^{(r)}h_{t-1}) rt=σ(W(r)xt+U(r)ht−1)
new memory content:
h t ~ = t a n h ( W x t + r t ∘ U h t − 1 ) \widetilde{h_t}=tanh(Wx_t+r_t\circ{Uh_{t-1}}) ht =tanh(Wxt+rt∘Uht−1)
如果reset gate单元是0,那么这里的new memory content就只保留当前输入的信息,忘记之前所有的记忆。
final memory:
h t = z t ∘ h t − 1 + ( 1 − z t ) ∘ h t ~ h_t=z_t\circ{h_{t-1}}+(1-z_t)\circ{\widetilde{h_t}} ht=zt∘ht−1+(1−zt)∘ht
如果 z t z_t zt是单位向量,那么就只是复制上一时刻隐层信息。
示意图如下:
上图中,虚线代表某个gate的调节作用。隐藏层取决于上一个时刻的隐藏层和新的记忆,而update gate负责调节它们的比例,reset gate和输入共同决定新的记忆
有人问这个reset gate是不是多余的,是不是可以直接让 h t = z t ∘ h t − 1 h_t=z_t\circ{h_{t−1}} ht=zt∘ht−1。做是的确可以这么做,但 x t x_t xt永远无法把之前的记忆 h t − 1 h_{t−1} ht−1“挤出去”,因为 z t z_t zt是个求和的形式。
- LSTMs
input gate:
i t = σ ( W ( i ) x t + U ( i ) h t − 1 ) i_t=\sigma(W^{(i)}x_t+U^{(i)}h_{t-1}) it=σ(W(i)xt+U(i)ht−1)
forget gate:
f t = σ ( W ( f ) x t + U ( f ) h t − 1 ) f_t=\sigma(W^{(f)}x_t+U^{(f)}h_{t-1}) ft=σ(W(f)xt+U(f)ht−1)
output gate:
o t = σ ( W ( o ) x t + U ( o ) h t − 1 ) o_t=\sigma(W^{(o)}x_t+U^{(o)}h_{t-1}) ot=σ(W(o)xt+U(o)ht−1)
new memory cell:
c t ~ = t a n h ( W ( c ) x t + U ( c ) h t − 1 ) \widetilde{c_t}=tanh(W^{(c)}x_t+U^{(c)}h_{t-1}) ct =tanh(W(c)xt+U(c)ht−1)
final memory cell:
c t = f t ∘ c t − 1 + i t ∘ c t ~ c_t=f_t\circ{c_{t-1}}+i_t\circ{\widetilde{c_t}} ct=ft∘ct−1+it∘ct
final hidden state:
h t = o t ∘ t a n h ( c t ) h_t=o_t\circ{tanh(c_t)} ht=ot∘tanh(ct)
这里也算是老生常谈了,输入门、遗忘门、输出门分别控制保留多少当前输入信息,保留多少上一时刻信息、输出多少信息。另外将经过输入门和遗忘门处理后的信息进行相加得到。
一张LSTM的经典图: