基于Keras的RNN多特征序列填充和掩蔽

基于Keras的RNN多特征序列填充和掩蔽,keras,padding,lstm,masking,Keras,Padding,Lstm,Masking,我已经使用Keras构建了LSTM体系结构,但我不确定复制时间步长是否是处理可变序列长度的好方法 我有一个多维数据集,具有多特征序列和变化的时间步长。这是一个多变量时间序列数据,有多个示例来训练LSTM,Y为0或1。目前,我正在为每个序列复制上一个时间步,以确保timesteps=3 如果有人能回答以下问题或顾虑,我将不胜感激: 1.使用零表示的特征值创建额外的时间步长是否更合适? 2.确定此问题的正确方法是什么、焊盘顺序和用于评估的掩码。 3.我也在复制Y变量中的最后一个时间步进行预测,Y中的

我已经使用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)
#输入序列为
trainX=np.array([
[
#在时间步1输入功能
[1, 2, 3],
#在时间步2输入功能

[5,2,3]#在我看来,有两种方法可以解决您的问题。(复制时间步长不是其中之一):

  • 结合使用。这是常见的方法。现在由于填充,每个样本都有相同的时间步数。这种方法的优点是,它非常容易实现。此外,掩蔽层将给您带来一点性能提升。 这种方法的缺点是:如果你在GPU上训练,CuDNNLSTM就是要去的层,它针对GPU进行了高度优化,因此速度要快得多。但它不适用于掩蔽层,如果你的数据集有很高的时间步长范围,你就会失去性能

  • 将timesteps shape设置为None并编写一个keras生成器,它将按timesteps对批进行分组。(我认为您还必须使用函数api)现在您可以实现CuDNNLSTM,并且每个样本将仅使用相关的timesteps(而不是填充的timesteps)进行计算,这将更加高效


  • 如果您是keras新手,并且性能不太重要,请选择选项1。如果您的生产环境中经常需要训练网络,并且与成本相关,请尝试选项2。

    选项1意味着我必须去掉扁平层,因为它与掩蔽不兼容。此外,不填充测试数据会返回错误r、 那么,如果我填充测试数据与不填充测试数据有什么区别吗?基本思想是,LSTM层可以处理不同timspes_长度的数据…但不能在同一批中。我将应用与火车数据集中相同的预处理,但您也可以执行类似选项2的操作,或使用1的批大小进行验证。我想知道您为什么要这样做首先要使用“展平”。通常情况下,您只需删除最后一个LSTM层中的返回序列。但选项1也可以在没有掩蔽的情况下工作,因此即使没有掩蔽,您也可能会很好。@dennis ec请说明在MLP情况下如何使用填充和掩蔽层。@DINATAKLIT发布您自己的问题解释m可能更有意义更多关于您的问题以及您想要归档的内容。现在我不明白您为什么首先要在MLP中使用填充。@dennis ec我想在MLP中使用零填充和掩码层,因为我有可变的输入长度。我问题的详细信息在这里:。如果清楚,请告诉我。需要提供更多详细信息。