一般我们用CNN来提取特征, 但是在现实生活中有很多的数据是基于时间序列的, 比如语音识别, 机器翻译等任务, 下面我们介绍一种处理序列数据的神经网络RNN, LSTM可以看做是一种特殊的RNN
参数共享
参数共享使得模型能够扩展到不同形式的样本并进行泛化, 在CNN中我们认为图像在局部区域是具有相关性的, 基于这样的假设我们进行参数共享, 在RNN中, 我们假设在一个序列中相同的信息会在不同的位置出现, 这是RNN中参数共享的条件, 在现实生活中这两种假设都是成立的.
RNN
RNN叫做循环神经网络, 如下图所示, 循环结构有效的保存了历史信息
在循环神经网络中, $x$为输入向量
- RNN输入到隐藏的连接由权重矩阵$ U $参数化
- 隐藏到隐藏的循环连接由权重矩阵$ W $参数化
- 隐藏到输出的连接由权重矩阵$ V $参数化
注意,
- 在RNN的训练过程中,RNN的参数被所有的时间点所共享, 这主要是说明RNN中的每一步都在做相同的事,只是输入不同,因此大大地降低了网络中需要学习的参数
RNN的数学定义如下: 在$t$时刻, RNN的输入是$I(t)$, 输出是$y(t)$, 隐藏层的状态为$s(t)$, 隐藏层的输入为$x(t)$,
$$
x(t)=I(t)+s(t-1)\\
s_j(t)=f(\sum_{i}{x_i(t)u_{ji}})\\
y_k(t)=g(\sum_{j}{s_j(t)v_{kj}})
$$
其中:
$f$为sigmoid激活函数
: $$f(z)=\frac{1}{1+e^{-z}}$$
$g$为softmax函数
: $$g(z_m) = \frac{e^{z_m}}{\sum_k{e^{z_k}}}$$
RNN Forward
- 输入层->隐藏层:
$$
net_j(t)=\sum_{i}^Nx_i(t)u_{ji}+\sum_{h}^Ms_h(t-1)w_{jh}+\theta_j \\
s_j(t)=f(net_j(t))
$$
- 隐藏层->输出层:
$$
net_k(t)=\sum_{j}^Ms_j(t)v_{kj}+\theta_k \\
y_k(t)=g(net_k(t))
$$
RNN BPTT
BPTT是BackPropagation Through Time的缩写, 是基于时间序列的后向优化算法, 为了衡量序列的误差函数我们定义SSE(summed squared error)作为代价函数, 我们的优化目标就是代价函数最小
代价函数
$$
C=\frac{1}{2}\sum_l^P\sum_k^O(d_{lk}-y_{lk})^2
$$
我们基于SSD作为优化函数:
- 输出单元的误差:
$$
\delta_{lk}=-\frac{\partial C}{\partial net_{lk}}=-\frac{\partial C}{\partial y_{lk}}\frac{\partial y_{lk}}{\partial net_{lk}}=(d_{lk}-y_{lk})g’(y_{lk})
$$
- 隐藏单元的误差:
$$
\delta_{lj}=-(\sum_k^O\frac{\partial C}{\partial y_{lk}}\frac{\partial y_{lk}}{\partial net_{lk}}\frac{\partial net_{lk}}{\partial s_{lj}})\frac{\partial s_{lj}}{\partial net_{lj}}=\sum_k^O\delta_{lk}v_{kj}f’(net_{lj})
$$
- 激活函数的反向求导:
sigmoid的函数:
$$
f(net)=\frac{1}{1+e^{-net}}\\
f’(net)=f(net){1-f(net)}
$$
softmax函数:
$$g(net_k)=\frac{e^{net_k}}{\sum_k^Oe^{net_k}} $$
$$ g’(net_k)=\frac{e^{net_k}(\sum_j^Oe^{net_j}-e^{net_k})}{(\sum_j^Oe^{net_j})^2} $$
梯度下降
在梯度下降法中, 代价函数和权值的关系是:
$$\Delta w=-\eta \frac{\partial C}{\partial w}$$
其中, $\eta$是学习率, $C$是代价函数, $w$为权值矩阵
- 输入到隐藏层:
$$\Delta u_{ji}=-\eta \frac{\partial C}{\partial u_{ji}}=\eta \sum_l^P\delta_{lj}x_{li}$$
- 隐藏层到输出层:
$$\Delta v_{kj}=-\eta \frac{\partial C}{\partial v_{kj}}=\eta \sum_l^P(-\frac{\partial C}{\partial net_{lk}})\frac{\partial net_{lk}}{\partial v_{kj}}=\eta \sum_l^P\delta_{lk}\frac{\partial net_{lk}}{\partial v_{kj}}=\eta \sum_l^P\delta_{lk}s_{lj}$$
- 隐藏层到隐藏层:
$$\Delta w_{jh}=-\eta \frac{\partial C}{\partial w_{jh}}=\eta \sum_l^P\delta_{lj}s_{(l-1)h}$$
在循环神经网络中, 由于神经元的状态信息是递归传递的, 为了在反向传播时获取历史状态信息, 我们将按照时间序列将RNN展开计算, 这个过程叫Unfolding
$$
\delta_{lj}(t-1)=-\frac{\partial C}{\partial s_{lj(t-1)}}=-\sum_h^M\frac{\partial C}{\partial s_{lh}}\frac{\partial s_{lh}}{\partial s_{lj}(t-1)}\\
=(-\sum_h^M\frac{\partial C}{\partial s_{lh}})(\frac{\partial s_{lh}}{\partial s_{lj}(t-1)})(\frac{\partial s_{lj}(t-1)}{\partial s_{lj}(t-1)})\\
=\sum_h^M\delta_{lh}(t)w_{hj}f’(s_{lj}(t-1))
$$
权值更新
- 输入层->隐藏层:
$$u_{ji}(t+1)=u_{ji}(t)+\eta \sum_z^T\sum_l^P\delta_{lj}(t-z)x_{li}(t-z)$$
- 隐藏层-> 隐藏层:
$$w_{jh}(t+1)=w_{jh}(t)+\eta \sum_z^T\sum_l^P\delta_{lj}(t-z)s_{(l-1)h}(t-z)$$
- 隐藏层-> 输出层:
$$v_{kj}(t+1)=v_{kj}(t)+\eta \sum_l^P\delta_{lk}s_{lj}$$
由此看见BPTT是基于时间步骤的后向传播算法
BackPropagation Through Time
A guide to recurrent neural networks and backpropagation
长期依赖
- 如上图所示, 如果我们在很近的一个上下文中试着预测
the clouds are in the sky
, 我们并不需要其他的上下文, 因为在这种语境下sky
的概率是很大的
- 如上图所示, 假设我们试着去预测
I grew up in France... I speak fluent French
最后的词。当前的信息建议下一个词可能是一种语言的名字,但是如果我们需要弄清楚是什么语言,我们是需要先前提到的离当前位置很远的France
的上下文的。在这个间隔不断增大时,RNN会丧失学习到连接如此远的信息的能力。
出现长期依赖的本质是因为隐含层的连乘导致权值矩阵过小或者过大, 就会引起梯度消失或者梯度爆炸, 这都会导致历史信息无法传递
LSTM
长期依赖
LSTM网络可以看做是特殊的RNN, 该网络结构克服了长期依赖
问题, 首先我们来看一下RNN和LSTM的结构对比:
- 所有RNN都具有一种重复神经网络模块的链式的形式。在标准的RNN中,这个重复的模块只有一个非常简单的结构,例如一个
tanh
层
- LSTM有四个神经网络层, 分别是遗忘门, 输入控制门, 输出控制门, 状态输出
- 每一条黑线传输着一整个向量,从一个节点的输出到其他节点的输入, 合在一起的线表示向量的连接,分开的线表示内容被复制,然后分发到不同的位置
- 粉色的圈代表 pointwise 的操作,诸如向量的和,
- 黄色的矩阵是学习到的神经网络层
如下图所示, LSTM克服梯度问题的核心思想就是引入了细胞状态传输高速路
, 通过一个加法器将历史信息通过高速路
传递到更远的相对位置
- 其中的
乘法器
和sigmoid神经网络层
组成了门结构, 门是一种让信息选择式通过的方法。
逐步解析
- 遗忘门: 遗忘门控制是否将前一个状态信息传入但前状态信息, 即决定是否丢弃信息, 在语言模型中, 细胞状态可能包含当前主语的性别,因此正确的代词可以被选择出来。当我们看到新的主语,我们希望忘记旧的主语。
- 输入控制门: 确定什么样的新信息被存放在细胞状态中,sigmoid层决定是否更新, tanh层产生新的候选值向量, 在我们语言模型的例子中,我们希望增加新的主语的性别到细胞状态中,来替代旧的需要忘记的主语。
- 更新细胞单元状态: 在语言模型的例子中,这就是我们实际根据前面确定的目标,丢弃旧代词的性别信息并添加新的信息的地方。
- 输出控制门: 确定输出什么值。这个输出将会基于我们的细胞状态,但是也是有选择性的输出, 由一个sigmoid层来确定细胞状态的哪个部分将输出出去, 然后把细胞状态通过 tanh 进行处理并将它和sigmoid门的输出相乘,最终我们仅仅会输出我们确定输出的那部分。