我已经使用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)
答案 0 :(得分:2)
我认为您的问题有两种解决方案。 (没有重复的时间步):
将pad_sequence layer与masking layer结合使用。这是常见的方法。现在,由于填充,每个样本都具有相同数量的时间步长。这种方法的好处是,它很容易实现。此外,Masking层将为您带来一点性能提升。 这种方法的缺点:如果在GPU上进行训练,则CuDNNLSTM是要使用的层,它针对gpu进行了高度优化,因此速度要快得多。但这不适用于遮罩层,并且如果您的数据集具有较大的时间步长,那么您将失去性能。
将timesteps-shape设置为None并编写一个keras生成器,该生成器将按时间步长对批次进行分组。(我认为您还必须使用功能性api)现在您可以实现CuDNNLSTM,每个示例都将仅使用相关的时间步长(而不是填充的时间步长)进行计算,效率更高。
如果您不熟悉keras,而性能并不那么重要,请选择方法1。如果您的生产环境经常需要培训网络并且与成本相关,请尝试方法2。