RNN模型

序列数据建模常用的方法有隐马尔可夫模型(HMM)和条件随机场(CRF)以及RNN. RNN的结构示意图如下
rnn_cell这种循环/重复设计结构称为事件链,事件链之间存在依赖关系,即在 t t t时刻,不仅有输入 x t x_t xt还有前 t − 1 t-1 t1时刻的信息,将RNN循环结构展开如下
rnn_unroll展开后的网络可以看做一个 n n n层前馈神经网络,记 t t t时刻的输入状态,隐藏状态,输出状态分别为 x t , h t , o t x_t, h_t, o_t xt,ht,ot,训练目标输出值为 y t y_t yt,则有

  • 隐藏状态 h t h_t ht取决于当前时刻的输入状态 x t x_t xt和上一时刻的隐藏状态 h t − 1 h_{t-1} ht1确定
    h t = σ ( U x t + W h t − 1 + b ) h_t=\sigma(Ux_t+Wh_{t-1}+b) ht=σ(Uxt+Wht1+b)
    其中, U U U是输入层到隐藏层的权重矩阵, W W W是不同时刻隐藏层之间的连接权重, b b b是偏置向量, σ ( ⋅ ) \sigma(\cdot) σ()是激活函数.
    展开计算图如下
    rnn_chain典型的激活有sigmoid函数和tanh函数,示意图如下
    rnn_

  • 输出状态 o t o_t ot的计算公式为
    o t = g ( V h t + c ) o_t=g(Vh_t+c) ot=g(Vht+c)
    其中, V V V是隐藏层到输出层的权重矩阵, c c c是偏置向量, g ( ⋅ ) g(\cdot) g()是输出层的激活函数,对于分类任务可以使用softmax函数.

  • 网络整个序列上的损失可以定义为所有时刻的损失之和
    L = ∑ t L t = ∑ t L o s s ( o t , y t ) L=\sum_t L_t=\sum_t Loss(o_t, y_t) L=tLt=tLoss(ot,yt)
    其中, L t L_t Lt表示 t t t时刻的损失,Loss()定义了损失函数,对于分类任务可以使用交叉熵损失函数.

可以看出RNN采用参数共享机制,使得需要学习参数的数量大大减少,而且可以处理长度不固定的输入序列.

训练算法

