RNN总结

1. 普通RNN

对于单隐藏层的多层感知机 H = ϕ ( X W x h + b h ) \boldsymbol{H}=\phi \left( \boldsymbol{XW}_{xh}+\boldsymbol{b}_h \right) O = H W h q + b q \boldsymbol{O}=\boldsymbol{HW}_{hq}+\boldsymbol{b}_q 其中 X R n × d \boldsymbol{X}\in \mathbb{R}^{n\times d} W x h R d × h \boldsymbol{W_{xh}}\in \mathbb{R}^{d\times h} b h R 1 × h \boldsymbol{b_h}\in \mathbb{R}^{1\times h} O R n × q \boldsymbol{O}\in \mathbb{R}^{n\times q} W h q R h × q \boldsymbol{W_{hq}}\in \mathbb{R}^{h\times q} b q R 1 × q \boldsymbol{b_q}\in \mathbb{R}^{1\times q}


传统的神经网络做不到延续性(它们没办法保留对前文的理解)。但是,循环神经网络可以做到。在RNNs的网络中,有一个循环的操作,使得它们能够保留之前学习到的内容。现在我们考虑输⼊数据存在时间相关性的情况,我们保存上⼀时间步的隐藏变量 H t 1 H_{t-1} ,并引⼊⼀个新的权重参数 W h h R h × h \boldsymbol{W_{hh}}\in \mathbb{R}^{h\times h} 时间步 t t 的隐藏变量的计算由当前时间步的输⼊上⼀时间步的隐藏变量共同决定: H t = ϕ ( X t W x h + H t 1 W h h + b h ) \boldsymbol{H}_t=\phi \left( \boldsymbol{X}_t\boldsymbol{W}_{xh}+\boldsymbol{H}_{t-1}\boldsymbol{W}_{hh}+\boldsymbol{b}_h \right) 从上式可知,这⾥的隐藏变量能够捕捉截⾄当前时间步的序列的历史信息,该隐藏变量也称为隐藏状态。由于隐藏状态在当前时间步的定义使⽤了上⼀时间步的隐藏状态,上式的计算是循环的。使⽤循环计算的⽹络即循环神经⽹络。在时间步 t t ,输出层的输出和多层感知机中的计算类似: O t = H t W h q + b q \boldsymbol{O}_t=\boldsymbol{H}_t\boldsymbol{W}_{hq}+\boldsymbol{b}_q
循环神经⽹络的参数包括隐藏层的权重 W x h R d × h \boldsymbol{W_{xh}}\in \mathbb{R}^{d\times h} W h h R h × h \boldsymbol{W_{hh}}\in \mathbb{R}^{h\times h} 和偏差 b h R 1 × h \boldsymbol{b_h}\in \mathbb{R}^{1\times h} ,以及输出层的权重 W h q R h × q \boldsymbol{W_{hq}}\in \mathbb{R}^{h\times q} 和偏差 b q R 1 × q \boldsymbol{b_q}\in \mathbb{R}^{1\times q} ,图1.1展示了循环神经⽹络在3个相邻时间步的计算逻辑。即便在不同时间步,循环神经⽹络也始终使⽤这些模型参数,即不同时间步参数共享。因此,循环神经⽹络模型参数的数量不随时间步的增加⽽增⻓
在这里插入图片描述
注:

  1. 上面式子中 W t R n × d \boldsymbol{W_t}\in \mathbb{R}^{n\times d} 是序列中时间步 t t 的⼩批量输⼊,如下例子中一个batch包含三句话,则 X 1 X_1 就是{我,台,中}三个汉字词向量(d维)组成的矩阵(3 x d); X 2 X_2 是{爱,湾,国}三个字组成的矩阵,以此类推。
我爱中国
台湾是中国的一部分
中国台湾
  1. 公式中 ϕ \phi 是激活函数,普通rnn一般都是用的tanh
  2. 由上面的图可知,经典的RNN只能处理输入输出等长的数据,因此在实际中应用较少

1.2 RNN的反向传播

解释了当时间步 T T 较大时,RNN容易出现梯度爆炸和梯度消失

TODO...

reference
动手学深度学习P218

1.3 普通RNN的编程实现

TODO...

2. 门控循环单元GRU

普通RNN当时间步数较大时容易出现梯度消失或梯度爆炸,虽然裁剪梯度可以应对梯度爆炸,但⽆法解决梯度衰减的问题。所以循环神经⽹络在实际中较难捕捉时间序列中时间步距离较⼤的依赖关系

