【发布时间】:2020-01-17 14:22:46
【问题描述】:
我有一个构建 LSTM 模型的脚本,将其用于训练数据,预测一些测试数据。 (只是为了对火车数据进行有趣的情节预测,因为它们应该接近火车数据,只是为了知道我的模型是否构建良好)
1) 第一个问题是,对测试数据和训练数据的预测完全不同,这取决于我是先预测训练数据还是先测试数据。
2) 第二个问题可能与第一个问题相关,所以每次我运行我的脚本时,对测试数据的预测都是完全不同的。我知道神经网络具有某种随机性,但正如您在我的结果图中看到的那样,它完全不同:
edit1:我尝试按照 cmets 中的建议设置 'stateful=False',但没有成功。
edit2:我更新了脚本和绘图,并在新代码中提供了一些基本的正弦波样本数据。即使在那个简单的例子中,问题仍然存在
resulting plots of predictions with stateful=False
我得到一个输入信号 X,它是具有 100 个时间步长和随机幅度和频率的正弦波。 我的目标 y 与 X 相关(在每个时间步)并且是 - 在这种情况下 - 也是一个正弦波。 我的数据的形状是
X_train.shape = (100, 1, 1)
y_train.shape = (100,)
X_test.shape = (100, 1, 1)
y_test.shape = (100,)
我正在使用 LSTM 网络尝试拟合完整的正弦波,因此批量大小 = 100,并预测测试信号的每个单点,因此预测的批量大小 = 1。此外,我正在手动重置状态每个 epoch 之后的 LSTM,如下所述: https://machinelearningmastery.com/use-different-batch-sizes-training-predicting-python-keras/
为了构建我的网络,我遵循了此处提到的“keras-rules”: Delayed echo of sin - cannot reproduce Tensorflow result in Keras
我知道解决问题的基本方法,如下所示: Wrong predictions with LSTM Neural Network 但对我没有任何帮助。
感谢您对此提供的任何帮助,以及提出更好的问题,以防我做错了什么,因为这是我在堆栈上的第一篇文章。
谢谢大家! 这是我的代码示例:
import numpy as np
import matplotlib.pyplot as plt
from keras import models, layers, optimizers
from keras.callbacks import Callback
# create training sample data
Fs = 100 # sample rate
z = np.arange(100)
f = 1 # frequency in Hz
X_train = np.sin(2 * np.pi * f * z / Fs)
y_train = 0.1 * np.sin(2 * np.pi * f * z / Fs)
# create test sample data
f = 1 # frequency in Hz
X_test = np.sin(2 * np.pi * f * z / Fs) * 2
y_test = 0.2 * np.sin(2 * np.pi * f * z / Fs)
# convert data into LSTM compatible format
y_train = np.array(y_train)
y_test = np.array(y_test)
X_train = X_train.reshape(X_train.shape[0], 1, 1)
X_test = X_test.reshape(X_test.shape[0], 1, 1)
# build and compile model
model = models.Sequential()
model.add(layers.LSTM(1, batch_input_shape=(len(X_train), X_train.shape[1], X_train.shape[2]),
return_sequences=False, stateful=False))
model.add(layers.Dense(X_train.shape[1], input_shape=(1,), activation='linear'))
model.compile(optimizer=optimizers.Adam(lr=0.01, decay=0.008, amsgrad=True), loss='mean_squared_error', metrics=['mae'])
# construct a class for keras callbacks, to make sure the cell state is reset after each epoch
class ResetStatesAfterEachEpoch(Callback):
def on_epoch_end(self, epoch, logs=None):
self.model.reset_states()
reset_state = ResetStatesAfterEachEpoch()
callbacks = [reset_state]
# fit model to training data
history = model.fit(X_train, y_train, epochs=20000, batch_size=len(X_train),
shuffle=False, callbacks=callbacks)
# re-define LSTM model with weights of fit model to predict for 1 point, so also re-define the batch size to 1
new_batch_size = 1
new_model = models.Sequential()
new_model.add(layers.LSTM(1, batch_input_shape=(new_batch_size, X_test.shape[1], X_test.shape[2]), return_sequences=False,
stateful=False))
new_model.add(layers.Dense(X_test.shape[1], input_shape=(1,), activation='linear'))
# copy weights to new model
old_weights = model.get_weights()
new_model.set_weights(old_weights)
# single point prediction on train data
y_pred_train = new_model.predict(X_train, batch_size=new_batch_size)
# single point prediction on test data
y_pred_test = new_model.predict(X_test, batch_size=new_batch_size)
# plot predictions
plt.figure()
plt.plot(y_test, 'r', label='ground truth test',
linestyle='dashed', linewidth=0.8)
plt.plot(y_train, 'b', label='ground truth train',
linestyle='dashed', linewidth=0.8)
plt.plot(y_pred_test, 'g',
label='y pred test', linestyle='dotted',
linewidth=0.8)
plt.plot(y_pred_train, 'k',
label='y pred train', linestyle='-.',
linewidth=0.8)
plt.title('pred order: test, train')
plt.xlabel('time steps')
plt.ylabel('y')
plt.legend(prop={'size': 8})
plt.show()
【问题讨论】:
-
能否请您详细说明 1) ?
-
在我的代码示例中,您可以看到我开始预测测试数据,然后预测训练数据。如果我以相反的方式启动脚本,那么首先在火车上进行预测,然后在测试数据上进行预测,结果会有所不同。你可以看到写在我提供的情节的“标题”中的差异
-
Matias 的回答能解决您的问题吗?注意:请与@otheruser 联系以获取通知。谢谢。
-
@Geeocode 很遗憾没有。
-
能否提供样本数据?
标签: keras deep-learning lstm prediction batchsize