RNN基础
[TOC]
# 1. 循环神经网络RNN
# 1.1 网络结构图
以右侧$x_t$所在的一列为特例说明符号:
- $x_t$ 输入向量
- $U$ 输入层到隐藏层的权重矩阵
- $s_{t}$ 隐藏层向量,根据计算公式有$s_t = f(Ux_t + Ws_{t-1})$,其中$f(*)$是输入层到隐藏层的激活函数
- $V$ 是隐藏层到输出层的权重矩阵
- $o_t$ 是输出向量,且有$o_t = g(Vs_t)$
- $W$ 是循环神经网络特有的权重矩阵,也是连接所有独立列的关键。下面会着重推一下$W$是如何连接起整个循环神经网络的
# 1.2 $W$是如何连接循环神经网络的
仍然以 $x_t$ 和 $o_t$ 所在的一列作为例子说明。
由上述的神经网络可以得到:$o_t = g(Vs_t)$
且有$s_t = f(Ux_t + Ws_{t-1})$,因此可以带入上面的$o_t$表达式开始套娃: $$ o_t = g(Vs_t) \ = g(Vf(Ux_t + Ws_{t-1}))\ = g(Vf(Ux_t + Wf(Ux_{t-1} + Ws_{t-2})))\ = g(Vf(Ux_t + Wf(Ux_{t-1} + Wf(Ux_{t-2} + Ws_{t-3})))\ =…………………………………………… $$ 这样想要计算$t$时刻的$o_t$,就需要使用前面所有时刻的输入。
换言之,$o_t$中包含了前面所有输入的信息
# 2. 双向循环神经网络
虽然普通的RNN包含了前面所有的输入,但是有时候我们还需要后面未来的输入来确定当前的输出,比如[参考博客](零基础入门深度学习(5) - 循环神经网络 - 作业部落 Cmd Markdown 编辑阅读器 (zybuluo.com) (opens new window))中的一个例子:
我的手机坏了,我打算____一部新手机。
如果需要用一个RNN来填词,那必须要考虑后面的输入,才能确定当前的输出。
双向RNN的网路结构与单向有很大的相似之处,其实就是将两个方向相反的普通RNN叠加
# 2.1 网络结构
这里没有列出各个权重矩阵,但是它们都是存在的,而且和刚才一致。
这里以$x1$输入$y_1$输出的一列作为举例:
显然我们有$y_1 = g(VA_1 + V^{'}A_1^{'})$,其中$V$和$V^{'}$都是权重矩阵
这时候避免混乱开始分开写$A_1$和$A_2$的表达式
$A_1 = f(WA_0 + Ux_1)$
$A_1^{'} = f(WA_2^{'} + Ux_1)$
上面两个公式都是带入$y_1$的表达式。秉着套娃的精神其实还可以继续写$A_0$和$A_2^{'}$但是已经没必要了,可以看出,两个$A$一个往前套娃,一个往后套娃,这样就获得了前面所有的信息和后面所有的信息,刚才所提出的**”同时需要过去和未来输入来决定这一时刻的输出“**的目的也就达到了。
# 3. 深度循环神经网络
挖个坑,参考的博客写的比较简单,日后待补充
# 4. 利用BPTT算法训练
挖坑,待填
# 5. RNN中的梯度爆炸与消失
# 5.1 RNN中梯度爆炸和消失的原因
# 5.2 应对措施
针对梯度爆炸,可以设置阈值截取梯度
针对梯度消失比较难处理,方法有三类:
- 合理初始化权重值,避开梯度消失的区域。
- 用ReLU代替sigmoid和tanh作为激活函数
- 使用其他结构的RNN,例如LSTM和GRU
# 参考
[零基础入门深度学习(5) - 循环神经网络](零基础入门深度学习(5) - 循环神经网络 - 作业部落 Cmd Markdown 编辑阅读器 (zybuluo.com) (opens new window))