LSTM和Keras用于小批量培训和在线测试

LSTM和Keras用于小批量培训和在线测试,keras,lstm,Keras,Lstm,我想在Keras中实现一个用于流式时间序列预测的LSTM——即在线运行,一次获取一个数据点,但正如人们所设想的那样,在线LSTM的培训时间可能非常缓慢。我想在小批量上训练我的网络,并在线测试(运行预测)。在Keras中这样做的最佳方式是什么 例如,一个小批量可以是在连续的时间步发生的1000个数据值的序列([33,34,42,33,32,33,36,…24,23])。为了训练网络,我指定了一个形状为(900,100,1)的数组X,其中有900个长度为100的序列,以及一个形状为(900,1)的数

我想在Keras中实现一个用于流式时间序列预测的LSTM——即在线运行,一次获取一个数据点,但正如人们所设想的那样,在线LSTM的培训时间可能非常缓慢。我想在小批量上训练我的网络,并在线测试(运行预测)。在Keras中这样做的最佳方式是什么

例如,一个小批量可以是在连续的时间步发生的1000个数据值的序列(
[33,34,42,33,32,33,36,…24,23]
)。为了训练网络,我指定了一个形状为
(900,100,1)
的数组
X
,其中有900个长度为100的序列,以及一个形状为
(900,1)
的数组
y
。例如:

X[0] = [[33], [34], [42], [33], ...]]
X[1] = [[34], [42], [33], [32], ...]]
...
X[999] = [..., [24]]

y[999] = [23]
因此,对于每个序列,
X[i]
,都有一个对应的
y[i]
表示时间序列中的下一个值——我们想要预测的值

在测试中,我想预测下一个数据值1000到1999。我通过为1000到1999年的每一步输入一个shape
(1100,1)
数组来实现这一点,其中模型试图预测下一步的值

这是解决我的问题的推荐方法和设置吗?启用状态性可能是纯在线实现的方式,但在Keras中,这需要在培训和测试中使用一致的
批输入形状
,这不符合我在小批量上培训然后在线测试的意图。或者我有办法做到这一点吗

更新:尝试按照@nemo的建议实施网络

我在一篇博客文章中的一个示例网络上运行了自己的数据集,然后尝试将预测阶段实现为一个有状态网络

以下两种情况下的模型构建和培训是相同的:

# Create and fit the LSTM network
numberOfEpochs = 10
look_back = 30
model = Sequential()
model.add(LSTM(4, input_dim=1, input_length=look_back))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, nb_epoch=numberOfEpochs, batch_size=1, verbose=2)
# trainX.shape = (6883, 30, 1)
# trainY.shape = (6883,)
# testX.shape = (3375, 30, 1)
# testY.shape = (3375,)
批次预测通过以下方式完成:

trainPredict = model.predict(trainX, batch_size=batch_size)
testPredict = model.predict(testX, batch_size=batch_size)
为了尝试有状态的预测阶段,我运行了与之前相同的模型设置和培训,但接下来是:

w = model.get_weights()
batch_size = 1
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
trainPredictions, testPredictions = [], []
for trainSample in trainX:
    trainPredictions.append(model.predict(trainSample.reshape((1,look_back,1)), batch_size=batch_size))
trainPredict = numpy.concatenate(trainPredictions).ravel()
for testSample in testX:
    testPredictions.append(model.predict(testSample.reshape((1,look_back,1)), batch_size=batch_size))
testPredict = numpy.concatenate(testPredictions).ravel()
为了检查结果,下图以蓝色显示实际(标准化)数据,以绿色显示训练集上的预测,以红色显示测试集上的预测


第一个图来自使用批处理预测,第二个图来自stateful。你知道我做错了什么吗?

如果我理解正确,你会问你是否可以在培训后启用状态。这应该是可能的,是的。例如:

net = Dense(1)(SimpleRNN(stateful=False)(input))
model = Model(input=input, output=net)

model.fit(...)

w = model.get_weights()
net = Dense(1)(SimpleRNN(stateful=True)(input))
model = Model(input=input, output=net)
model.set_weights(w)

之后,您可以有状态地进行预测。

谢谢。我已经尝试过实现这一点,但仍然存在一些问题。请看编辑后的问题。我真的很感谢你的帮助!两件事:你永远不会重置你的重复图层的状态,数据看起来非常相似,但缩放方式不同;例如,这可能是一个简单的绘图缩放问题。在任何情况下,这个问题都不再适合这样做了。最好是自己做测试,把事情浓缩起来,并制定简短的问题:)在培训和在线测试中使用状态。在培训期间,只需在每个批次后重置状态。由于所有数据的结构都是相同的,因此这也使事情变得更容易。对于其他想要了解keras中有状态LSTM的人,这里有一个教程:
model.set_weights(w)
在最后一个代码块中缺失。另外,正如尼莫在评论中指出的那样,我仔细观察了第二组结果,结果的起伏与蓝线有着非常高的相关性。