之前的博客里,都写了一些tensorflow的入门学习,当时在学习tensorflow时一个让我很头疼的问题就是,只要自己写大点深点的网络,基本都是跑不动,损失函数降了一阵就不动了,估计可能是初始化,正则防止过拟合没做好。这个LSTM网络算是我难得写出来能跑的网络,现在有空了来记录一下。
LSTM网络
LSTM网络是由RNN变化而来,当时一直很困惑的问题就是关于RNN,横的算一层还是竖的算一层,应该是横的算一层,因此最简单的RNN即是一层隐藏层,光看RNN模型图的话,总会有些误解,实际上RNN每个单元的输入对应的状态隐藏层是可以有多个输出的,因为一个单元的输入维度也是n维,对应隐藏层的输出若是m维,则但看这个单元可理解为n到m的全连接网络。这个隐藏层维度一般就是由自己设定。
同时关于RNN和LSTM的输出,一般在理解模型时,都是以一个句子为例,只需要最后一个序列单元对应的输出,实际上通过tensorflow和keras框架得到的输出,是包括所有单元的,如RNN的输出outputs, last_state = tf.nn.static_rnn(cell, inputs)
理论上可认为outputs[-1]与last_state是相等的
关于LSTM,由于其状态由两个值构成(Ct,Ht),认为其状态是一个tuple,其输出为outputs, state_out = tf.contrib.rnn.static_rnn(cell, inputs, initial_state=tuple_state)
这样得到的state_out包含两个值,若所写的网络中间有多个隐藏层,则可以有更多状态输出。
同时对于双向LSTM,其输出outputs的每个单元尺寸为两个LSTM的隐藏层输出单元的和
LSTM网络代码
1 | def biLSTMCell(x, hiddenSize): |
需要使用unstack与stack函数变化矩阵维度结构,unstack将一个整体tf变量变成了一个数字list内部的多个tf量,作为输入进入网络输出后,再使用stack函数变回整体tf变量。
完整代码