RNN在训练时,采用梯度下降法和BP算法进行迭代,将RNN展开得到迭代公式
{ ∂ L ∂ U = ∑ t ∂ L ∂ h t ∂ h t ∂ U ∂ L ∂ W = ∑ t ∂ L ∂ h t ∂ h t ∂ W ∂ L ∂ V = ∑ t ∂ L ∂ o t ∂ o t ∂ V \left\{ \begin{aligned} &\frac{\partial L}{\partial U}=\sum_t\frac{\partial L}{\partial h_t}\frac{\partial h_t}{\partial U}\\ &\frac{\partial L}{\partial W}=\sum_t\frac{\partial L}{\partial h_t}\frac{\partial h_t}{\partial W}\\ &\frac{\partial L}{\partial V}=\sum_t\frac{\partial L}{\partial o_t}\frac{\partial o_t}{\partial V} \end{aligned} \right. UL=thtLUhtWL=thtLWhtVL=totLVot
其中 ∂ L ∂ h t \frac{\partial L}{\partial h_t} htL计算较为复杂,需要递推计算
∂ L ∂ h t = ∂ L ∂ h t + 1 ∂ h t + 1 ∂ h t + ∂ L ∂ o t ∂ o t ∂ h t \frac{\partial L}{\partial h_t}=\frac{\partial L}{\partial h_{t+1}}\frac{\partial h_{t+1}}{\partial h_t}+\frac{\partial L}{\partial o_t}\frac{\partial o_t}{\partial h_t} htL=ht+1Lhtht+1+otLhtot
在RNN的训练过程中,由于不同时刻状态的相互依赖,所以需要存储每个时刻的信息(类似Bellman动态规划).并且无法并行计算,空间复杂度和时间复杂度均很高.
并且,由于网络复杂度较高,因此RNN无法处理远期依赖,同时复杂的网络会导致梯度消失和梯度爆炸的现象.

CNN对序列数据建模

一般认为CNN适合图像领域,输入为网格型数据,如果将序列建模为二维网格型数据,那么可以使用CNN处理序列型数据.
TetxCNN模型将文本序列建模为二维网格型数据,对于含有 N N N个单词的句子,提取每个单词的 M M M维嵌入向量(embedding feature),使得一维的句子成为了 N × M N\times M N×M的矩阵;然后采用CNN进行卷积,池化,全连接操作,其中词嵌入向量可以使用Word2Vec模型提取.
textcnn

在一些时间卷积网络中,序列数据被视为时间轴上采样得到的一维网络型数据,并使用因果卷积(Causal Connvolution)和空洞卷积(Dilated Convolution)进行处理,空洞卷积可以增加感受视野,一般卷积输出层上每个节点只能观测到输入层上的5个数据,如果采用空洞卷积,设置扩张率为(1,2,4,8)后,则可以观察到16个数据.
标准卷积
cnn_std

空洞卷积
cnn_d

考虑RNN的训练效率,一般会采用截断式BP算法控制梯度爆炸或者梯度消失的问题,但是在序列任务中CNN在并行和训练方面的优势还是很明显,实际科研工作中可以组合使用.

Dropout

Dropout是缓解过拟合的方法,最初在2012年的AlexNet中出现,是有效的正则化方法,在每次迭代时,丢弃网络中一定比例的神经元,然后进行数据前向传播以及误差的反向传播,在测试网络阶段,则会恢复全部神经元.
不难看出,Dropout本质上是一种Bagging的思想,但是和原生Bagging相比,Dropout中的网络是参数共享的. 由于Dropout屏蔽神经元具有随机性,所以使得每次网络训练得到的权值不依赖于隐藏层节点之间的固定关系(每个神经元不会对某个特定神经的状态敏感),有效增加了网络的泛化性能.
dropout

Dropout与RNN

由于RNN具有记忆功能,Dropout操作会使得网络的拟合能力下降,如果考虑使用在连接层中加入噪声提高鲁棒性的操作,那么噪声会被RNN放大导致信号淹没.
RNN中的连接层可以分为两种类型:

  • t t t时刻的输入到 t t t时刻输出之间的连接,称为前馈连接
  • t t t时刻到 t + 1 t+1 t+1时刻的连接,称为循环连接

一种直观的思路是只将Dropout应用在前馈连接上,Krueger等人提出了一种Zoneout结构,用之前时间步上的激活值代替Dropout中置零的方法,使得之前的信息容易保留.

RNN中长期依赖问题

信息前向传播

考虑一个简单的,无输入数据和激活函数的RNN,前向传播方程为
h t = W h t − 1 , t = 1 , 2 , … , n h_t=Wh_{t-1}, t=1, 2, \dots, n ht=Wht1,t=1,2,,n
对于之前的某个时刻 t 0 ( 0 ≤ t 0 < t ) t_0(0\leq t_0<t) t0(0t0<t),有
h t = W t − t 0 h t 0 h_t=W^{t-t_0}h_{t_0} ht=Wtt0ht0
随着幂值的增加,矩阵 W W W中幅值小于1的特征值不断向0衰减,而幅值大于1的特征值则不断发散,导致信息在前向传播中出现消失或者爆炸的现象.

误差反向传播

记网络在 t t t时刻的损失为 L t L_t Lt,则有
∂ L t ∂ h t 0 = ∂ L t ∂ h t ∂ h t ∂ h t − 1 ∂ h t − 1 ∂ h t − 2 … ∂ h t 0 + 1 ∂ h t 0 = ∂ L t ∂ h t W t − t 0 \frac{\partial L_t}{\partial h_{t_0}}=\frac{\partial L_t}{\partial h_t}\frac{\partial h_t}{\partial h_{t-1}}\frac{\partial h_{t-1}}{\partial h_{t-2}}\dots\frac{\partial h_{t_0+1}}{\partial h_{t_0}}=\frac{\partial L_t}{\partial h_t}W^{t-t_0} ht0Lt=htLtht1htht2ht1ht0ht0+1=htLtWtt0
由于矩阵幂的存在,梯度消失和梯度爆炸的情况一样存在.

但是在一般神经网络中由于参数不是共享的,不同层有不同的权值矩阵 W W W,消失/爆炸的现象没有RNN中严重.

普通RNN

对于普通RNN,前向传播公式为
h t = σ ( U x t + W h t − 1 + b ) h_t=\sigma(Ux_t+Wh_{t-1}+b) ht=σ(Uxt+Wht1+b)
由于激活函数的存在,会缓解信息消失/爆炸现象,但是如果激活函数是ReLU并且取值大于零,仍然会出现信息消失/爆炸现象.
在反向传播中,由公式
∂ h t ∂ h t − 1 = d i a g ( σ ′ ( U x t + W h t − 1 + b ) ) ⋅ W \frac{\partial h_t}{\partial h_{t-1}}=diag(\sigma'(Ux_t+Wh_{t-1}+b))\cdot W ht1ht=diag(σ(Uxt+Wht1+b))W
激活函数导数项(一般取值小于1)的存在缓解了梯度爆炸,但是可能会加速梯度消失.

解决方案

选择合适的初始化权值矩阵和激活函数,加入正则化项等;在网络设计方面,在时间维度上加入跳跃连接,可以构造出较长延迟的RNN.

参考资料

LSTM长短期记忆网络实现
百面深度学习 中国工信出版社 葫芦娃
Understanding LSTM Networks
RNN与LSTM公式推导
神经网络作图工具 知乎回答
tikz examples
交叉熵损失函数及推导
textcnn进行文本分类
空洞卷积、多孔卷积
Dropout原理解析

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