LSTM with Keras 用于小批量训练和在线测试
LSTM with Keras for mini-batch training and online testing
我想在 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 的每个步骤提供一个形状为 (1, 100, 1)
的数组来做到这一点,其中模型试图预测值下一步。
这是针对我的问题推荐的方法和设置吗?启用有状态性可能是纯在线实现的方式,但在 Keras 中,这需要在训练和测试中保持一致 batch_input_shape
,这对我的小批量训练然后在线测试的意图不起作用。或者我有办法做到这一点吗?
更新:尝试按照@nemo 推荐的方式实施网络
我 运行 我自己的数据集来自博客 post "Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras" 的示例网络,然后尝试将预测阶段实现为有状态网络。
两者的模型构建和训练相同:
# 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()
为了检查结果,下图以蓝色显示实际(归一化)数据,以绿色显示对训练集的预测,以红色显示对测试集的预测。
第一张图来自使用批量预测,第二张来自有状态。知道我做错了什么吗?
如果我没理解错的话,你是在问是否可以在训练后启用状态。这应该是可能的,是的。例如:
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 以进行流式时间序列预测——即,运行在线,一次获取一个数据点。
例如,小批量可以是连续时间步长出现的 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 的每个步骤提供一个形状为 (1, 100, 1)
的数组来做到这一点,其中模型试图预测值下一步。
这是针对我的问题推荐的方法和设置吗?启用有状态性可能是纯在线实现的方式,但在 Keras 中,这需要在训练和测试中保持一致 batch_input_shape
,这对我的小批量训练然后在线测试的意图不起作用。或者我有办法做到这一点吗?
更新:尝试按照@nemo 推荐的方式实施网络
我 运行 我自己的数据集来自博客 post "Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras" 的示例网络,然后尝试将预测阶段实现为有状态网络。
两者的模型构建和训练相同:
# 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()
为了检查结果,下图以蓝色显示实际(归一化)数据,以绿色显示对训练集的预测,以红色显示对测试集的预测。
第一张图来自使用批量预测,第二张来自有状态。知道我做错了什么吗?
如果我没理解错的话,你是在问是否可以在训练后启用状态。这应该是可能的,是的。例如:
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)
之后你可以用有状态的方式进行预测。