【问题标题】:Multi-Feature Sequence Padding and Masking in RNN using Keras使用 Keras 的 RNN 中的多特征序列填充和屏蔽
【发布时间】:2019-01-14 03:46:51
【问题描述】:

我已经使用 Keras 构建了 LSTM 架构,但我不确定复制时间步长是否是处理可变序列长度的好方法。

我有一个具有多特征序列和不同时间步长的多维数据集。它是一个多元时间序列数据,包含多个用于训练 LSTM 的示例,Y 为 0 或 1。目前,我正在为每个序列复制最后的时间步长以确保 timesteps = 3

如果有人能回答以下问题或疑虑,我将不胜感激: 1. 用零表示的特征值创建额外的时间步更合适吗?
2. 解决这个问题的正确方法是什么、填充序列和评估掩码。
3. 我也在 Y 变量中复制最后一个时间步以进行预测,并且 Y 中的值 1 仅出现在最后一个时间步。

# The input sequences are
trainX = np.array([
        [
            # Input features at timestep 1
            [1, 2, 3],
            # Input features at timestep 2
            [5, 2, 3] #<------ duplicate this to ensure compliance
        ],
        # Datapoint 2
        [
            # Features at timestep 1
            [1, 8, 9],
            # Features at timestep 2
            [9, 8, 9],
            # Features at timestep 3
            [7, 6, 1]
        ]
    ])

# The desired model outputs is as follows:
trainY = np.array([
        # Datapoint 1
        [
            # Target class at timestep 1
            [0],
            # Target class at timestep 2
            [1] #<---------- duplicate this to ensure compliance
        ],
        # Datapoint 2
        [
            # Target class at timestep 1
            [0],
            # Target class at timestep 2
            [0]
            # Target class at time step 3
            [0]
        ]
    ])

timesteps = 3
model = Sequential()
model.add(LSTM(3, kernel_initializer ='uniform', return_sequences=True, batch_input_shape=(None, timesteps, trainX.shape[2]), 
               kernel_constraint=maxnorm(3), name='LSTM'))
model.add(Dropout(0.2))
model.add(LSTM(3, return_sequences=True, kernel_constraint=maxnorm(3), name='LSTM-2'))
model.add(Flatten(name='Flatten'))
model.add(Dense(timesteps, activation='sigmoid', name='Dense'))
model.compile(loss="mse", optimizer="sgd", metrics=["mse"])
model.fit(trainX, trainY, epochs=2000, batch_size=2)
predY = model.predict(testX)

【问题讨论】:

    标签: keras padding lstm masking


    【解决方案1】:

    在我看来,您的问题有两种解决方案。 (重复的时间步都没有):

    1. pad_sequence layermasking layer 结合使用。这是常用的方法。现在多亏了填充,每个样本都有相同的时间步数。这种方法的好处是,它很容易实现。此外,遮罩层会给你一点性能提升。 这种方法的缺点:如果你在 GPU 上训练,CuDNNLSTM 是要走的层,它针对 gpu 进行了高度优化,因此速度要快得多。但它不适用于遮罩层,如果您的数据集的时间步长范围很大,那么您将失去性能。

    2. 将你的时间步长形状设置为无,并编写一个 keras 生成器,它将按时间步长对你的批次进行分组。(我认为你还必须使用功能 API)现在你可以实现 CuDNNLSTM,每个样本都将是仅使用相关时间步(而不是填充时间步)计算,效率更高。

    如果您是 keras 新手并且性能不是那么重要,请使用选项 1。如果您有一个经常需要训练网络并且成本相关的生产环境,请尝试选项 2。

    【讨论】:

    • 选项 1 意味着我必须摆脱 Flatten 层,因为它与遮罩不兼容。此外,不填充测试数据会返回错误,那么是否填充测试数据会有所不同吗?
    • 基本思想是,LSTM 层可以处理不同 timspes_length 变化的数据。 . . .但不在同一批次。我会应用与训练数据集相同的预处理,但您也可以执行选项 2 之类的操作或使用批量大小 1 进行验证。我想知道您为什么要首先使用 Flatten。通常,您只需在最后一个 LSTM 层中删除 return_sequence 。但是选项 1 也可以在没有遮罩的情况下工作,因此即使没有遮罩,您也可能会没事。
    • @dennis-ec 请在 MLP 的情况下如何使用填充和遮罩层。
    • @DINATAKLIT 发布您自己的问题来解释更多关于您的问题以及您想要归档的内容可能更有意义。现在我不明白你为什么要首先在 MLP 中使用填充。
    • @dennis-ec 我想在我的 MLP 中使用带掩码层的零填充,因为我的输入长度可变。我的问题的详细信息在这里:stackoverflow.com/questions/55270074/…。让我知道是否需要提供更多详细信息。
    猜你喜欢
    • 2016-10-15
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 2021-03-03
    • 2020-08-06
    • 1970-01-01
    相关资源
    最近更新 更多