⻔控循环神经⽹络(gated recurrent neural network)的提出,正是为了更好地捕捉时间序列中时间步距离较⼤的依赖关系。它通过可以学习的⻔来控制信息的流动。它引⼊了重置⻔(reset gate)和更新⻔(update gate)的概念。

2.1 重置门和更新门

⻔控循环单元中的重置⻔和更新⻔的输⼊均为当前时间步输⼊ X t X_t 与上⼀时间步隐藏状态 H t 1 H_{t-1} ,假设隐藏单元个数为 h h ,给定时间步 t t 的⼩批量输⼊ X t R n × d \boldsymbol{X_{t}}\in \mathbb{R}^{n\times d} (样本数为 n n ,输⼊个数为 d d )和上⼀时间步隐藏状态 H t 1 R n × h \boldsymbol{H_{t-1}}\in \mathbb{R}^{n\times h} 。重置⻔ R t R n × h \boldsymbol{R_{t}}\in \mathbb{R}^{n\times h} 和更新⻔ Z t R n × h \boldsymbol{Z_{t}}\in \mathbb{R}^{n\times h} 的计算如下:
R t = σ ( X t W x r + H t 1 W h r + b r ) Z t = σ ( X t W x z + H t 1 W h z + b z ) \begin{aligned} \boldsymbol{R}_t&=\sigma \left( \boldsymbol{X}_t\boldsymbol{W}_{xr}+\boldsymbol{H}_{t-1}\boldsymbol{W}_{hr}+\boldsymbol{b}_r \right)\\ \boldsymbol{Z}_t&=\sigma \left( \boldsymbol{X}_t\boldsymbol{W}_{xz}+\boldsymbol{H}_{t-1}\boldsymbol{W}_{hz}+\boldsymbol{b}_z \right)\\ \end{aligned} 其中 W x r , W x z R d × h \boldsymbol{W}_{xr},\boldsymbol{W}_{xz}\in \mathbb{R}^{d\times h} W h r , W h z R h × h \boldsymbol{W}_{h r}, \boldsymbol{W}_{h z} \in \mathbb{R}^{h \times h} 是权重参数, b r , b z R 1 × h \boldsymbol{b}_{r}, \boldsymbol{b}_{z} \in \mathbb{R}^{1 \times h} 是偏差参数。sigmoid函数可以将元素的值变换到0和1之间。因此,重置⻔和更新⻔中每个元素的值域都是[0, 1] 。
在这里插入图片描述

2.2 候选隐藏状态

⻔控循环单元将计算候选隐藏状态来辅助稍后的隐藏状态计算,如下图所示,我们将当前时间步重置⻔的输出与上⼀时间步隐藏状态做按元素乘法(符号为 \odot )。如果重置⻔中元素值接近0,那么意味着重置对应隐藏状态元素为0,即丢弃上⼀时间步的隐藏状态。如果元素值接近1,那么表示保留上⼀时间步的隐藏状态。然后,将按元素乘法的结果与当前时间步的输⼊连结,再通过含激活函数tanh的全连接层计算出候选隐藏状态,其所有元素的值域为[-1, 1] 。
在这里插入图片描述
具体来说,时间步 t t 的候选隐藏状态 H ~ t R n × h \boldsymbol{\tilde { H }}_{t} \in \mathbb{R}^{n \times h} 的计算为
H ~ t = tanh ( X t W x h + ( R t H t 1 ) W h h + b h ) \tilde{\boldsymbol{H}}_{t}=\tanh \left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}+\left(\boldsymbol{R}_{t} \odot \boldsymbol{H}_{t-1}\right) \boldsymbol{W}_{h h}+\boldsymbol{b}_{h}\right)
其中 W x h R d × h \boldsymbol{{ W }}_{xh} \in \mathbb{R}^{d \times h} W h h R h × h \boldsymbol{ { W }}_{hh} \in \mathbb{R}^{h \times h} 是权重参数, b h R 1 × h \boldsymbol{ { b }}_{h} \in \mathbb{R}^{1 \times h} 是偏差参数;从上面可以看出,重置⻔控制了上⼀时间步的隐藏状态如何流⼊当前时间步的候选隐藏状态。⽽上⼀时间步的隐藏状态可能包含了时间序列截⾄上⼀时间步的全部历史信息。因此,重置⻔可以⽤来丢弃与预测⽆关的历史信息。

2.3 隐藏状态

