日期: 2019/04/12
缘起: 最近在做时间序列分析的实验, FCN 网络做时序数据分类的效果还可以, 由于时间的依赖性, 自然地想到是否可以利用 LSTM 网络进行时序数据的分类. 我对 CNN 比较了解, 但是对 LSTM, 感觉很多文章都介绍得太笼统, 大部分都是介绍 cell, 而忽略了它和 CNN 的联系.
LSTM 叫长短期记忆网络 (Long short term memory), 是 RNN 循环神经网络(Recurrent Neural Network) 的一个变形. 我们先讲讲 RNN.
RNN
每个绿色的部分叫做 cell, 看起来它们好像是不同的 cell, 但实际上它们只是同一个 cell 在不同时刻的样子! 中间的这个 cell 清晰地画出了数据经过它到底进行了怎样的操作~ 输入是上一次 cell 输出的状态值和此时刻的输入, 组合后, 乘以权重和偏置, 经过一次 tanh 就得到了这个 cell 的输出.
普通的 RNN 对于处理短的序列数据还行, 当数据很长时, 就会出现梯度消失和梯度爆炸的问题. 所以又提出了改进版 RNN,LSTM.
LSTM
LSTM 多了什么呢?
看下面的图, 很复杂对嘛, 我们细细讲解. LSTM 多了一个表示 cell 记忆的值. 也就是我们不仅要更新当前 cell 的输出, 我们还要思考, 哪些东西可以记在我们的 cell 里呢, 记忆的话, 记多少又如何确定呢? 既然有了记忆, 那么我们的输入不仅仅有上一时刻的输出, 此刻的输入, 还有 cell 本身存储的那部分信息. 所以 LSTM 的构造看起来很复杂, 其实是围绕着记忆做操作的.
,
下图的 C 就表示记忆.
为了实现我们引入的记忆的思想, 构造了三个门, 遗忘门, 输入门, 输出门.
遗忘门
遗忘门能决定应丢弃或保留哪些信息. 来自先前隐藏状态的信息和当前输入的信息同时输入到 Sigmoid 函数, 输出值处于 0 和 1 之间, 越接近 0 意味着越应该忘记, 越接近 1 意味着越应该保留. 这个 f 就可以用来操控遗忘哪些数据.
输入门
f 是 forget 的意思, i 是 input 的意思.
输入门用来更新单元状态. 先将先前隐藏状态的信息和当前输入的信息输入到 Sigmoid 函数, 在 0 和 1 之间调整输出值来决定更新哪些信息, 0 表示不重要, 1 表示重要. 也可将隐藏状态和当前输入传输给 Tanh 函数, 并在 - 1 和 1 之间压缩数值以调节网络, 然后把 Tanh 输出和 Sigmoid 输出相乘, Sigmoid 输出将决定在 Tanh 输出中哪些信息是重要的且需要进行保留.
下面这张图显示了, 两个门是如何控制遗忘和记忆的.
输出门
我们确定了当前的状态, 那么当前状态的多少可以进行输出呢? 控制 Ct 输出的门叫输出门, 用 Ot 表示.
输出门能决定下个隐藏状态的值, 隐藏状态中包含了先前输入的相关信息. 当然, 隐藏状态也可用于预测. 首先把先前的隐藏状态和当前输入传递给 Sigmoid 函数; 接着把新得到的单元状态传递给 Tanh 函数; 然后把 Tanh 输出和 Sigmoid 输出相乘, 以确定隐藏状态应携带的信息; 最后把隐藏状态作为当前单元输出, 把新的单元状态和新的隐藏状态传输给下个时间步.
代码实现
- def LSTMCELL(prev_ct, prev_ht, input)
- combine = prev_ht + input
- ft = forget_layer(combine)
- it = input_layer(combine)
- ot = ouput_layer(combine)
- candidate = candidate_layer(combine)
- Ct = prev_ct*ft+candidate*it
- ht = ot*tanh(Ct)
- return ht, Ct
- ct = [0, 0, 0]
- ht = [0, 0, 0]
- for input in inputs:
- ct, ht = LSTMCELL(ct, ht, input)
ht 和 xt 结合后(拼接), 构造出三个门控单元. 再进行此 cell 在 t 时刻状态 Ct 的更新, 利用 Ct 输出 ht.inputs 是一个输入的时间序列, 可以看出, LSTM 在不同时刻输入, 只是在不断地循环输入而已. 整个代码由几个张量操作和一个 for 循环组成, 循环神经网络名字的来源一看便知哈.
多层 LSTM
多层 LSTM 只是将单个 cell 进行堆叠. LSTM 比为啥比 CNN 难理解呢? 因为它把神经元的个数都藏到 cell 里面啦. 假设大家都了解过 CNN, 看下面的图是不是有点感觉呢? 我来解释一下, 一个 cell 其实就是一层神经元, 只是 LSTM 和 CNN 不同的是, 它的每一层 t 时刻的输出和 t-1 时刻的状态有关. 也就是说当前 cell 的输出 ht 不仅仅影响到下一 cell(图中右边的那列), 还影响本 cell 下一时刻的状态和输出(图中按时间顺序堆叠的三个绿色的 cell).
理解到这一点了, 我们也自然地理解到, xt 可以是多维的. 然后每个 cell 的 hidden_size 都可以进行设置.
多层 LSTM 的代码
代码暂时没写, 未完待续~
参考资料:
https://zhuanlan.zhihu.com/p/46981722
我对 LSTM 的理解(一)
来源: http://www.bubuko.com/infodetail-3021069.html