Python 这个扁平层在我的LSTM中做什么?

Python 这个扁平层在我的LSTM中做什么?,python,machine-learning,keras,lstm,flatten,Python,Machine Learning,Keras,Lstm,Flatten,我正在使用Keras创建一个用于情绪分析的LSTM,它是IMDB数据库的一个子集。如果我在最终密集层之前添加一个展平层,我的培训、验证和测试精度将显著提高: def lstm_model_flatten(): embedding_dim = 128 model = Sequential() model.add(layers.Embedding(vocab_size, embedding_dim, input_length=maxlen)) model.add(la

我正在使用Keras创建一个用于情绪分析的LSTM,它是IMDB数据库的一个子集。如果我在最终密集层之前添加一个展平层,我的培训、验证和测试精度将显著提高:

def lstm_model_flatten():
    embedding_dim = 128
    model = Sequential()
    model.add(layers.Embedding(vocab_size, embedding_dim, input_length=maxlen))
    model.add(layers.LSTM(128, return_sequences = True,  dropout=0.2)) 
    # Flatten layer
    model.add(layers.Flatten())
    model.add(layers.Dense(1,activation='sigmoid'))
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    model.summary()
    return model
这很快就超出了范围,但验证准确率高达76%左右:

Model: "sequential_43"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding_42 (Embedding)     (None, 500, 128)          4768256   
_________________________________________________________________
lstm_63 (LSTM)               (None, 500, 128)          131584    
_________________________________________________________________
flatten_10 (Flatten)         (None, 64000)             0         
_________________________________________________________________
dense_40 (Dense)             (None, 1)                 64001     
=================================================================
Total params: 4,963,841
Trainable params: 4,963,841
Non-trainable params: 0
_________________________________________________________________
Epoch 1/7
14/14 [==============================] - 26s 2s/step - loss: 0.6911 - accuracy: 0.5290 - val_loss: 0.6802 - val_accuracy: 0.5650
Epoch 2/7
14/14 [==============================] - 23s 2s/step - loss: 0.6451 - accuracy: 0.6783 - val_loss: 0.6074 - val_accuracy: 0.6950
Epoch 3/7
14/14 [==============================] - 23s 2s/step - loss: 0.4594 - accuracy: 0.7910 - val_loss: 0.5237 - val_accuracy: 0.7300
Epoch 4/7
14/14 [==============================] - 23s 2s/step - loss: 0.2566 - accuracy: 0.9149 - val_loss: 0.4753 - val_accuracy: 0.7650
Epoch 5/7
14/14 [==============================] - 23s 2s/step - loss: 0.1397 - accuracy: 0.9566 - val_loss: 0.6011 - val_accuracy: 0.8050
Epoch 6/7
14/14 [==============================] - 23s 2s/step - loss: 0.0348 - accuracy: 0.9898 - val_loss: 0.7648 - val_accuracy: 0.8100
Epoch 7/7
14/14 [==============================] - 23s 2s/step - loss: 0.0136 - accuracy: 0.9955 - val_loss: 0.8829 - val_accuracy: 0.8150
在没有展平层的情况下使用相同的体系结构(并且在LSTM层上使用return_sequences=False)只能产生大约50%的验证精度

上的注释建议在密集层之前使用
return\u sequences=False
,而不是平坦层


但为什么会这样呢?如果它改进了我的模型,可以使用展平层吗?展平层到底在做什么?为什么它能提高精度?

LSTM层由顺序处理的不同LSTM单元组成。如下图所示,第一个单元格接受输入/嵌入计算隐藏状态,下一个单元格使用其输入和上一时间步的隐藏状态计算其自身的隐藏状态。基本上,单元格之间的箭头也通过隐藏状态如果执行
返回\u sequences=False
,则lstm层仅输出最后一个隐藏状态
(图中为h_4)因此,来自所有输入和单元格的所有信息都嵌入到一个固定大小的信息中,它不能包含大量信息。这就是为什么当您仅使用最后一个隐藏状态时,您的准确性不高

当您执行
return\u sequences=True
时,lstm层输出每个隐藏状态,因此下一层可以访问所有隐藏状态,并且它们自然包含更多信息。但是,LSTM层返回一个矩阵。您也可以在模型摘要中看到这一点。它返回一个大小为(None、500128)的矩阵。“无”基本上是指批次中的样本数量,您可以忽略它。500是输入大小,128是隐藏状态大小。稠密层不能处理矩阵,它必须是向量。这就是为什么需要应用展平,它所做的基本上只是打开2D矩阵并将其表示为1D向量。因此,展平层的大小为64000,因为500*128=64000。当然,随着隐藏状态的增加,精确度也会提高,因为它们包含了更多的信息。

我投票决定结束这个问题,因为它不是关于中定义的编程,而是关于ML理论和/或方法-请参阅机器学习中的介绍和说明。对此表示抱歉。我已经去掉了机器学习的标签。恐怕你没抓住重点;请注意,一个问题是否在这里与主题相关,只与问题的内容有关,并且不能仅通过标记操纵来解决。如果问题是标签本身,我会自己删除它而不采取任何进一步的行动。准确度的变化可能更多地来自于使用
return\u sequences=True
而不是使用
Flatten
return_sequences=True
将使LSTM的每一步输出一个值,而不仅仅是最后一步。这意味着网络的最后部分有更多的输出值要处理。
展平
层只是更改输出的尺寸形状。非常感谢,这非常有用。我一直认为return_sequences=True仅在有多个LSTM层时使用,以将一个LSTM层的输出传递到下一个LSTM层。我知道最后一个(或单个)LSTM层应该有返回序列=False。但是听起来把所有隐藏状态的输出传递到稠密层也没问题吧?很高兴我能帮上忙!如果你能投票并接受答案,如果你觉得有帮助的话,我会很高兴的。你完全正确。这是最常见的用例,但没有规则像单个层必须有return_seq false那样。这取决于你想对隐藏状态做什么,你想如何组合它们等等。是的,使用所有隐藏状态输出是可以的,甚至是推荐的,因为下面的层可以访问更多的信息