简单循环神经网络
\[\begin{aligned} \mathbf{z}_{t} &=U \mathbf{h}_{t-1}+W \mathbf{x}_{t}+\mathbf{b} \\ \mathbf{h}_{t} &=f\left(\mathbf{z}_{t}\right) \end{aligned} \]
参数学习
定义时刻 \(t\) 的损失函数为
\[\mathcal{L}_{t}=\mathcal{L}\left(y_{t}, g\left(\mathbf{h}_{t}\right)\right) \]
$ g(_{t}) \(为第 \)t$ 时刻的输出
那么整个序列上损失函数为
\[\mathcal{L}=\sum_{t=1}^{T} \mathcal{L}_{t} \]
整个序列的损失函数 \(\mathcal{L}\) 关于参数 \(U\) 的梯度为
\[\frac{\partial \mathcal{L}}{\partial U}=\sum_{t=1}^{T} \frac{\partial \mathcal{L}_{t}}{\partial U} \]
随时间反向传播(Backpropagation Through Time,BPTT)
在“展开”的前馈网络中, 所有层的参数是共享的,因此参数的真实梯度是将所有“展开层”的参数梯度 之和。
计算偏导数 \(\frac{\partial \mathcal{L}_{t}}{\partial U}\)
\[\mathbf{z}_{k}=U \mathbf{h}_{k-1}+W \mathbf{x}_{k}+\mathbf{b} \]
\[\begin{aligned} \frac{\partial \mathcal{L}_{t}}{\partial U_{i j}} &=\sum_{k=1}^{t} \operatorname{tr}\left(\left(\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}}\right)^{\mathrm{T}} \frac{\partial^{+} \mathbf{z}_{k}}{\partial U_{i j}}\right) \\ &=\sum_{k=1}^{t}\left(\frac{\partial^{+} \mathbf{z}_{k}}{\partial U_{i j}}\right)^{\mathrm{T}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}} \end{aligned} \]
定义\(\delta_{t, k}=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}}\)
\[\begin{aligned} \delta_{t, k} &=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}} \\ &=\frac{\partial \mathbf{h}_{k}}{\partial \mathbf{z}_{k}} \frac{\partial \mathbf{z}_{k+1}}{\partial \mathbf{h}_{k}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k+1}} \\ &=\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{k}\right)\right) U^{\mathrm{T}} \delta_{t, k+1} \end{aligned} \]
\[\frac{\partial \mathcal{L}_{t}}{\partial U_{i j}}=\sum_{k=1}^{t}\left[\delta_{t, k}\right]_{i}\left[\mathbf{h}_{k-1}\right]_{j} \]
将上式写成矩阵形式为
\[\frac{\partial \mathcal{L}_{t}}{\partial U}=\sum_{k=1}^{t} \delta_{t, k} \mathbf{h}_{k-1}^{\mathrm{T}} \]
参数梯度
\[\frac{\partial \mathcal{L}}{\partial U}=\sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{h}_{k-1}^{\mathrm{T}} \]
\(\mathcal{L}\)关于权重 \(\mathbf{W}\) 和偏置 \(\mathbf{b}\) 的梯度为
\[\begin{aligned} \frac{\partial \mathcal{L}}{\partial W}=& \sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{x}_{k}^{\mathrm{T}} \\ \frac{\partial \mathcal{L}}{\partial \mathbf{b}}=& \sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \end{aligned} \]
计算复杂度 参数的梯度需要在一个完整的“前向”计算和 “反向”计算后才能得到并进行参数更新
实时循环学习(Real-Time Recurrent Learning,RTRL)
\[\begin{aligned} \frac{\partial \mathbf{h}_{t+1}}{\partial U_{i j}} &=\frac{\partial \mathbf{h}_{t+1}}{\partial \mathbf{z}_{t+1}}\left(\frac{\partial^{+} \mathbf{z}_{t+1}}{\partial U_{i j}}+U \frac{\partial \mathbf{h}_{t}}{\partial U_{i j}}\right) \\ &=\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{t+1}\right)\right)\left(\mathbb{I}_{i}\left(\left[\mathbf{h}_{t}\right]_{j}\right)+U \frac{\partial \mathbf{h}_{t}}{\partial U_{i j}}\right) \\ &=f^{\prime}\left(\mathbf{z}_{t+1}\right) \odot\left(\mathbb{I}_{i}\left(\left[\mathbf{h}_{t}\right]_{i}\right)+U \frac{\partial \mathbf{h}_{t}}{\partial U_{i j}}\right) \end{aligned} \]
\[\frac{\partial \mathcal{L}_{t}}{\partial U_{i j}}=\left(\frac{\partial \mathbf{h}_{t}}{\partial U_{i j}}\right)^{\mathrm{T}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{h}_{t}} \]
两种算法比较 BPTT 算法的计算量会更小,但是 BPTT 算法需 要保存所有时刻的中间梯度,空间复杂度较高。RTRL 算法不需要梯度回传,因 此非常适合用于需要在线学习或无限序列的任务中。
长期依赖问题
虽然简单循环网络理论上可以建立长时间间隔的状态之间的依赖关系,但 是由于梯度爆炸或消失问题,实际上只能学习到短期的依赖关系。这样,如果 \(t\) 时刻的输出\(y_t\) 依赖于 \(t−k\) 时刻的输入 \(\mathbf{x}_t−k\),当间隔\(k\) 比较大时,简单神经网络很 难建模这种长距离的依赖关系,称为 长期依赖问题(Long-Term Dependencies Problem)。
基于门控的循环神经网络
长短期记忆网络
LSTM 网络主要改进在以下两个方面:
- 新的内部状态 \(\mathbf{c}_t\) 专门进行线性的循环信息传递,同时(非线性)输出信息给隐藏层的外部状态\(\mathbf{h}_t\)。 \[\begin{aligned} \mathbf{c}_{t} &=\mathbf{f}_{t} \odot \mathbf{c}_{t-1}+\mathbf{i}_{t} \odot \tilde{\mathbf{c}}_{t} \\ \mathbf{h}_{t} &=\mathbf{o}_{t} \odot \tanh \left(\mathbf{c}_{t}\right) \end{aligned} \] \(\widetilde{\mathbf{c}}_{t}\)是通过非线性函数得到候选状态 \[\tilde{\mathbf{c}}_{t}=\tanh \left(W_{c} \mathbf{x}_{t}+U_{c} \mathbf{h}_{t-1}+\mathbf{b}_{c}\right) \]
- 门机制 当\(\mathbf{f}_t = 0, \mathbf{i}_t = 1\) 时,记忆单元将历史信息清空,并将候选状态向量 \(\widetilde{\mathbf{c}}_{t}\) 写入。 但此时记忆单元 \(\mathbf{C}_{t}\) 依然和上一时刻的历史信息相关。当\(\mathbf{f}_{t}=1, \mathbf{i}_{t}=0\) 时,记忆单元将复制上一时刻的内容,不写入新的信息。