时间步 t t 的隐藏状态 H t H_{t} 的计算使⽤当前时间步的更新⻔ Z t Z_{t} 来对上⼀时间步的隐藏状态 H t 1 H_{t-1} 和当前时间步的候选隐藏状态 H ~ t 1 \tilde{H}_{t-1} 做组合:
H t = Z t H t 1 + ( 1 Z t ) H ~ t \boldsymbol{H}_{t}=\boldsymbol{Z}_{t} \odot \boldsymbol{H}_{t-1}+\left(1-\boldsymbol{Z}_{t}\right) \odot \tilde{\boldsymbol{H}}_{t}
更新⻔可以控制隐藏状态应该如何被 包含当前时间步信息的候选隐藏状态所更新,如下图所示。
在这里插入图片描述
假设更新⻔在时间步 t t^{\prime} t t 之间⼀直近似1。那么,在时间步 t t^{\prime} t t 之间的输⼊信息⼏乎没有流⼊时间步 t t 的隐藏状态 H t H_{t} 。实际上,这可以看作是较早时刻的隐藏状态 H t 1 \boldsymbol{H}_{t^{\prime}-1} ⼀直通过时间保存并传递⾄当前时间步 t t , 这个设计可以应对循环神经⽹络中的梯度衰减问题 **[1]**并更好地捕捉时间序列中时间步距离较⼤的依赖关系。
注意:
[1]. 上面标注【1】处的解释:出现梯度爆炸或梯度消失的原因是因为下面这个式子中次数太高

L h t = i = t T ( W h h ) T i W q h L o T + t i \frac{\partial L}{\partial \boldsymbol{h}_{t}}=\sum_{i=t}^{T}\left(\boldsymbol{W}_{h h}^{\top}\right)^{T-i} \boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{T+t-i}}

而采用GRU这种门结构,假设更新⻔在时间步 t t^{\prime} t t 之间⼀直近似1。那么,在时间步 t t^{\prime} t t 之间的输⼊信息⼏乎没有流⼊时间步 t t 的隐藏状态 H t H_{t} 。实际上,这可以看作是较早时刻的隐藏状态 H t 1 \boldsymbol{H}_{t^{\prime}-1} ⼀直通过时间保存并传递⾄当前时间步 t t ,这样即使时间步在增加,但是指数次数并未增加,从而降低梯度消失的风险。

[2]. 重置⻔有助于捕捉时间序列⾥短期的依赖关系;更新⻔有助于捕捉时间序列⾥⻓期的依赖关系

2.4 GRU编程实现

TODO...

3. 长短期记忆(LSTM)

LSTM 中引⼊了3个⻔,即输⼊⻔(input gate)、遗忘⻔(forget gate)和输出⻔(output gate),以及与隐藏状态形状相同的记忆细胞,从⽽记录额外的信息。

3.1 输入门、遗忘门和输出门

⻓短期记忆的⻔的输⼊均为当前时间步输⼊ X t X_t 与上⼀时间步隐藏状态 H t 1 H_{t-1} ,输出由激活函数为sigmoid函数的全连接层计算得到。如此⼀来,这3个⻔元素的值域均为[0, 1] 。
在这里插入图片描述
具体来说,假设隐藏单元个数为 h h ,给定时间步 t t 的小批量输入 W t R n × d \boldsymbol{{ W }}_{t} \in \mathbb{R}^{n \times d} (样本数为 n n ,输⼊个数为 d d )和上⼀时间步隐藏状态 H t 1 R n × h \boldsymbol{{ H}}_{t-1} \in \mathbb{R}^{n \times h} 。时间步 t t 的输⼊⻔ I t R n × h \boldsymbol{{ I}}_{t} \in \mathbb{R}^{n \times h} 、遗忘门 F t R n × h \boldsymbol{{ F}}_{t} \in \mathbb{R}^{n \times h} 、输出门 O t R n × h \boldsymbol{{ O}}_{t} \in \mathbb{R}^{n \times h} 分别计算如下:
I t = σ ( X t W x i + H t 1 W h i + b i ) F t = σ ( X t W x f + H t 1 W h f + b f ) O t = σ ( X t W x o + H t 1 W h o + b o ) \begin{array}{l} \boldsymbol{I}_{t}=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x i}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h i}+\boldsymbol{b}_{i}\right) \\ \boldsymbol{F}_{t}=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x f}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h f}+\boldsymbol{b}_{f}\right) \\ \boldsymbol{O}_{t}=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x o}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h o}+\boldsymbol{b}_{o}\right) \end{array}
其中的 W x i , W x f , W x o R d × h W_{xi},W_{xf},\boldsymbol{{ W}}_{xo} \in \mathbb{R}^{d \times h} W h i , W h f , W h o R h × h W_{hi},W_{hf},\boldsymbol{{ W}}_{ho} \in \mathbb{R}^{h \times h} 是权重参数, b i , b f , b o R 1 × h b_i,b_f,\boldsymbol{{ b}}_{o} \in \mathbb{R}^{1 \times h} 是偏差参数。

