

这个是网上看的最多的图了,但是在理解lstm的应用过程中的时候这个图带来了不少麻烦。

展开之后实际的物理结构是这样的,1、2图同颜色的点代表了同一个东西;
问题1:

这里的输入xt和ht是怎么结合的?比如:

这块儿很多地方都没讲清楚,实际上就是concat,直接concat起来了:

问题2:LSTM的权重到底是啥样的?
这里直接以tf.keras的代码为例子看看就造了:
def build_model(look_back: int, batch_size: int=1) -> Sequential:model = Sequential()model.add(LSTM(units=128,activation='relu',batch_input_shape=(batch_size, look_back, 1),stateful=True,return_sequences=False))model.add(Dense(1, activation='linear'))model.compile(loss='mean_squared_error', optimizer='adam')return model
model = build_model(28, batch_size=1)
首先,当我们的units=128的时候,LSTM的最终输出(仅考虑最后一个时间步输出,并且不考虑sequence的输出)就是128维的向量定下来了,对应的输出就是:

这里的最后一个ht的部分,注意这个ht既可以作为最终的输出,也是时间中的hidden state输入到下一个时间点的前向传播中去。
model.layers[0].trainable_variables

Param <tf.Variable 'lstm_4/lstm_cell_4/recurrent_kernel:0' shape=(128, 512) dtype=float32, numpy=
array([[ 3.0333996e-03, 1.4155725e-02, -3.9381277e-02, ...,
4.0887762e-02, -3.1605218e-02, -1.7439183e-02],
[-5.2204579e-02, 1.6296864e-02, 4.4382092e-02, ...,
2.1501739e-02, 5.1224865e-02, -5.1180001e-02],
[ 1.9754471e-02, -2.7741276e-02, -3.0992866e-02, ...,
1.8080823e-02, -2.1589132e-02, 8.2989247e-04],
...,
[-2.9214425e-05, -2.5351198e-02, -4.1916996e-02, ...,
-5.0040476e-02, -1.1436570e-02, 4.7302879e-02],
[-4.4846401e-02, 3.3629253e-03, 1.7752033e-02, ...,
-4.5454025e-02, -8.5912934e-03, -1.8942051e-02],
[-1.8914735e-02, -4.9705409e-02, -5.3823508e-02, ...,
3.6144644e-02, -2.1415317e-02, 1.5490238e-02]], dtype=float32)>:
(截图不知道怎么搞的一直上传失败)

可以看到,LSTM层一共有3组参数,第一组是512个参数,我们的LSTM的units设置为128,因此


这里的四个门,每一个门对应一个dense层,将input映射为128维,4个门一共4*128=512个参数,对应的就是第1组权重,注意,这里我们的输入的维度是1,因为就是简单的序列数据,没有其它的,所以这里第一个矩阵权重为(1,512),如果是embedding的话,比如embedding的维度是100,那么就是(100,512),tensorflow.keras这里把多个门的权重合并到一起来了。。。看了半天才看明白,其实严格一点应该是 4个 1*128的小矩阵,估计是为了工程上的便利和优化直接合并到一起了;
那么第三组的权重也很好理解,就是bias,

512个bias分别分配到这4个门的计算中;
最后是第二组权重,实际上就是
上一个时间步的ht-1到4个门的映射

我们前面说过上一个时间步的ht-1和这个时刻的输入xt是concat的,所以应该是(128+1)*128*4 这样比较好理解,不过tf.keras的权重不是按照这样保存的就是了,所以看代码的时候会有一点疑惑,不过总算看明白了shift~
问题3 LSTM的两个dropout是drop啥?
LSTM中有两个dropout的参数:
一个是
| dropout: Float between 0 and 1. Fraction of the units to drop for the linear
| transformation of the inputs. Default: 0.
这个dropout实际上就是输入X的dropout,


也就是这个部分做dropout
一个是
| recurrent_dropout: Float between 0 and 1. Fraction of the units to drop for
| the linear transformation of the recurrent state. Default: 0.

是针对于这个部分做dropout,
常规的dropout层是对LSTM最终的输出进行dropout。
问题四 :stateful LSTM 和 stateless LSTM有啥区别?
首先我们需要知道的是,我们平常大部分时候使用的LSTM都是属于stateless LSTM。

举个例子,比如情感分析:
“我 喜欢 你”当我们把这个句子的每个词embedding之后进入上面的这个LSTM的结构,到最终的时间步后,输出结束,此时,ht作为输出接一个分类层完成任务。
这个时候,tf.keras中的LSTM默认会reset_state,也就是

cell state和 hidden state都没有消失了。然后进入下一个句子的前向传播;
stateful LSTM则可以将当前句子的最终的cell state和hidden state的输出作为下个句子的初始的cell state和hidden state。
stateful LSTM:能让模型学习到你输入的samples之间的时序特征,适合一些长序列的预测,哪个sample在前,那个sample在后对模型是有影响的。尤鱼哥:Keras之stateful LSTM全面解析+实例测试zhuanlan.zhihu.com
stateless LSTM:输入samples后,默认就会shuffle,可以说是每个sample独立,之间无前后关系,适合输入一些没有关系的样本。详细可见:

很好理解了。
我们在做时间序列预测的时候可以同时考虑stateful LSTM和stateness LSTM看看哪个效果好。