神经翻译笔记4. 循环神经网络(RNN)
本文来自于如下来源
- [Neubig2017]第6节(主要来源,结构遵从此文)
- [Koehn2017]13.4.4、13.4.5、13.4.6三小节
- NNMNLP第14、15章
- 花书第十章
- CS224n第6、7讲(2019年春)
前面介绍的三种语言模型(N元语法、log-linear语言模型和神经网络语言模型)尽管在表示能力上逐渐变强,但是仍然没有摆脱一项桎梏:需要给定一个窗口大小,而且通常这个窗口宽度不会太大。但是语言里通常会有长距离依赖现象,例如He doesn’t have very much confidence in himself,这里himself只是受到句首He的影响——如果句首是She,那么末尾这个词就要变成herself了!这样的现象在英语里比较多,在其它语言里甚至可以超级多:一方面,很多语言形态更加丰富,名词有变格,动词有变位。另一方面,一些语言有自己独特的语法结构,例如德语里丧心病狂的句框结构/框型结构:ich muss morgen zur Uni gehen,这里实意动词gehen与其搭配的情态动词muss遥相呼应,在这种情况下,固定小窗口的语言模型能力显得不足
除却语法的层面,语义上也需要对单词的长距离依赖建模。这里最典型的问题是选择依赖/选择约束问题,即从语义上讲,当上文出现某个单词时,它会潜在地约束之后哪些单词更可能出现,哪些单词更不可能出现。例如前文出现eat,后文很可能出现fork(作为eat的器具)或者friend(作为一起eat的人),但是出现wall感觉就不太合理。这种依赖约束也可能横跨多个单词,难以被简单模型所捕捉
最后,文档内,句与句之间(或者句内),也需要遵守主题一致性和风格一致性。一篇讨论体育的文章不适合突然拐到母猪的产后护理,一篇严谨的学术论文(一般情况下)也不应该突然出现乡间俚语
综上所述,需要一种能力更强,能够捕捉词语长距离依赖关系的模型。在这种背景下,循环神经网络(Recurrent Neural Network, RNN)应运而生
普通RNN (Vanilla RNN)
普通RNN的核心思想是引入时刻的概念,此时每一时刻 t t t的隐藏单元 h t \boldsymbol{h}_t ht不再只依赖于这一时刻的模型输入 x t \boldsymbol{x}_t xt,也依赖于上一时刻的隐藏单元 h t − 1 \boldsymbol{h}_{t-1} ht−1,即
h t = { tanh ( W x h x t + W h h h t − 1 + b t ) t ≥ 1 0 o t h e r w i s e \boldsymbol{h}_t = \begin{cases} \tanh(\boldsymbol{W}_{xh}\boldsymbol{x}_t + \boldsymbol{W}_{hh}\boldsymbol{h}_{t-1} + \boldsymbol{b}_t) & t\ge 1 \\ \boldsymbol{0} & {\rm otherwise} \end{cases} ht={
tanh(Wxhxt+Whhht−1+bt)0t≥1otherwise
这样一来,若干个时刻之前的隐藏单元状态可以依次传输到当前的隐藏单元,使得模型可以对长距离依赖关系建模。引入输入层和softmax层后,模型的结构为
m t = M ⋅ , e t − 1 h t = { tanh ( W m h m t + W h h h t − 1 + b t ) t ≥ 1 0 o t h e r w i s e p t = s o f t m a x ( W h s h t + b s ) \begin{aligned} \boldsymbol{m}_t &= \boldsymbol{M}_{\cdot, e_{t-1}} \\ \boldsymbol{h}_t &= \begin{cases} \tanh(\boldsymbol{W}_{mh}\boldsymbol{m}_t + \boldsymbol{W}_{hh}\boldsymbol{h}_{t-1} + \boldsymbol{b}_t) & t\ge 1 \\ \boldsymbol{0} & {\rm otherwise} \end{cases} \\ \boldsymbol{p}_t &= {\rm softmax}(\boldsymbol{W}_{hs}\boldsymbol{h}_t + \boldsymbol{b}_s) \end{aligned} mthtpt=M⋅,et−1={
tanh(Wmhmt+Whhht−1+bt)0t≥1otherwise=softmax(Whsht+bs)
此时模型不需要再显式依赖上文的多个单词 (即在每一时刻 t t t只需要接收一个单词作为输入),上文的全部信息可以看做都包含在了上游传递过来的上一时刻隐藏状态 h t − 1 \boldsymbol{h}_{t-1} ht−1里
对上式记号稍作变化,
x ( t ) = E ⋅ , e ( t − 1 ) s ( t ) = { tanh ( U x ( t ) + W s ( t − 1 ) + b s ) t ≥ 1 0 o t h e r w i s e o ( t ) = V s ( t ) + b o y ^ ( t ) = s o f t m a x ( o ( t ) ) \begin{aligned} \boldsymbol{x}^{(t)} &= \boldsymbol{E}_{\cdot, e^{(t-1)}} \\ \boldsymbol{s}^{(t)} &= \begin{cases} \tanh(\boldsymbol{U}\boldsymbol{x}^{(t)} + \boldsymbol{W}\boldsymbol{s}^{(t-1)} + \boldsymbol{b}_s) & t\ge 1 \\ \boldsymbol{0} & {\rm otherwise} \end{cases} \\ \boldsymbol{o}^{(t)} &= \boldsymbol{V}\boldsymbol{s}^{(t)} + \boldsymbol{b}_o \\ \hat{\boldsymbol{y}}^{(t)} &= {\rm softmax}(\boldsymbol{o}^{(t)}) \end{aligned} x(t)s(t)o(t)y^(t)=E⋅,e(t−1)={
tanh(Ux(t)+Ws(t−1)+bs)0t≥1otherwise=Vs(t)+bo=softmax(o(t))
可以用如下示意图来表示上述RNN结构,其中右半部分可以看做是RNN网络的"展开形式"(图片来源:Nature)
可以将上面的模型描述简写为
x ( t ) = E ⋅ , e ( t − 1 ) s ( t ) = R N N ( x ( t ) , s ( t − 1 ) ) o ( t ) = V s ( t ) + b o y ^ ( t ) = s o f t m a x ( o ( t ) ) \begin{aligned} \boldsymbol{x}^{(t)} &= \boldsymbol{E}_{\cdot, e^{(t-1)}} \\ \boldsymbol{s}^{(t)} &= {\rm RNN}\left(\boldsymbol{x}^{(t)}, \boldsymbol{s}^{(t-1)}\right) \\ \boldsymbol{o}^{(t)} &= \boldsymbol{V}\boldsymbol{s}^{(t)} + \boldsymbol{b}_o \\ \hat{\boldsymbol{y}}^{(t)} &= {\rm softmax}\left(\boldsymbol{o}^{(t)}\right) \end{aligned} x(t)s(t)o(t)y^(t)=E⋅,e(t−1)=RNN(x(t),s(t−1))=Vs(t)+bo=softmax(o(t))
RNN的反向传播
(本节参考了《循环神经网络(RNN)模型与前向反向传播算法》和Recurrent Neural Networks Tutorial, Part 3 – Backpropagation Through Time and Vanishing Gradients)
由上面的模型描述可以看出,模型在第 t t t时刻的输出 o ( t ) \boldsymbol{o}^{(t)} o(t)不再只依赖于该时刻的隐藏状态 s ( t ) \boldsymbol{s}^{(t)} s(t),而是还依赖于上游所有时刻的隐藏状态 s ( 1 ) , … , s ( t − 1 ) \boldsymbol{s}^{(1)}, \ldots, \boldsymbol{s}^{(t-1)} s(1),…,s(t−1)。反过来, t t t时刻的隐藏状态 s ( t ) \boldsymbol{s}^{(t)} s(t)不止直接决定该时刻的输出 o ( t ) \boldsymbol{o}^{(t)} o(t),也直接影响了下一时刻隐藏状态 s ( t + 1 ) \boldsymbol{s}^{(t+1)} s(t+1)(此外还间接影响了下游所有隐藏状态,这里先不论),因此误差对 s ( t ) \boldsymbol{s}^{(t)} s(t)的梯度有两个直接来源。又因为 s ( t ) \boldsymbol{s}^{(t)} s(t)由参数 U \boldsymbol{U} U、 W \boldsymbol{W} W和 b \boldsymbol{b} b算出,因此这三个参数的更新不仅受到第 t t t时刻输出 o ( t ) \boldsymbol{o}^{(t)} o(t)的影响,也受到第 t + 1 t+1 t+1时刻隐藏状态 s ( t + 1 ) \boldsymbol{s}^{(t+1)} s(t+1)的影响。即反向传播时梯度会沿"时间"向上游传播,因此RNN的反向传播也被称作为经由时间的反向传播 (Back-Propagation Through Time, BPTT)
下面进行推导:对上面的模型描述引入一个中间记号,并稍作记号上的替换,有
a ( t ) = U x ( t ) + W s ( t − 1 ) + b s ( t ) = tanh ( a ( t ) ) o ( t ) = V s ( t ) + c y ^ ( t ) = s o f t m a x ( o ( t ) ) (1) \begin{aligned} \boldsymbol{a}^{(t)} &= \boldsymbol{U}\boldsymbol{x}^{(t)} + \boldsymbol{W}\boldsymbol{s}^{(t-1)} + \boldsymbol{b} \tag{1} \\ \boldsymbol{s}^{(t)} &= \tanh\left(\boldsymbol{a}^{(t)}\right) \\ \boldsymbol{o}^{(t)} &= \boldsymbol{V}\boldsymbol{s}^{(t)} + \boldsymbol{c} \\ \hat{\boldsymbol{y}}^{(t)} &= {\rm softmax}\left(\boldsymbol{o}^{(t)}\right) \end{aligned} a(t)s(t)o(t)y^(t)=Ux(t)+Ws(t−1)+b=tanh(a(t))=Vs(t)+c=softmax(o(t))(1)
假设使用交叉熵作为模型的损失函数,由于每个时刻都有一个最终输出 y ^ ( t ) \hat{\boldsymbol{y}}^{(t)} y^(t),因此模型的总损失函数为
E ( y , y ^ ) = ∑ t E ( t ) ( y ( t ) , y ^ ( t ) ) E ( t ) ( y ( t ) , y ^ ( t ) ) = − ∑ i = 1 ∣ V ∣ y i ( t ) log y ^ i ( t ) \begin{aligned} E(\boldsymbol{y}, \hat{\boldsymbol{y}}) &= \sum_t E^{(t)}\left(\boldsymbol{y}^{(t)}, \hat{\boldsymbol{y}}^{(t)}\right) \\ E^{(t)}\left(\boldsymbol{y}^{(t)}, \hat{\boldsymbol{y}}^{(t)}\right) &= -\sum_{i=1}^{|V|}y^{(t)}_{i}\log\hat{y}^{(t)}_{i} \end{aligned} E(y,y^)E(t)(y(t),y^(t))=t∑E(t)(y(t),y^(t))=−i=1∑∣V∣yi(t)logy^i(t)
假设模型各参数、输入、输出和中间结果维度为
y ^ ( t ) , o ( t ) , c ∈ R ∣ V ∣ × 1 s ( t ) , a ( t ) , b ∈ R h × 1 x ∈ R d × 1 U ∈ R h × d W ∈ R h × h V ∈ R ∣ V ∣ × h \begin{aligned} \hat{\boldsymbol{y}}^{(t)}, \boldsymbol{o}^{(t)}, \boldsymbol{c} &\in \mathbb{R}^{|V| \times 1} \\ \boldsymbol{s}^{(t)}, \boldsymbol{a}^{(t)}, \boldsymbol{b} &\in \mathbb{R}^{h \times 1} \\ \boldsymbol{x} &\in \mathbb{R}^{d\times 1} \\ \boldsymbol{U} &\in \mathbb{R}^{h \times d} \\ \boldsymbol{W} &\in \mathbb{R}^{h \times h} \\ \boldsymbol{V} &\in \mathbb{R}^{|V| \times h} \\ \end{aligned} y^(t),o(t),cs(t),a(t),bxUWV∈R∣V∣×1∈Rh×1∈Rd×1∈Rh×d∈Rh×h∈R∣V∣×h
由于 V \boldsymbol{V} V和 c \boldsymbol{c} c不依赖于之前时刻的内容,因此比较容易计算。考虑到
∂ E ∂ o ( t ) = ∂ E ∂ E ( t ) ∂ E ( t ) ∂ o ( t ) = ∂ E ( t ) ∂ o ( t ) = y ^ ( t ) − y ( t ) : = δ 1 ( t ) \frac{\partial E}{\partial \boldsymbol{o}^{(t)}} = \frac{\partial E}{\partial E^{(t)}}\frac{\partial E^{(t)}}{\partial \boldsymbol{o}^{(t)}} =\frac{\partial E^{(t)}}{\partial \boldsymbol{o}^{(t)}} = \hat{\boldsymbol{y}}^{(t)} - \boldsymbol{y}^{(t)} := \boldsymbol{\delta}^{(t)}_1 ∂o(t)∂E=∂E(t)∂E∂o(t)∂E(t)=∂o(t)∂E(t)=y^(t)−y(t):=δ1(t)
可得
∂ E ∂ c = ∑ t = 1 T ∂ E ( t ) ∂ o ( t ) ∂ o ( t ) ∂ c = ∑ t = 1 T δ 1 ( t ) ∂ E ∂ V = ∑ t = 1 T ∂ E ( t ) ∂ o ( t ) ∂ o ( t ) ∂ V = δ 1 ( t ) ( s ( t ) ) T = ∑ t = 1 T δ 1 ( t ) × s ( t ) \begin{aligned} \frac{\partial E}{\partial \boldsymbol{c}} &= \sum_{t=1}^T\frac{\partial E^{(t)}}{\partial \boldsymbol{o}^{(t)}}\frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{c}} = \sum_{t=1}^T\boldsymbol{\delta}_1^{(t)} \\ \frac{\partial E}{\partial \boldsymbol{V}} &= \sum_{t=1}^T\frac{\partial E^{(t)}}{\partial \boldsymbol{o}^{(t)}} \frac{\partial \boldsymbol{o}^{(t)}}{\partial \boldsymbol{V}} = \boldsymbol{\delta}_1^{(t)}\left(\boldsymbol{s}^{(t)}\right)^\mathsf{T} = \sum_{t=1}^T\boldsymbol{\delta}_1^{(t)}\times \boldsymbol{s}^{(t)} \end{aligned} ∂c∂E∂V∂E=t=1∑T∂o(t)∂E(t)∂c∂o(t)=t=1∑Tδ1(t)=