3.2 候选记忆细胞

如下图所示,时间步 t t 的候选记忆细胞 C t ~ R n × h \tilde{\boldsymbol{{C}}_{t} }\in \mathbb{R}^{n \times h} 的计算为:
C ~ t = tanh ( X t W x c + H t 1 W h c + b c ) \tilde{\boldsymbol{C}}_{t}=\tanh \left(\boldsymbol{X}_{t} \boldsymbol{W}_{x c}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h c}+\boldsymbol{b}_{c}\right)
其中 W x c R n × h \boldsymbol{{W}}_{xc} \in \mathbb{R}^{n \times h} W h c R h × h \boldsymbol{{W}}_{hc}\in \mathbb{R}^{h\times h} 是权重参数, b c R 1 × h \boldsymbol{{b}}_{c}\in \mathbb{R}^{1\times h} 是偏差参数。
在这里插入图片描述

3.3 记忆细胞

通过元素值域在 [0, 1] 的输⼊⻔、遗忘⻔和输出⻔来控制隐藏状态中信息的流动,这⼀般也是通过使⽤按元素乘法来实现的。当前时间步记忆细胞 C t R n × h \boldsymbol{{C}}_{t} \in \mathbb{R}^{n \times h} 的计算组合了上⼀时间步记忆细胞当前时间步候选记忆细胞的信息,并通过遗忘⻔输⼊⻔来控制信息的流动:
C t = F t C t 1 + I t C ~ t \boldsymbol{C}_{t}=\boldsymbol{F}_{t} \odot \boldsymbol{C}_{t-1}+\boldsymbol{I}_{t} \odot \tilde{\boldsymbol{C}}_{t}
如下图所示,遗忘门控制上一时间步的记忆细胞 C t 1 C_{t-1} 中的信息是否传递到当前时间步,⽽输⼊⻔则控制当前时间步的输⼊ X t X_t 通过候选记忆细胞 C t ~ \tilde{C_t} 如何流入当前前时间步的记忆细胞。如果遗忘⻔⼀直近似1
且输⼊⻔⼀直近似0,过去的记忆细胞将⼀直通过时间保存并传递⾄当前时间步。这个设计可以应对循环神经⽹络中的梯度衰减问题,并更好地捕捉时间序列中时间步距离较⼤的依赖关系。
在这里插入图片描述

3.4 隐藏状态

有了记忆细胞以后,接下来我们还可以通过输出⻔来控制从记忆细胞到隐藏状态 H t R n × h \boldsymbol{{H}}_{t} \in \mathbb{R}^{n \times h} 的信息的
流动
H t = O t tanh ( C t ) \boldsymbol{H}_{t}=\boldsymbol{O}_{t} \odot \tanh \left(\boldsymbol{C}_{t}\right)
这⾥的tanh函数确保隐藏状态元素值在-1到1之间。当输出⻔近似1时,记忆细胞信息将
传递到隐藏状态供输出层使⽤;当输出⻔近似0时,记忆细胞信息只⾃⼰保留。下图展示了⻓短期记忆中隐藏状态的计算。
在这里插入图片描述

3.5 LSTM编程实现

TODO...

4. 深度循环神经网络

