当使用Keras LSTM预测时间序列数据时,当我尝试使用批量大小为50训练模型时,我一直在收到错误,然后尝试使用批量大小为1(即批量大小)进行预测只是预测下一个值).
为什么我无法同时训练和匹配多个批次的模型,然后使用该模型预测除了相同批次大小之外的任何其他内容.它似乎没有意义,但后来我很容易就会遗漏一些关于此的东西.
编辑:这是模型. batch_size
是50,sl
是序列长度,目前设置为20.
model = Sequential() model.add(LSTM(1, batch_input_shape=(batch_size, 1, sl), stateful=True)) model.add(Dense(1)) model.compile(loss='mean_squared_error', optimizer='adam') model.fit(trainX, trainY, epochs=epochs, batch_size=batch_size, verbose=2)
这是预测RMSE训练集的线
# make predictions trainPredict = model.predict(trainX, batch_size=batch_size)
这是对看不见的时间步骤的实际预测
for i in range(test_len): print('Prediction %s: ' % str(pred_count)) next_pred_res = np.reshape(next_pred, (next_pred.shape[1], 1, next_pred.shape[0])) # make predictions forecastPredict = model.predict(next_pred_res, batch_size=1) forecastPredictInv = scaler.inverse_transform(forecastPredict) forecasts.append(forecastPredictInv) next_pred = next_pred[1:] next_pred = np.concatenate([next_pred, forecastPredict]) pred_count += 1
这个问题与行:
forecastPredict = model.predict(next_pred_res, batch_size=batch_size)
batch_size此处设置为1时的错误是:
ValueError: Cannot feed value of shape (1, 1, 2) for Tensor 'lstm_1_input:0', which has shape '(10, 1, 2)'
这是与batch_size
其他批量大小一样设置为50 时抛出的相同错误.
总误差是:
forecastPredict = model.predict(next_pred_res, batch_size=1) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/keras/models.py", line 899, in predict return self.model.predict(x, batch_size=batch_size, verbose=verbose) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/keras/engine/training.py", line 1573, in predict batch_size=batch_size, verbose=verbose) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/keras/engine/training.py", line 1203, in _predict_loop batch_outs = f(ins_batch) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/keras/backend/tensorflow_backend.py", line 2103, in __call__ feed_dict=feed_dict) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 767, in run run_metadata_ptr) File "/home/entelechy/tf_keras/lib/python3.5/site-packages/tensorflow/python/client/session.py", line 944, in _run % (np_val.shape, subfeed_t.name, str(subfeed_t.get_shape()))) ValueError: Cannot feed value of shape (1, 1, 2) for Tensor 'lstm_1_input:0', which has shape '(10, 1, 2)'
编辑:一旦我将模型设置为stateful=False
然后我就可以使用不同的批量大小进行拟合/训练和预测.这是什么原因?
不幸的是,你想要做的事情对Keras来说是不可能的......我也在这个问题上花费了很多时间,唯一的方法就是潜入兔子洞并与Tensorflow直接合作进行LSTM滚动预测.
首先,要明确术语,batch_size
通常意味着一起训练的序列数量,并且num_steps
意味着一起训练多少时间步骤.当你的意思是batch_size=1
"只是预测下一个价值"时,我认为你的意思是预测num_steps=1
.
否则,应该可以训练和预测batch_size=50
你正在训练50个序列并且每个时间步进行50个预测,每个序列一个(意味着训练/预测num_steps=1
).
但是,我认为你的意思是你想使用有状态LSTM进行训练num_steps=50
并进行预测num_steps=1
.从理论上讲,这可以使感觉成为可能,并且Tensorflow可以实现,而不是Keras.
问题:Keras需要有状态RNN的显式批量大小.您必须指定batch_input_shape(batch_size,num_steps,features).
原因是:Keras必须在计算图中使用shape(batch_size,num_units)分配固定大小的隐藏状态向量,以便在训练批次之间保留值.另一方面,当stateful=False
隐藏状态向量可以在每批开始时用零动态初始化,因此它不需要是固定大小.更多细节在这里:http://philipperemy.github.io/keras-stateful-lstm/
可能的解决方法:训练和预测num_steps=1
.示例:https://github.com/keras-team/keras/blob/master/examples/lstm_stateful.py.对于您的问题,这可能会或可能根本不起作用,因为反向传播的梯度将仅在一个时间步上计算.请参阅:https://github.com/fchollet/keras/issues/3669
我的解决方案:使用Tensorflow:在Tensorflow中你可以训练batch_size=50, num_steps=100
,然后做预测batch_size=1, num_steps=1
.这可以通过为训练和预测共享相同的RNN权重矩阵创建不同的模型图来实现.请参阅此示例以了解下一个字符预测:https://github.com/sherjilozair/char-rnn-tensorflow/blob/master/model.py#L11和博客文章http://karpathy.github.io/2015/05/21/rnn-effectiveness /.请注意,一个图仍然只能使用一个指定的图batch_size
,但您可以在Tensorflow中设置多个共享权重的模型图.
可悲的是,你所希望的是不可能的,因为你在定义模型时指定了batch_size ......但是,我找到了解决这个问题的简单方法:创建2个模型!第一个用于训练,第二个用于预测,并让它们共享权重:
train_model = Sequential([Input(batch_input_shape=(batch_size,...),]) predict_model = Sequential([Input(batch_input_shape=(1,...), ]) train_model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam()) predict_model.compile(loss='sparse_categorical_crossentropy', optimizer=Adam())
现在,您可以使用任何所需的批量大小.在你的train_model适合之后,只需保存它的权重并使用predict_model加载它们:
train_model.save_weights('lstm_model.h5') predict_model.load_weights('lstm_model.h5')
注意你只想保存和加载权重,而不是整个模型(包括架构,优化器等......).这样你就可以获得权重,但你可以一次输入一批...更多关于keras保存/加载模型:https: //keras.io/getting-started/faq/#how-can-i-save-a -keras模型
请注意,您需要安装h5py才能使用"保存权重".