这是我的代码,训练整个模型并保存它:
num_units = 2
activation_function = 'sigmoid'
optimizer = 'adam'
loss_function = 'mean_squared_error'
batch_size = 10
num_epochs = 100
# Initialize the RNN
regressor = Sequential()
# Adding the input layer and the LSTM layer
regressor.add(LSTM(units = num_units, activation = activation_function, input_shape=(None, 1)))
# Adding the output layer
regressor.add(Dense(units = 1))
# Compiling the RNN
regressor.compile(optimizer = optimizer, loss = loss_function)
# Using the training set to train the model
regressor.fit(x_train, y_train, batch_size = batch_size, epochs = num_epochs)
regressor.save('model.h5')
之后我已经看到大多数时候人们建议测试数据集来检查我已经尝试过的预测并获得了良好的结果。
但问题在于我创建的模型的使用。我希望对未来30天或每分钟做出预测。现在我有经过训练的模型,但我没有得到我能做的或者我用什么代码来使用模型并预测未来30天或一分钟的价格。
请建议我出路。我被困在这个问题一个星期,并没有能够做任何成功的尝试。
以下是存储库的链接,可以找到完整的可运行代码,模型和数据集:My repository link
答案 0 :(得分:9)
嗯,你需要一个stateful=True
模型,所以你可以一个接一个地预测它以获得下一个并保持模型认为每个输入不是一个新序列,而是前一个的续集。
修复代码和培训
我在代码中看到有人试图让你的y
成为一个shifte x
(预测后续步骤的一个很好的选择)。但是这里的预处理也存在一个很大的问题:
training_set = df_train.values
training_set = min_max_scaler.fit_transform(training_set)
x_train = training_set[0:len(training_set)-1]
y_train = training_set[1:len(training_set)]
x_train = np.reshape(x_train, (len(x_train), 1, 1))
LSTM
图层的数据必须设为(number_of_sequences, number_of_steps,features)
。
所以,你清楚地创建了仅一步的序列,这意味着你的LSTM根本就不是学习序列。 (没有只有一步的序列)。
假设您的数据是一个包含1个特征的唯一序列,那么它的形状肯定应为(1, len(x_train), 1)
。
当然,y_train
也应该具有相同的形状。
反过来,这将要求您的LSTM图层为return_sequences=True
- 使y
具有一定长度的唯一方法。此外,为了获得良好的预测,您可能需要一个更复杂的模型(因为现在它将是真正的学习)。
这样做,你训练你的模型,直到你得到满意的结果。
预测未来
为了预测未来,您需要stateful=True
LSTM图层。
在此之前,您重置模型的状态:model.reset_states()
- 每次您将新序列输入有状态模型时都需要。
然后,首先预测整个X_train
(这是模型需要了解序列的哪个点,技术词语:创建状态)。
predictions = model.predict(`X_train`) #this creates states
最后,您创建一个循环,从上一个预测的最后一步开始:
future = []
currentStep = predictions[:,-1:,:] #last step from the previous prediction
for i in range(future_pred_count):
currentStep = model.predict(currentStep) #get the next step
future.append(currentStep) #store the future steps
#after processing a sequence, reset the states for safety
model.reset_states()
示例强>
此代码使用2特征序列,移位的未来步骤预测和与此答案略有不同的方法,但基于相同的原理。
我创建了两个模型(一个stateful=False
,用于培训而无需每次都重置状态 - 永远不要忘记在重新启动新序列时重置状态 - 而另一个stateful=True
,从训练模型中复制权重,用于预测未来)
https://github.com/danmoller/TestRepo/blob/master/TestBookLSTM.ipynb
答案 1 :(得分:2)
为了使用 RNN 预测未来值,您需要做的是将数据作为序列提供。像这样:
[0 1 2] --> [3]
[1 2 3] --> [4]
[2 3 4] --> [5]
[3 4 5] --> [6]
[4 5 6] --> [7]
RNN 学习序列的结构,因此需要一个独特的输入形状:
(n_samples, time_steps, n_features)
例如,如果您使用上周的每一天,时间步长可能是 7。
您需要做的是为该函数提供 a) 当前值和 b) 未来值。此处,seq_length
是要使用的时间步数。
import tensorflow as tf
seq_length = 3
x = tf.range(25)[:-seq_length]
y = tf.range(25)[seq_length:]
ds = tf.keras.preprocessing.timeseries_dataset_from_array(x, y,
sequence_length=seq_length,
batch_size=1)
for present_values, next_value in ds.take(5):
print(tf.squeeze(present_values).numpy(), '-->', next_value.numpy())
[0 1 2] --> [3]
[1 2 3] --> [4]
[2 3 4] --> [5]
[3 4 5] --> [6]
[4 5 6] --> [7]
您也可以对多个变量执行相同的操作:
import tensorflow as tf
seq_length = 3
x = tf.concat([
tf.reshape(tf.range(25, dtype=tf.float32)[:-seq_length], (-1, 1)),
tf.reshape(tf.linspace(0., .24, 25) [:-seq_length], (-1, 1))], axis=-1)
y = tf.concat([
tf.reshape(tf.range(25, dtype=tf.float32)[seq_length:], (-1, 1)),
tf.reshape(tf.linspace(0., .24, 25) [seq_length:], (-1, 1))], axis=-1)
ds = tf.keras.preprocessing.timeseries_dataset_from_array(x, y,
sequence_length=seq_length,
batch_size=1)
for present_values, next_value in ds.take(5):
print(tf.squeeze(present_values).numpy(), '-->', tf.squeeze(next_value).numpy())
model = tf.keras.Sequential([
tf.keras.layers.LSTM(8),
tf.keras.layers.Dense(8, activation='relu'),
tf.keras.layers.Dense(2)
])
model.compile(loss='mae', optimizer='adam')
history = model.fit(ds)
[[0. 0. ]
[1. 0.01]
[2. 0.02]] --> [3. 0.03]
[[1. 0.01]
[2. 0.02]
[3. 0.03]] --> [4. 0.04]
[[2. 0.02]
[3. 0.03]
[4. 0.04]] --> [5. 0.05]
[[3. 0.03]
[4. 0.04]
[5. 0.05]] --> [6. 0.06]
[[4. 0.04]
[5. 0.05]
[6. 0.06]] --> [7. 0.07]
import tensorflow as tf
import numpy as np
x = np.arange(25)
def univariate_data(dataset, start_index, end_index, history_size, target_size):
data, labels = [], []
start_index = start_index + history_size
if end_index is None:
end_index = len(dataset) - target_size
for i in range(start_index, end_index):
indices = np.arange(i-history_size, i)
data.append(np.reshape(dataset[indices], (history_size, 1)))
labels.append(dataset[i:i+target_size])
return np.array(data), np.array(labels)
present_values, future_values = univariate_data(x, 0, 9, 3, 3)
for present, next_val in zip(present_values, future_values):
print(tf.squeeze(present).numpy(), '-->', tf.squeeze(next_val).numpy())
[0 1 2] --> [3 4]
[1 2 3] --> [4 5]
[2 3 4] --> [5 6]
[3 4 5] --> [6 7]
[4 5 6] --> [7 8]
[5 6 7] --> [8 9]
现在对于多个变量:
import tensorflow as tf
import numpy as np
history_size = 3
x = np.concatenate([np.expand_dims(np.arange(25), 1)[:-history_size],
np.expand_dims(np.linspace(0., .24, 25), 1)[:-history_size]], axis=1)
y = np.concatenate([np.expand_dims(np.arange(25), 1)[history_size:],
np.expand_dims(np.linspace(0., .24, 25), 1)[history_size:]], axis=1)
def multivariate_data(dataset, target, start_index, end_index, history_size,
target_size, step, single_step=False):
data = []
labels = []
start_index = start_index + history_size
if end_index is None:
end_index = len(dataset) - target_size
for i in range(start_index, end_index):
indices = range(i-history_size, i, step)
data.append(dataset[indices])
if single_step:
labels.append(target[i+target_size])
else:
labels.append(target[i:i+target_size])
return np.array(data), np.array(labels)
present_values, future_values = multivariate_data(x, y, 0, 8, history_size, 1, 1)
for present, next_val in zip(present_values, future_values):
print(tf.squeeze(present).numpy(), '-->', tf.squeeze(next_val).numpy())
[[0. 0. ]
[1. 0.01]
[2. 0.02]] --> [6. 0.06]
[[1. 0.01]
[2. 0.02]
[3. 0.03]] --> [7. 0.07]
[[2. 0.02]
[3. 0.03]
[4. 0.04]] --> [8. 0.08]
[[3. 0.03]
[4. 0.04]
[5. 0.05]] --> [9. 0.09]
[[4. 0.04]
[5. 0.05]
[6. 0.06]] --> [10. 0.1]
import tensorflow as tf
import numpy as np
history_size = 3
lookahead = 2
x = tf.range(8)
ds = tf.data.Dataset.from_tensor_slices(x)
ds = ds.window(history_size + lookahead, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda window: window.batch(history_size + lookahead))
ds = ds.map(lambda window: (window[:-lookahead], window[-lookahead:]))
for present_values, next_value in ds:
print(present_values.numpy(), '-->', next_value.numpy())
[0 1 2] --> [3 4]
[1 2 3] --> [4 5]
[2 3 4] --> [5 6]
[3 4 5] --> [6 7]
有多个变量:
import tensorflow as tf
import numpy as np
history_size = 3
lookahead = 2
x = tf.concat([
tf.reshape(tf.range(20, dtype=tf.float32), (-1, 1)),
tf.reshape(tf.linspace(0., .19, 20), (-1, 1))], axis=-1)
ds = tf.data.Dataset.from_tensor_slices(x)
ds = ds.window(history_size + lookahead, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda window: window.batch(history_size + lookahead))
ds = ds.map(lambda window: (window[:-lookahead], window[-lookahead:]))
for present_values, next_value in ds.take(8):
print(tf.squeeze(np.round(present_values, 2)).numpy(), '-->',
tf.squeeze(np.round(next_value, 2)).numpy())
print()
[[0. 0. ]
[1. 0.01]
[2. 0.02]] --> [[3. 0.03]
[4. 0.04]]
[[1. 0.01]
[2. 0.02]
[3. 0.03]] --> [[4. 0.04]
[5. 0.05]]
[[2. 0.02]
[3. 0.03]
[4. 0.04]] --> [[5. 0.05]
[6. 0.06]]
[[3. 0.03]
[4. 0.04]
[5. 0.05]] --> [[6. 0.06]
[7. 0.07]]
[[4. 0.04]
[5. 0.05]
[6. 0.06]] --> [[7. 0.07]
[8. 0.08]]
[[5. 0.05]
[6. 0.06]
[7. 0.07]] --> [[8. 0.08]
[9. 0.09]]
答案 2 :(得分:0)
在我的案例中,我在下面几乎没有修改的情况下使用了此代码。它工作正常。谢谢
future_pred_count=10
future = []
currentStep = np.array([187, 196, 210])
for i in range(future_pred_count):
prediction = model.predict(currentStep[np.newaxis, :, np.newaxis]) # set dimentions
future.append(prediction[0][0])
currentStep = np.append(currentStep[1:], prediction[0][0], axis=None ) #store the future steps
print(future)