如下图演示了一个有 L L 个隐藏层的深度循环神经网络,每个隐藏状态不断传递⾄当前层的下⼀时间步当前时间步的下⼀层
在这里插入图片描述
具体来说,在时间步 t t 里,设小批量输入 X t R n × d \boldsymbol{{X}}_{t} \in \mathbb{R}^{n \times d} ,第 l l 隐藏层的隐藏状态为 H t ( ) R n × h \boldsymbol{H}_{t}^{(\ell)} \in \mathbb{R}^{n \times h} (隐藏单元个数为 h h ),输出层变量为 O t R n × q \boldsymbol{{O}}_{t} \in \mathbb{R}^{n \times q} (输出个数为 q q ),且隐藏层的激活函数为 ϕ \phi 。第1隐藏层的隐藏状态和之前的计算⼀样:
H t ( 1 ) = ϕ ( X t W x h ( 1 ) + H t 1 ( 1 ) W h h ( 1 ) + b h ( 1 ) ) \boldsymbol{H}_{t}^{(1)}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(1)}+\boldsymbol{H}_{t-1}^{(1)} \boldsymbol{W}_{h h}^{(1)}+\boldsymbol{b}_{h}^{(1)}\right)
1 < l < = L 1<l<=L 时,第 l l 隐藏层的隐藏状态的表达式为
H t ( ) = ϕ ( H t ( 1 ) W x h ( ) + H t 1 ( ) W h h ( ) + b h ( ) ) \boldsymbol{H}_{t}^{(\ell)}=\phi\left(\boldsymbol{H}_{t}^{(\ell-1)} \boldsymbol{W}_{x h}^{(\ell)}+\boldsymbol{H}_{t-1}^{(\ell)} \boldsymbol{W}_{h h}^{(\ell)}+\boldsymbol{b}_{h}^{(\ell)}\right)
最终,输出层的输出只需基于第 L L 隐藏层的隐藏状态:
O t = H t ( L ) W h q + b q \boldsymbol{O}_{t}=\boldsymbol{H}_{t}^{(L)} \boldsymbol{W}_{h q}+\boldsymbol{b}_{q}
其中 W h q R h × q \boldsymbol{W}_{h q} \in \mathbb{R}^{h \times q} b q R 1 × q \boldsymbol{b}_{q} \in \mathbb{R}^{1 \times q}

同多层感知机⼀样,隐藏层个数 L L 和隐藏单元个数 h h 都是超参数。此外,如果将隐藏状态的计算换成⻔控循环单元或者⻓短期记忆的计算,我们可以得到深度⻔控循环神经⽹络

5. 双向循环神经网络

双向循环神经⽹络通过增加从后往前传递
信息的隐藏层来更灵活地处理信息。下图演示了⼀个含单隐藏层的双向循环神经⽹络的架构。
在这里插入图片描述
给定时间步 t t 的⼩批量输⼊ X t R n × d \boldsymbol{X}_{t} \in \mathbb{R}^{n \times d} 和隐藏层激活函数 ϕ \phi 。在双向循环神经⽹络的架构中, 设该时间步正向隐藏状态为 H t R n × h \overrightarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h} (正向隐藏单元个数为 h h ), 反向隐藏状态为 H t R n × h \overleftarrow{\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times h} (反向隐藏单元个数为 h h )正向隐藏状态和反向隐藏状态计算如下:
H t = ϕ ( X t W x h ( f ) + H t 1 W h h ( f ) + b h ( f ) ) H t = ϕ ( X t W x h ( b ) + H t + 1 W h h ( b ) + b h ( b ) ) \begin{array}{l} \overrightarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(f)}+\overrightarrow{\boldsymbol{H}}_{t-1} \boldsymbol{W}_{h h}^{(f)}+\boldsymbol{b}_{h}^{(f)}\right) \\ \overleftarrow{\boldsymbol{H}}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}^{(b)}+\overleftarrow{\boldsymbol{H}}_{t+1} \boldsymbol{W}_{h h}^{(b)}+\boldsymbol{b}_{h}^{(b)}\right) \end{array}
其中 W x h ( f ) R d × h , W h h ( f ) R h × h , W x h ( b ) R d × h , W h h ( b ) R h × h \boldsymbol{W}_{x h}^{(f)} \in \mathbb{R}^{d \times h}, \boldsymbol{W}_{h h}^{(f)} \in \mathbb{R}^{h \times h}, \boldsymbol{W}_{x h}^{(b)} \in \mathbb{R}^{d \times h}, \boldsymbol{W}_{h h}^{(b)} \in \mathbb{R}^{h \times h}

然后我们连结两个⽅向的隐藏状态 H t \overrightarrow{\boldsymbol{H}}_{t} H t \overleftarrow{\boldsymbol{H}}_{t} 来得到隐藏状态 H t R n × 2 h {\boldsymbol{H}}_{t} \in \mathbb{R}^{n \times 2h} ,并将其输⼊到输出层。输出层计算输出 O t R n × q {\boldsymbol{O}}_{t} \in \mathbb{R}^{n \times q} (输出个数为q)
O t = H t W h q + b q O_t = H_tW_{hq}+b_q
其中 W h q R 2 h × q {\boldsymbol{W}}_{hq} \in \mathbb{R}^{2h \times q} b q R 1 × q {\boldsymbol{b}}_{q} \in \mathbb{R}^{1 \times q} ,不同⽅向上的隐藏单元个数也可以不同。

发布了39 篇原创文章 · 获赞 2 · 访问量 3696

猜你喜欢

转载自blog.csdn.net/orangerfun/article/details/105053838
RNN