【问题标题】:About Output of the Keras LSTM关于 Keras LSTM 的输出
【发布时间】:2019-12-03 02:45:45
【问题描述】:

我使用 Keras 构建了一个 LSTM 架构。我的目标是将长度为 29 的浮点时间序列输入序列映射到长度为 29 的浮点输出序列。我正在尝试实施“多对多”的方法。我跟着this post 实现了这样一个模型。

我首先将每个数据点重塑为形状为 `(1, 29, 1) 的 np.array。我有多个数据点,并分别在每个数据点上训练模型。以下代码是我构建模型的方式:

def build_model():
    # define model
    model = tf.keras.Sequential()
    model.add(tf.keras.layers.LSTM(29, return_sequences=True, input_shape=(29, 1)))
    model.add(tf.keras.layers.LeakyReLU(alpha=0.3))

    model.compile(optimizer='sgd', loss='mse', metrics = ['mae'])

    #cast data
    for point in train_dict:
        train_data = train_dict[point]

        train_dataset = tf.data.Dataset.from_tensor_slices((
            tf.cast(train_data[0], features_type),
            tf.cast(train_data[1], target_type))
        ).repeat() #cast into X, Y

        # fit model


        model.fit(train_dataset, epochs=100,steps_per_epoch = 1,verbose=0)


        print(model.summary())   
    return model 

我很困惑,因为当我调用 model.predict(test_point, steps = 1, verbose = 1) 时,模型返回 29 长度 29 序列!根据我对链接帖子的理解,我不明白为什么会这样。当我尝试 return_state=True 而不是 return_sequences=True 时,我的代码会引发此错误:ValueError: All layers in a Sequential model should have a single output tensor. For multi-output layers, use the functional API.

我该如何解决这个问题?

【问题讨论】:

  • test_point 的形状是什么?据我所知,您的模型输出[batch_size, 29, 29] 大小的输出。所以输出形状中会有两个 29(我假设这就是你得到的)。
  • test_point 也是 [1,29,1]。这也是我想输出的理想形状
  • 那么你需要在你的 LSTM 之上有一个密集层。我假设这是一个回归问题。因此,我在 LSTM 之上发布了一个带有线性密集层的答案。另外,我不确定您为什么要在 LSTM 之上应用 LeakyReLU。这对我来说似乎很奇怪。

标签: python tensorflow keras neural-network lstm


【解决方案1】:

您的模型几乎没有缺陷。

  1. 模型的最后一层是 LSTM。假设您正在进行分类/回归。这之后应该是一个密集层(SoftMax/sigmoid - 分类,线性 - 回归)。但由于这是一个时间序列问题,因此应将密集层包装在 TimeDistributed 包装器中。

  2. 在 LSTM 之上应用 LeakyReLU 很奇怪。

我已经修复了上述问题的代码。看看有没有帮助。

from tensorflow.keras.layers import Embedding, Input, Bidirectional, LSTM, Dense, Concatenate, LeakyReLU, TimeDistributed
from tensorflow.keras.initializers import Constant
from tensorflow.keras.models import Model
from tensorflow.keras.models import Sequential
def build_model():
    # define model
    model = Sequential()
    model.add(LSTM(29, return_sequences=True, input_shape=(29, 1)))
    model.add(TimeDistributed(Dense(1)))
    model.compile(optimizer='sgd', loss='mse', metrics = ['mae'])


    print(model.summary())   
    return model 

model = build_model()

【讨论】:

  • 成功了,谢谢!我正在使用 Leaky ReLu,因为我的 LSTM 通常只是在所有时间步骤中预测为 0。我读到如果问题是由死亡的 ReLu 引起的并且发现了良好的结果,那么泄漏的 ReLu 可以解决这个问题。为什么你觉得奇怪?
  • 还要跟进,我的model.summary() 报告TimeDistributed 层之前,LSTM 输出一个(None, 29, 29) 张量。我还是不明白为什么这不是(None, 29, 1)
  • 嗨@taurus,LSTM 的输出是 (None, 29, 29) 因为你的 LSTM 的潜在大小(即隐藏大小是 29)。如果真的希望 LSTM 输出为 (None, 29, 1),则 LSTM 层应为LSTM(1, …)
  • 关于你关于 ReLUs 的问题,你的论点是部分正确的。是的,LeakyReLU 作为一种非线性函数确实有助于缓解“神经元死亡”。但是 LSTM 已经在单元格中具有非线性(例如 tanh / sigmoid),并且您在这些非线性之上应用 LeakyReLU,这不是标准的做法。
猜你喜欢
  • 1970-01-01
  • 2018-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-16
  • 2019-01-04
  • 1970-01-01
  • 2018-11-06
相关资源
最近更新 更多