首页 > 解决方案 > 如果我在上面堆叠一个全连接层,LSTM 的长度会如何变化?

问题描述

我尝试构建一个不同长度的 LSTM。首先,我制作 LSTM 单元,然后堆叠一个具有 2 个输出节点的全连接层。代码如下:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, TimeDistributed
from tensorflow.keras.utils import to_categorical
import numpy as np

model = Sequential()

model.add(LSTM(32, return_sequences=True, input_shape=(None, 5))) 
model.add(LSTM(8, return_sequences=True))
model.add(Dense(2, activation='sigmoid'))  

model.compile(loss='categorical_crossentropy',
              optimizer='adam')

for episode in range(2):
    sequence_length = np.random.randint(10, 100)
    x_train = np.random.random((1000, sequence_length, 5))
    y_train = x_train[:, :, 0]
    for i in range(1, 5):
        y_train[:, i:] += x_train[:, :-i, i]
    y_train = to_categorical(y_train > 2.5)
    model.fit(x_train, y_train, epochs=5, verbose=1)

但问题是,我知道 LSTM 的长度可以变化,但是当我将全连接层堆叠到它上面时,它的长度怎么可能仍然变化?

标签: pythontensorflowkerasdeep-learning

解决方案


简短的回答:该Dense层不关心除了最后一个维度之外的任何东西的大小,因此它“正常工作”,并且独立地应用于每个时间步。

查看LSTM 文档,它只接受 3D 数据块[batch, timesteps, feature]。然后它将遍历时间步长维度,循环地将输出作为下一个时间步的输入。

查看Dense docs,它接受任何大小的数据。如果您的数据有超过 2 个维度,它只会在每个中间维度上独立应用层。

也就是说,如果你给一个Dense层输入 shape [batch, timestep, feature_in],它将在batchtimestep维度上对操作进行矢量化,给你一个输出 shape [batch, timestep, feature_out]。您可以将其视为执行以下操作:

out = [dense_layer(inp[:, s]) for s in range(inp.shape[1])]  

需要注意的是,feature_infeature_out在这个描述中是在你创建你的模型时确定的,而不是在你给它一个例子的时候。

例如,假设我制作了一个密集层,它采用一个具有 2 个值的向量并创建一个具有 3 个值的向量。然后不管输入有多少维度,该层将把最后一个维度作为向量,并在所有其他维度上应用相同的操作

import tensorflow as tf
import numpy as np

dense_layer = tf.keras.layers.Dense(3, input_shape=(2,))

inp1 = tf.convert_to_tensor(np.random.random((4, 2)).astype(np.float32))
# <tf.Tensor 'Const:0' shape=(4, 2) dtype=float32>
out1 = dense_layer(inp1)
# <tf.Tensor 'dense/BiasAdd:0' shape=(4, 3) dtype=float32>

inp2 = tf.convert_to_tensor(np.random.random((5, 4, 2)).astype(np.float32))
# <tf.Tensor 'Const_1:0' shape=(5, 4, 2) dtype=float32>
out3 = dense_layer(inp2)
# <tf.Tensor 'dense/BiasAdd_1:0' shape=(5, 4, 3) dtype=float32>

inp3 = tf.convert_to_tensor(np.random.random((6, 5, 4, 2)).astype(np.float32))
# <tf.Tensor 'Const_2:0' shape=(6, 5, 4, 2) dtype=float32>
out3 = dense_layer(inp3)
# <tf.Tensor 'dense/BiasAdd_2:0' shape=(6, 5, 4, 3) dtype=float32>

inp4 = tf.convert_to_tensor(np.random.random((7, 6, 5, 4, 2)).astype(np.float32))
# <tf.Tensor 'Const_5:0' shape=(7, 6, 5, 4, 2) dtype=float32>
out4 = dense_layer(inp4)
# <tf.Tensor 'dense/BiasAdd_5:0' shape=(7, 6, 5, 4, 3) dtype=float32>

inp5 = tf.convert_to_tensor(np.random.random((8, 7, 6, 5, 4, 2)).astype(np.float32))
# <tf.Tensor 'Const_6:0' shape=(8, 7, 6, 5, 4, 2) dtype=float32>
out5 = dense_layer(inp5)
# <tf.Tensor 'dense/BiasAdd_6:0' shape=(8, 7, 6, 5, 4, 3) dtype=float32>

推荐阅读