全前馈神经网络,信息单向传递,网络易学习,但能力被减弱。网络输出只依赖于当前的输入。输入输出维数固定。
循环神经网络,具有
短期记忆 能力。其中的神经元可接收
其他神经元 的信息和
本身 的信息。输入输出可不固定。参数学习可通过
随时间反向传播算法 学习。输入序列较长时,错误信息向前传递过长,存在
梯度爆炸 和
梯度消失 问题,即
长程依赖问题 ,一种有效的改进方式:
门控机制 。
循环神经网络易拓展到更广义的记忆网络模型:
递归神经网络 、
图网络 。
1. 给网络增加记忆能力
时序数据处理需要历史信息。前馈网络无记忆能力。介绍三种方法给网络增加记忆能力 。
1.1 延时神经网络
延时神经网络通过在前馈网络的非输出层中都添加一个延时器,记录神经元的最近几次活性值,增加前馈网络的短期记忆能力。在 t t t 时刻,第 l l l 层神经元的活性值依赖于第 l − 1 l-1 l − 1 层神经元的最近 K K K 个时刻的活性值:
h t ( l ) = f ( h t ( l − 1 ) , h t − 1 ( l − 1 ) , ⋅ ⋅ ⋅ , h t − K ( l − 1 ) )
\pmb{h}_t^{(l)} = f(\pmb{h}_t^{(l-1)},\pmb{h}_{t-1}^{(l-1)},\cdot\cdot\cdot,\pmb{h}_{t-K}^{(l-1)})
h h h t ( l ) = f ( h h h t ( l − 1 ) , h h h t − 1 ( l − 1 ) , ⋅ ⋅ ⋅ , h h h t − K ( l − 1 ) )
其中 h t ( l ) ∈ R M l \pmb{h}_t^{(l)} \in \mathbb{R}^{ \pmb{M}_l } h h h t ( l ) ∈ R M M M l 表示第 l l l 层神经元在时刻 t t t 的活性值,M l M_l M l 为第 l l l 层神经元的数量。前馈神经网络的活性值:
a ( l ) = f l ( W ( l ) a ( l − 1 ) + b ( l ) )
\pmb{a}^{(l)} = f_l(\pmb{W}^{(l)}\pmb{a}^{(l-1)} + \pmb{b}^{(l)})
a a a ( l ) = f l ( W W W ( l ) a a a ( l − 1 ) + b b b ( l ) )
1.2 有外部输入的非线性自回归模型
自回归模型 (AutoRegressive Model,AR)统计学上的时间序列模型,用一个变量 y t \pmb{y}_t y y y t 的历史信息来预测自己:
y t = w 0 + ∑ k = 1 K w k y t − k + ϵ t
\pmb{y}_t = w_0 + \sum_{k=1}^K w_k \pmb{y}_{t-k} + \epsilon_t
y y y t = w 0 + k = 1 ∑ K w k y y y t − k + ϵ t
其中 K K K 为超参数,w 0 , ⋅ ⋅ ⋅ , w K w_0, \cdot\cdot\cdot, w_K w 0 , ⋅ ⋅ ⋅ , w K 为可学习参数,ϵ t \epsilon_t ϵ t ~ N ( 0 , σ 2 ) N(0, \sigma^2) N ( 0 , σ 2 ) 为第 t t t 个时刻的噪声,方差 σ 2 \sigma^2 σ 2 与时间无关。
有外部输入的自回归模型 (Nonlinear AutoRegressive with Exogenous Inputs Model,NARX),在每个时刻 t t t 都有一个外部输入 x t \pmb{x}_t x x x t , 产生一个输出 y t \pmb{y}_t y y y t , NARX 通过一个延时器记录最近 K x K_x K x 次的外部输入和最近K y K_y K y 次的输出,第 t t t 个时刻的输出y t \pmb{y}_t y y y t 为:
y t = f ( x t , x t − 1 , ⋅ ⋅ ⋅ , x t − K x , y t − 1 , y t − 2 , ⋅ ⋅ ⋅ , y t − K y )
\pmb{y}_t = f(\pmb{x}_t,\pmb{x}_{t-1},\cdot\cdot\cdot,\pmb{x}_{t-K_x}, \pmb{y}_{t-1},\pmb{y}_{t-2},\cdot\cdot\cdot,\pmb{y}_{t-K_y})
y y y t = f ( x x x t , x x x t − 1 , ⋅ ⋅ ⋅ , x x x t − K x , y y y t − 1 , y y y t − 2 , ⋅ ⋅ ⋅ , y y y t − K y )
其中 f ( ⋅ ) f(\cdot) f ( ⋅ ) 表示非线性函数,可以前馈网络,K x K_x K x 和 K y K_y K y 为超参数。
1.3 循环神经网络
循环神经网络 (Recurrent Neural Network,RNN)通过使用带自反馈的神经元 处理任意长度的时序数据。
给定输入序列 x 1 : T = ( x 1 , x 2 , . . . , x t , . . . , x T ) \pmb{x}_{1:T} = (\pmb{x_1}, \pmb{x_2}, ... ,\pmb{x_t}, ..., \pmb{x_T}) x x x 1 : T = ( x 1 x 1 x 1 , x 2 x 2 x 2 , . . . , x t x t x t , . . . , x T x T x T ) ,RNN 这样更新带反馈边的隐藏层的活性值 h t \pmb{h}_t h h h t :
h t = f ( h t − 1 , x t )
\pmb{h}_t = f(\pmb{h}_{t-1}, \pmb{x}_t)
h h h t = f ( h h h t − 1 , x x x t )
其中h 0 = 0 \pmb{h}_0 = 0 h h h 0 = 0 , f ( ⋅ ) f(\cdot) f ( ⋅ ) 为非线性函数。可谓前馈网络。从数学上来说,该公式可看成动力系统,故隐藏层活性值 h t \pmb{h}_t h h h t 又被成为状态(State)或隐状态(Hidden State)。
2. 简单循环网络
简单循环网络 (SRN)只有一个隐藏层。在一个两层的前馈神经网络 中,连接存在相邻的层与层之间,隐藏层的节点之间无连接。简单循环网络 增加了隐藏层到隐藏层的反馈连接。
假设向量 x t ∈ R M \pmb{x}_t \in \mathbb{R}^M x x x t ∈ R M 表示在时刻t t t 时网络的输入, h t ∈ D M \pmb{h}_t \in \mathbb{D}^M h h h t ∈ D M 表示隐藏层状态(隐藏层神经元活性值), h t \pmb{h}_t h h h t 和当前时刻输入x t \pmb{x}_t x x x t 、上一时刻隐藏层状态h t − 1 \pmb{h}_{t-1} h h h t − 1 相关。 SRN在t时刻更新公式为:
其中z t \pmb{z}_t z z z t 为隐藏层的净输入,U ∈ R D × D \pmb{U} \in \mathbb{R}^{D \times D} U U U ∈ R D × D 是状态-状态 权重矩阵,W ∈ R D × D \pmb{W} \in \mathbb{R}^{D \times D} W W W ∈ R D × D 是状态-输入 权重矩阵,b ∈ R D \pmb{b} \in \mathbb{R}^{D} b b b ∈ R D 是偏移向量 , 其中 f ( ⋅ ) f(\cdot) f ( ⋅ ) 表示非线性函数,常为Logistic函数或Tanh函数。
若把每个时刻的状态都看做前馈神经网络的一层,循环神经网络可看做在时间维度上权值共享的神经网络。按时间展开的循环神经网络:
2.1 循环神经网络的计算能力
前馈神经网络可以模拟任何连续函数,而循环神经网络可以模拟任何程序。定义一个完全连接 的循环神经网络。x t \pmb{x}_t x x x t 为输入, y t \pmb{y}_t y y y t 为输出, h t \pmb{h}_t h h h t 为隐状态, f ( ⋅ ) f(\cdot) f ( ⋅ ) 为非线性激活函数, U \pmb{U} U U U 、W \pmb{W} W W W 、b \pmb{b} b b b 、V \pmb{V} V V V 为网络参数:
2.1.1 循环神经网络的通用近似定理
循环神经网络的拟合能力也十分强大。一个完全连接的循环网络是任何非线性动力系统 的近似器。可用通用近似定理解释:
2.1.2 图灵完备
图灵完备 (Turing Completeness)是指一种数据操作规则,比如一种编程语言,可以实现图灵机 (Turing Machine)的所有功能,解决所有的可计算问题。
故一个完全连接 的循环神经网络 可以近似解决所有的可计算问题。
3. 应用到机器学习
循环神经网络可以应用到三种模式的机器学习任务::序列到类别 模式、同步的序列到序列 模式、异步的序列到序列 模式。
3.1 序列到类别模式
序列到类别 模式主要用于序列数据的分类问题。比如文本分类任务,输入为单词序列,输出为该文本类别。
假设输入序列 x 1 : T = ( x 1 , x 2 , . . . , x t , . . . , x T ) \pmb{x}_{1:T} = (\pmb{x_1}, \pmb{x_2}, ... ,\pmb{x_t}, ..., \pmb{x_T}) x x x 1 : T = ( x 1 x 1 x 1 , x 2 x 2 x 2 , . . . , x t x t x t , . . . , x T x T x T ) ,输出为一个类别 y ∈ y \in y ∈ {1, … , C}。可将样本 x \pmb{x} x x x 按不同时刻输入到循环神经网络中,得到不同时刻的隐藏状态:h 1 \pmb{h}_1 h h h 1 , . . . ... . . . , h T \pmb{h}_T h h h T 。可将 h T \pmb{h}_T h h h T 看做整个序列的最终表示或特征,输入分类器 g ( ⋅ ) g(\cdot) g ( ⋅ ) :
y ^ = g ( h T )
\hat{y} = g(\pmb{h}_T)
y ^ = g ( h h h T )
也可以将整个序列的所有状态进行平均,做为整个序列的表示:
y ^ = g ( 1 T ∑ t = 1 T h t )
\hat{y} = g(\frac{1}{T}\sum_{t=1}^{T}\pmb{h}_t)
y ^ = g ( T 1 t = 1 ∑ T h h h t )
两种图示:
3.2 同步的序列到序列模式
同步的序列到序列 模式主要用于序列标注(Sequence Labeling)任务,即每一时刻都有输入输出,输入输出序列长度相同。比如在词性标注 (Part-of-Speech Tagging)中,每一个单词需要标注其词性标签 。
假设输入序列 x 1 : T = ( x 1 , x 2 , . . . , x t , . . . , x T ) \pmb{x}_{1:T} = (\pmb{x_1}, \pmb{x_2}, ... ,\pmb{x_t}, ..., \pmb{x_T}) x x x 1 : T = ( x 1 x 1 x 1 , x 2 x 2 x 2 , . . . , x t x t x t , . . . , x T x T x T ) ,输出序列为一个类别 y 1 : T = ( y 1 , . . . , y T ) y_{1:T} = (y_1, ... , y_T) y 1 : T = ( y 1 , . . . , y T ) 。样本 x \pmb{x} x x x 按不同时刻输入到循环神经网络中,得到不同时刻的隐含态 h 1 \pmb{h}_1 h h h 1 , …, h T \pmb{h}_T h h h T 。每个时刻的隐含态 h t \pmb{h}_t h h h t 代表了当前时刻和历史的信息,作为输入:
y ^ t = g ( h t ) , ∀ t ∈ [ 1 , T ]
\hat{y}_t = g(\pmb{h}_t), \forall t \in [1, T]
y ^ t = g ( h h h t ) , ∀ t ∈ [ 1 , T ]
3.3 异步的序列到序列模式
异步的序列到序列模式 又称编码器-解码器 (Encoder-Decoder)模型,即输入序列和输出序列不需具有严格的对应关系,也不需相同长度。比如机器翻译任务中,输入为源语言单词序列,输出为目标语言单词序列。
假设输入为 x 1 : T = ( x 1 , x 2 , . . . , x T ) \pmb{x}_{1:T} = (\pmb{x_1}, \pmb{x_2}, ..., \pmb{x_T}) x x x 1 : T = ( x 1 x 1 x 1 , x 2 x 2 x 2 , . . . , x T x T x T ) ,输出为 y 1 : M = ( y 1 , y 2 , . . . , x M ) \pmb{y}_{1:M} = (\pmb{y_1}, \pmb{y_2}, ... ,\pmb{x_M}) y y y 1 : M = ( y 1 y 1 y 1 , y 2 y 2 y 2 , . . . , x M x M x M ) 异步的序列到序列模式 一般通过先编码后解码的方式来实现。先将样本 x x x 按不同时刻输入到一个RNN(编码器)中,得到其编码 h T \pmb{h}_T h h h T 。然后再使用另外一个RNN(解码器),得到输出序列 y ^ 1 : M \hat{y}_{1:M} y ^ 1 : M ,为建立输出序列之间的依赖关系,在解码器中通常使用非线性的自回归模型:
其中 f 1 ( ⋅ ) f_1(\cdot) f 1 ( ⋅ ) 和 f 2 ( ⋅ ) f_2(\cdot) f 2 ( ⋅ ) 分别作为编码器和解码器,g ( ⋅ ) g(\cdot) g ( ⋅ ) 为分类器,y ^ t \hat{\pmb{y}}_t y y y ^ t 为预测输出 y ^ t \hat{y}_t y ^ t 的向量表示。
异步的序列到序列模式示例如下图,其中⟨𝐸𝑂𝑆⟩ 表示输入序列的结束,虚线表示将上一个时刻的输出作为下一个时刻的输入:
4. 参数学习
可用梯度下降学习RNN中的参数。以随机梯度下降为例。给定样本 ( x , y ) (\pmb{x}, \pmb{y}) ( x x x , y y y ) ,其中输入为 x 1 : T = ( x 1 , x 2 , . . . , x T ) \pmb{x}_{1:T} = (\pmb{x_1}, \pmb{x_2}, ..., \pmb{x_T}) x x x 1 : T = ( x 1 x 1 x 1 , x 2 x 2 x 2 , . . . , x T x T x T ) ,输出为 y 1 : T = ( y 1 , y 2 , . . . , x T ) \pmb{y}_{1:T} = (\pmb{y_1}, \pmb{y_2}, ... ,\pmb{x_T}) y y y 1 : T = ( y 1 y 1 y 1 , y 2 y 2 y 2 , . . . , x T x T x T ) 每个时刻t,都有一个监督信息y t y_t y t ,定义时刻 t 的损失函数为:
L t = L ( y t , g ( h t ) )
L_t = L(y_t, g(\pmb{h}_t))
L t = L ( y t , g ( h h h t ) )
其中 g ( h t ) g(\pmb{h}_t) g ( h h h t ) 为 t 时刻的输出,L为可微分的损失函数,如交叉熵。整个序列的损失函数为:
L t = ∑ t = 1 T L t
L_t = \sum_{t=1}^{T}{L_t}
L t = t = 1 ∑ T L t
整个序列的损失函数 L 为关于参数 U 的梯度为每个时刻损失 L_t 对参数U的偏导数之和:
∂ L ∂ U = ∑ t = 1 T ∂ L t ∂ U
\frac{\partial{L}}{\partial{\pmb{U}}} = \sum_{t=1}^{T}\frac{\partial{L}_t}{\partial{\pmb{U}}}
∂ U U U ∂ L = t = 1 ∑ T ∂ U U U ∂ L t
RNN中存在提个递归调用的 f ( ⋅ ) f(\cdot) f ( ⋅ ) ,因此计算参数梯度的方式不同于计算前馈网络,主要有两种::随时间反向传播 (BPTT)算法和实时循环学习 (RTRL)算法.
4.1 随时间反向传播算法
随时间反向传播 算法类似前馈网络的错误反向传播算法 。
BPTT 算法将RNN看做展开的多层前馈网络,其中的“每一层”对应RNN中的“每个时刻”:
这样,RNN就可按照前馈网络中的反向传播算法计算参数梯度。在展开的前馈网络中,所有层参数共享,参数的真实梯度是所有“展开层”的参数梯度之和。
计算偏导数∂ L ∂ U \frac{\partial{L}}{\partial{\pmb{U}}} ∂ U U U ∂ L 先计算时刻 t 的损失对参数U的偏导 ∂ L ∂ U \frac{\partial{L}}{\partial{\pmb{U}}} ∂ U U U ∂ L 。
参数 U 和隐藏层净输入 z k = U h k − 1 + W x k + b \pmb{z}_k = \pmb{Uh}_{k-1} + \pmb{Wx_k} + b z z z k = U h U h U h k − 1 + W x k W x k W x k + b 有关,故 t 时刻的损失 L t L_t L t 关于参数 u i j u_{ij} u i j 的梯度为:
其中 ∂ + z k ∂ u i j \frac{\partial^{+}z_k}{\partial{\pmb{u}_{ij}}} ∂ u u u i j ∂ + z k 表示直接偏导数 即 z k = U h k − 1 + W x k + b \pmb{z}_k = \pmb{Uh}_{k-1} + \pmb{Wx}_k + b z z z k = U h U h U h k − 1 + W x W x W x k + b 中保持 h k − 1 \pmb{h}_{k-1} h h h k − 1 不变,对 u i j u_{ij} u i j 进行求偏导,得到:
其中 [ h k − 1 ] j [\pmb{h}_{k-1}]_j [ h h h k − 1 ] j 为第 k-1 时刻隐状态的第 j 维;I i ( x ) \mathbb{I}_i(x) I i ( x ) 为除了第 i 行为 x 外,其余部分为 0 的行向量。
定义误差项为第 t 时刻的损失对第 k 时刻隐藏神经层的净输入z k \pmb{z}_k z z z k 的导数,则当 1 ≤ k ≤ t 1 \leq k \leq t 1 ≤ k ≤ t 时:
由以上可得到:
其矩阵形式:
参数梯度 得到整个序列的损失函数 L 关于参数 U、权重W、偏置b 的梯度:
计算复杂度 在BPTT 算法中,参数的梯度需要在一个完整的“前向”计算和“反向”计算后才能得到并进行参数更新。
4.2 实时循环学习算法
与反向传播的BPTT不同,实时循环学习 (Real-Time Recurrent earning,RTRL)是通过前向传播的方式来计算梯度。
假设RNN的第 t + 1 t+1 t + 1 时刻的状态 h t + 1 \pmb{h}_{t+1} h h h t + 1 为:
其中关于参数 u i j u_{ij} u i j 的偏导数为:
RTRL算法从第1个时刻开始,计算RNN的隐状态,同时一次向前计算偏导数 ∂ h 1 ∂ u i j \frac{\partial h_1}{\partial{\pmb{u}_{ij}}} ∂ u u u i j ∂ h 1 ,∂ h 2 ∂ u i j \frac{\partial h_2}{\partial{\pmb{u}_{ij}}} ∂ u u u i j ∂ h 2 ,∂ h 3 ∂ u i j \frac{\partial h_3}{\partial{\pmb{u}_{ij}}} ∂ u u u i j ∂ h 3 ,…这样第 t 时刻,可以实时计算损失 L_t 关于参数 U 的梯度,并更新参数。参数W W W 和 b b b 的梯度同理。
RTRL和BPTT算法比较 两者都是基于梯度下降算法,分别通过前向模式和后向模式利用链式法则计算梯度。RNN中,一般网络输出维数原低于输入维度,因此BPTT算法计算量更小,但要保存所有时刻的中间梯度,空间复杂度高。RTRL不需要梯度回传,适合在线学习和无限序列任务。
5. 长程依赖问题
RNN在学习过程中主要的问题是梯度消失或梯度爆炸。很难建模长时间间隔 的状态之间的依赖关系。
将BPTT中的误差项 展开:
得到:
再定义:
得到:
若 γ > 1 \gamma > 1 γ > 1 , 当 t − k → ∞ t-k \rightarrow \infty t − k → ∞ 时,γ t − k → ∞ \gamma^{t-k} \rightarrow \infty γ t − k → ∞ 。当间隔 t − k t - k t − k 比较大时,梯度也变得很大,会造成系统不稳定,即梯度爆炸问题。
若 γ < 1 \gamma < 1 γ < 1 , 当 t − k → ∞ t-k \rightarrow \infty t − k → ∞ 时,γ t − k → 0 \gamma^{t-k} \rightarrow 0 γ t − k → 0 。当间隔 t − k t - k t − k 比较大时,梯度也变得很小,会出现和深层前馈网络类似的梯度爆炸问题。
注意:
RNN常使用Logistic或Tanh函数作为非线性激活函数,其导数值都小于1,权重矩阵 ∣ ∣ U ∣ ∣ ||\pmb{U}|| ∣ ∣ U U U ∣ ∣ 不会太大,故若时间间隔 t − k t - k t − k 过大,δ t , k \delta_{t,k} δ t , k 会趋于0,故出现梯度消失问题。
RNN理论上可以建立长时间间隔的状态之间的依赖关系,但由于梯度爆炸或消失问题,实际上只能学到短期的依赖关系。这样,如时刻 t 的输出 y t y_t y t 依赖于时刻 k 的输入 x k \pmb{x}_k x x x k ,当间隔 t − k t-k t − k 较大时,简单RNN难建模长距离依赖关系,成为长程依赖问题 。
5.1 改进方案
为避免梯度爆炸或梯度消失,一种直接方式:选取合适参数 ,使用非饱和激活函数 ,尽量使 d i a g ( f ′ ( z ) ) U T ≈ 1 diag(f^{'}(\pmb{z})) \pmb{U}^T \approx1 d i a g ( f ′ ( z z z ) ) U U U T ≈ 1 。这种方式依赖于人工调参经验,限制模型的广泛应用。一种有效方式:通过改进模型 或优化方法 。
梯度爆炸 RNN的梯度爆炸更易解决,常通过权重衰减 或梯度截断 。
权重衰减 通过给参数增加 l 1 l1 l 1 或l 2 l2 l 2 范数的正则化,来限制参数取值范围,从而使 γ ≤ 1 \gamma \leq 1 γ ≤ 1 。梯度截断是另一种有效的启发式方法,梯度的模大于阈值时,将其截断为及较小的数。
梯度消失 RNN的主要问题。解决方式:一是用优化技巧;二是改变模型(更有效),如让 U = I \pmb{U} = \pmb{I} U U U = I I I ,同时令 ∂ h t ∂ h t − 1 = I \frac{\partial \pmb{h}_t}{\partial \pmb{h}_{t-1}} = \pmb{I} ∂ h h h t − 1 ∂ h h h t = I I I 为单位矩阵,即:
h t = h t − 1 + g ( x t ; θ )
\pmb{h}_t = \pmb{h}_{t-1} + g(\pmb{x}_t; \theta)
h h h t = h h h t − 1 + g ( x x x t ; θ )
其中 h t h_t h t 和 h t − 1 h_{t-1} h t − 1 之间为线性依赖关系,权重系数为1,不存在梯度爆炸或消失问题,但是,丢失了神经元在反馈边上的非线性激活的性质,故降低了模型的表示能力。更有效的改进策略:
h t = h t − 1 + g ( x t , h t − 1 ; θ )
\pmb{h}_t = \pmb{h}_{t-1} + g(\pmb{x}_t, \pmb{h}_{t-1}; \theta)
h h h t = h h h t − 1 + g ( x x x t , h h h t − 1 ; θ )
这样 h t h_t h t 和 h t − 1 h_{t-1} h t − 1 既有线性关系,也有非线性关系,并可缓解梯度消失问题。仍存在问题:
梯度爆炸:令 z k = U h k − 1 + U x k + b \pmb{z}_k = \pmb{Uh}_{k-1} + \pmb{Ux}_k + \pmb{b} z z z k = U h U h U h k − 1 + U x Ux U x k + b b b 为 k k k 时刻 g ( ⋅ ) g(\cdot) g ( ⋅ ) 的输入,在误差项计算中:
梯度可能过大,存在梯度爆炸问题。
记忆容量:随着 h t \pmb{h}_t h h h t 不断累积存储新的输入信息,会发生饱和。 假设 g ( ⋅ ) g(\cdot) g ( ⋅ ) 为 Logistic 函数,则随着时间 t 的增长,h t \pmb{h}_t h h h t 会变得大,从而导致 h \pmb{h} h h h 变得饱和。即隐状态h t \pmb{h}_t h h h t 可存储信息有限,随着记忆单元存储内容增多,其丢失信息也增多。
利用门控机制 改进模型,解决这两个问题。
6. 基于门控的循环神经网络
为改善RNN的长程依赖问题 ,在公式:
h t = h t − 1 + g ( x t , h t − 1 ; θ )
\pmb{h}_t = \pmb{h}_{t-1} + g(\pmb{x}_t, \pmb{h}_{t-1}; \theta)
h h h t = h h h t − 1 + g ( x x x t , h h h t − 1 ; θ )
上引入门控机制 来控制信息积累速度,包括有选择地加入新的信息,并有选择地遗忘之前累积的信息。这类网络叫做 基于门控的循环神经网络 (Gated RNN)。
6.1 长短期记忆网络(LSTM)
长短期记忆网络(Long Short-Term Memory Network,LSTM)是RNN的一变体,可有效解决RNN的梯度爆炸或梯度消失问题。在以下公式上,进行两方面的改进:
h t = h t − 1 + g ( x t , h t − 1 ; θ )
\pmb{h}_t = \pmb{h}_{t-1} + g(\pmb{x}_t, \pmb{h}_{t-1}; \theta)
h h h t = h h h t − 1 + g ( x x x t , h h h t − 1 ; θ )
新的内部状态 LSTM引入新的内部状态 (internal state)c t ∈ R D \pmb{c}_t \in \mathbb{R}^D c c c t ∈ R D 专门进行线性的循环信息传递,同时非线性地输出信息给隐藏层的外部状态 h t ∈ R D \pmb{h}_t \in \mathbb{R}^D h h h t ∈ R D 。内部状态 c t \pmb{c}_t c c c t 这样计算:
其中 f t ∈ [ 0 , 1 ] D \pmb{f}_t \in [0,1]^D f f f t ∈ [ 0 , 1 ] D 、i t ∈ [ 0 , 1 ] D \pmb{i}_t \in [0,1]^D i i i t ∈ [ 0 , 1 ] D 、o t ∈ [ 0 , 1 ] D \pmb{o}_t \in [0,1]^D o o o t ∈ [ 0 , 1 ] D 为三个门(gate)来控制信息传递的路径;⨀ \bigodot ⨀ 为向量元素乘积;c t − 1 \pmb{c}_{t-1} c c c t − 1 为上一个时刻的记忆单元;c ^ t ∈ R D \hat{\pmb{c}}_t \in \mathbb{R}^D c c c ^ t ∈ R D 是通过非线性函数得到的候选状态 :
在每个时刻 t ,LSTM 网络的内部状态 c t \pmb{c}_t c c c t 记录了到当前时刻为止的历史信息。
门控机制 数字电路中,门为二值变量 {0,1},0代表关闭,不需信息通过。LSTM引入门控机制 (Gating Mechanism),控制信息传递的路径。公式:
中有三个门:f t ∈ [ 0 , 1 ] D \pmb{f}_t \in [0,1]^D f f f t ∈ [ 0 , 1 ] D 为遗忘门、i t ∈ [ 0 , 1 ] D \pmb{i}_t \in [0,1]^D i i i t ∈ [ 0 , 1 ] D 为输入门、o t ∈ [ 0 , 1 ] D \pmb{o}_t \in [0,1]^D o o o t ∈ [ 0 , 1 ] D 为输出门。三个门的作用:
f t ∈ [ 0 , 1 ] D \pmb{f}_t \in [0,1]^D f f f t ∈ [ 0 , 1 ] D 为遗忘门,控制上一个时刻的内部状态 c t − 1 \pmb{c}_{t-1} c c c t − 1 需要遗忘多少信息。
i t ∈ [ 0 , 1 ] D \pmb{i}_t \in [0,1]^D i i i t ∈ [ 0 , 1 ] D 为输入门,控制当前时刻的候选状态 c ^ t \hat{\pmb{c}}_t c c c ^ t 需要保存多少信息。
o t ∈ [ 0 , 1 ] D \pmb{o}_t \in [0,1]^D o o o t ∈ [ 0 , 1 ] D 为输出门,控制当前时刻的内部状态 c t \pmb{c}_t c c c t 有多少信息需要输出给外部状态 h t \pmb{h}_t h h h t 。
当 f t = 0 , i t = 1 \pmb{f}_t = 0,\pmb{i}_t = 1 f f f t = 0 , i i i t = 1 时,记忆单元将历史信息清空,将候选状态写入,但此时记忆单元 c t \pmb{c}_t c c c t 依然和上一时刻的历史信息相关。
当 f t = 1 , i t = 0 \pmb{f}_t = 1,\pmb{i}_t = 0 f f f t = 1 , i i i t = 0 时,记忆单元将复制上一时刻的内容,不写入新的信息。
LSTM的“门”是“软门”,取值在 (0,1) 之间,并以一定的比例通过信息,三种门的计算如下,其中 σ ( ⋅ ) \sigma(\cdot) σ ( ⋅ ) 为 Logistic函数,其输出区间为 (0,1),x t \pmb{x}_t x x x t 为当前时刻的输入,h t − 1 \pmb{h}_{t-1} h h h t − 1 为上一时刻的外部状态:
LSTM的循环单元结构如图:
其计算过程为:
利用上一时刻的外部状态 h t − 1 \pmb{h}_{t-1} h h h t − 1 和当前时刻的输入 x t \pmb{x}_t x x x t ,计算出三个门f t \pmb{f}_t f f f t 、i t \pmb{i}_t i i i t 、o t \pmb{o}_t o o o t ,和候选状态c ^ t \pmb{\hat{c}}_t c ^ c ^ c ^ t 。
结合遗忘门 f t \pmb{f}_t f f f t 、输入门 i t \pmb{i}_t i i i t 更新记忆单元 c t \pmb{c}_t c c c t 。
结合输出门 o t \pmb{o}_t o o o t ,将内部状态的信息传递给外部状态 h t \pmb{h}_{t} h h h t 。
通过LSTM循环单元,整个网络可以建立较长距离的时序依赖关系。给出以上LSTM循环单元公式的简洁描述:
其中 x t ∈ R M \pmb{x}_t \in \mathbb{R}^M x x x t ∈ R M 为当前时刻的输入,W ∈ R 4 D × ( D + M ) \pmb{W} \in \mathbb{R}^{4D \times (D+M)} W W W ∈ R 4 D × ( D + M ) 、b ∈ R 4 D \pmb{b} \in \mathbb{R}^{4D} b b b ∈ R 4 D 是网络参数。
记忆 循环神经网络的隐状态 h h h 存储了历史信息,可以看做是一种 记忆 。
在简单RNN中,隐状态 h h h 每个时刻都会被重写,看做短期记忆 (Short-Term Memory)。
在神经网络中,长期记忆 (Long-Term Memory)可看做是网络参数,隐含从训练数据中学到的经验,更新周期远慢于短期记忆 。
而在LSTM中,记忆单元 c c c 可以在某个时刻捕捉到某个关键信息,并有能力将此关键信息保存一定的时间。记忆单元c c c 中保存信息的生命周期要长于短期记忆 h h h ,短于长期记忆 ,因此称为长短期记忆 (Long Short-Term Memory)。
6.2 LSTM网络的各种变体
主流的LSTM用三个门动态控制内部状态 ,遗忘 历史信息、输出 信息、输入 信息的数量。对门控机制 修改,得到LSTM变体。
无遗忘门的LSTM 最早的LSTM是没有遗忘门的,内部状态的更新为:
记忆单元 c c c 会不断增大。输入序列很长时,记忆单元容量饱和,大大降低LSTM的性能。
peephole 连接 三种门不但依赖于输入 x t \pmb{x}_t x x x t 和上一个时刻的隐状态 h t − 1 \pmb{h}_{t-1} h h h t − 1 ,也依赖于上一个时刻的记忆单元 c t − 1 \pmb{c}_{t-1} c c c t − 1 :
其中 V i 、 V f 、 V o \pmb{V}_i、\pmb{V}_f、\pmb{V}_o V V V i 、 V V V f 、 V V V o 为对角矩阵。
耦合输入门和遗忘门 LSTM的输入门和输出门有些互补关系,同时使用两个门较冗余,为减少LSTM的计算复杂度,将输入门输出门合并,令 f t = 1 − i t \pmb{f}_t = 1 - \pmb{i}_t f f f t = 1 − i i i t ,内部状态更新方式:
6.3 门控循环单元网络
门控循环单元 (Gated Recurrent Unit,GRU)网络比LSTM更简单。
GRU网络引入门控机制控制信息更新方式,不同LSTM,GRU不引入额外的记忆单元,在公式:
h t = h t − 1 + g ( x t , h t − 1 ; θ )
\pmb{h}_t = \pmb{h}_{t-1} + g(\pmb{x}_t, \pmb{h}_{t-1}; \theta)
h h h t = h h h t − 1 + g ( x x x t , h h h t − 1 ; θ )
上,引入一个更新门 控制当前状态需从历史状态中保留多少信息,需从候选状态中接受多少新信息:
h t = z t ⨀ h t − 1 + ( 1 − z t ) ⨀ g ( x t , h t − 1 ; θ ) z t = σ ( W z x t + U z h t − 1 + b z )
\pmb{h}_t = \pmb{z}_t \bigodot \pmb{h}_{t-1} + (1-\pmb{z}_t) \bigodot g(\pmb{x}_t, \pmb{h}_{t-1}; \theta) \\
\pmb{z}_t = \sigma(\pmb{W}_z \pmb{x}_t + \pmb{U}_z \pmb{h}_{t-1} + \pmb{b}_z)
h h h t = z z z t ⨀ h h h t − 1 + ( 1 − z z z t ) ⨀ g ( x x x t , h h h t − 1 ; θ ) z z z t = σ ( W W W z x x x t + U U U z h h h t − 1 + b b b z )
其中 z t ∈ [ 0 , 1 ] D \pmb{z}_t \in [0,1]^D z z z t ∈ [ 0 , 1 ] D 为更新门。在LSTM中,输入输出互补,具有冗余性,GRU用更新门平衡输入和遗忘之间的平衡:
当 z t = 0 \pmb{z}_t = 0 z z z t = 0 时,当前状态 h t \pmb{h}_t h h h t 和前一时刻的状态h t − 1 \pmb{h}_{t-1} h h h t − 1 之间为非线性函数关系;
当 z t = 1 \pmb{z}_t = 1 z z z t = 1 时, h t \pmb{h}_t h h h t 和h t − 1 \pmb{h}_{t-1} h h h t − 1 之间为线性函数关系。
在GRU中,函数 g ( x t , h t − 1 ; θ ) g(\pmb{x}_t, \pmb{h}_{t-1}; \theta) g ( x x x t , h h h t − 1 ; θ ) 的定义为:
其中 h ^ t \pmb{\hat{h}_t} h ^ t h ^ t h ^ t 表示当前时刻的候选状态, r t ∈ [ 0 , 1 ] D \pmb{r}_t \in [0,1]^D r r r t ∈ [ 0 , 1 ] D 为重置门:
用来控制候选状态 h ^ t \pmb{\hat{h}_t} h ^ t h ^ t h ^ t 的计算是否依赖上一个时刻的状态 h t − 1 \pmb{h}_{t-1} h h h t − 1 :
r t = 0 \pmb{r}_t = 0 r r r t = 0 时,候选状态 h ^ t = t a n h ( W c x t + b ) \pmb{\hat{h}_t} = tanh(\pmb{W}_c\pmb{x}_t + \pmb{b} ) h ^ t h ^ t h ^ t = t a n h ( W W W c x x x t + b b b ) 只和当前输入 x t \pmb{x}_t x x x t 相关,和历史状态无关。
r t = 1 \pmb{r}_t = 1 r r r t = 1 时,候选状态 h ^ t = t a n h ( W c x t + U h h t − 1 + b ) \pmb{\hat{h}_t} = tanh(\pmb{W}_c\pmb{x}_t + \pmb{U}_h\pmb{h}_{t-1} +\pmb{b} ) h ^ t h ^ t h ^ t = t a n h ( W W W c x x x t + U U U h h h h t − 1 + b b b ) 和当前输入 x t \pmb{x}_t x x x t 、历史状态 h t − 1 \pmb{h}_{t-1} h h h t − 1 相关,和简单RNN一致。
综上,GRU网络的状态更新方式为:
h t = z t ⨀ h t − 1 + ( 1 − z t ) ⨀ h ^ t
\pmb{h}_t = \pmb{z}_t \bigodot \pmb{h}_{t-1} + (1-\pmb{z}_t) \bigodot \pmb{\hat{h}}_t
h h h t = z z z t ⨀ h h h t − 1 + ( 1 − z z z t ) ⨀ h ^ h ^ h ^ t
当 z t = 0 , r = 1 \pmb{z}_t = 0,\pmb{r} = 1 z z z t = 0 , r r r = 1 时,GRU退化为简单RNN;
当 z t = 0 , r = 0 \pmb{z}_t = 0,\pmb{r} = 0 z z z t = 0 , r r r = 0 时,当前状态 h t \pmb{h}_t h h h t 和当前输入 x t \pmb{x}_t x x x t 相关,和历史状态h t − 1 \pmb{h}_{t-1} h h h t − 1 无关;
当 z t = 1 \pmb{z}_t = 1 z z z t = 1 时,当前状态 h t = h t − 1 \pmb{h}_{t} = \pmb{h}_{t-1} h h h t = h h h t − 1 ,和当前输入 x t \pmb{x}_t x x x t 无关。
GRU网络的循环单元结构:
7. 深层循环神经网络
如果将深度定义为网络中中信息传递路径长度的话,RNN可以看作是既“深”又“浅”的网络。因为,把RNN按时间展开,长时间间隔的状态之间的路径很长,RNN可以看作是一个非常深的网络;而果同一时刻网络输入到输出之间的路径x t → y t \pmb{x}_t → \pmb{y}_t x x x t → y y y t ,这个RNN网络是非常浅的。
故,可增加RNN的深度来增强RNN的能力,即增加同一时刻网络输入到输出的路径x t → y t \pmb{x}_t → \pmb{y}_t x x x t → y y y t ,比如增加隐状态到输出的路径 h t → y t \pmb{h}_t → \pmb{y}_t h h h t → y y y t ,以及输入x t → h t \pmb{x}_t → \pmb{h}_t x x x t → h h h t 到隐状态的路径深度。
7.1 堆叠循环神经网络
常见的简单做法,将多个RNN堆叠起来,称为堆叠循环神经网络 (Stacked Recurrent Neural Network,SRNN)。一个堆叠的简单循环网络(Stacked SRN) 也称为循环多层感知器(Recurrent Multi-Layer Perceptron,RMLP)。按时间展开的SRNN如下:
第 l l l 层网络的输入是 l − 1 l-1 l − 1 层网络的输出。定义,h t ( l ) \pmb{h}_t^{(l)} h h h t ( l ) 为在时刻 t t t 时第 l l l 层的隐状态:
其中U ( l ) \pmb{U}^{(l)} U U U ( l ) 、W ( l ) \pmb{W}^{(l)} W W W ( l ) 、b ( l ) \pmb{b}^{(l)} b b b ( l ) 为权重矩阵和偏置向量,h t ( 0 ) = x t \pmb{h}_t^{(0)} = \pmb{x}_t h h h t ( 0 ) = x x x t 。
7.2 双向循环神经网络
特定任务中,一个时刻的输出不但和过去时刻的信息有关,也和后续时刻的信息有关。比如给定句子,其中一个词的词性由它的上下文决定。因此,在这些任务中,可以增加一个按时间的逆序来传递信息的网络层,以增强网络的能力。
双向循环神经网络(Bidirectional Recurrent Neural Network,Bi-RNN)由两层循环神经网络组成,他们的输入相同,只是信息传递的方向不同。
假设第1 层按时间顺序,第2 层按时间逆序,在时刻t t t 时的隐状态定义为 h t ( 1 ) \pmb{h}_t^{(1)} h h h t ( 1 ) 和 h t ( 2 ) \pmb{h}_t^{(2)} h h h t ( 2 ) ,则:
其中⨁ \bigoplus ⨁ 为向量拼接操作。
8. 拓展到图结构
如果将RNN按时间展开,每个时刻的隐状态h t \pmb{h}_t h h h t 看作一个节点,那么这些节点构成一个链式结构,每个节点t t t 都收到其父节点的消息(Message),更新自己的状态,并传递给其子节点。而链式结构是一种特殊的图结构,我们可以比较容易地将这种消息传递(Message Passing)的思想扩展到任意的图结构上。
8.1 递归神经网络
递归神经网络 (Recursive Neural Network,RecNN)是RNN在有向无循环图 上的拓展,常为树桩层次结构:
三个隐藏层 h 1 \pmb{h}_1 h h h 1 、 h 2 \pmb{h}_2 h h h 2 、 h 3 \pmb{h}_3 h h h 3 ,其中h 1 \pmb{h}_1 h h h 1 由两个输入层x 1 \pmb{x}_1 x x x 1 、 x 2 \pmb{x}_2 x x x 2 计算得到。
对一个节点h i \pmb{h}_i h h h i ,他可以接受来自父节点集合 π i \pi_i π i 中所有节点的消息,并更新自己的状态:
h i = f ( h π i )
\pmb{h}_i = f(\pmb{h}_{\pi_i})
h h h i = f ( h h h π i )
其中h π i \pmb{h}_{\pi_i} h h h π i 表示集合 π i \pi_i π i 中所有节点状态的拼接,f f f 是一个和节点位置无关的非线性函数,可以为一个单层的前馈神经网络。递归神经网络一般结构可以写成:
当递归神经网络的结构退化为线性序列结构(图b),递归神经网络等价于简单RNN。
递归神经网络主要用来建模自然语言句子的语义。
同样,可用门控机制 来改进递归神经网络中的长距离依赖问题,比如树结构的长短期记忆模型 (Tree-Structured LSTM),就是将LSTM模型的思想应用到树结构的网络中,来实现更灵活的组合函数。
8.2 图神经网络
实际中很多数据是图结构的,比如知识图谱、社交网络、分子网络等。而前馈网络和反馈网络很难处理图结构的数据。图神经网络(Graph Neural Network,GNN)是将消息传递的思想扩展到图结构数据上的神经网络,可用来处理图数据。
对一个任意的图结构 G ( V , ϵ ) G(V,\epsilon) G ( V , ϵ ) 。图中每个节点 v 都用一组神经元来表示状态 h ( v ) \pmb{h}^{(v)} h h h ( v ) ,初始状态可以为节点 v 的输入特征 x ( v ) \pmb{x}^{(v)} x x x ( v ) 。每个节点可收到来自相邻节点的消息,并更新自己的状态:
其中 N ( v ) N(v) N ( v ) 表示节点 v 的邻居,m t ( v ) \pmb{m}_t^{(v)} m m m t ( v ) 表示在第 t 时刻节点 v 收到的信息,e ( u , v ) \pmb{e}^{(u,v)} e e e ( u , v ) 为边e ( u , v ) e^{(u,v)} e ( u , v ) 上的特征。
该公式是同步的更新方式,所有结构同时接受信息并更新自己的状态。对有向图,异步更新更有效,如RNN或递归神经网络。整个图更新后T此后,可通过一个读出函数 g g g 来得到整个网络的表示: