fro*_*ael 4 python time-series keras recurrent-neural-network
我一直在阅读有关 Keras RNN 模型(LSTM 和 GRU)的内容,作者似乎主要关注语言数据或使用由先前时间步骤组成的训练实例的单变量时间序列。我的数据有点不同。
我在 10 年中每年测量 100,000 人的 20 个变量作为输入数据,并将第 11 年测量的 20 个变量作为输出数据。我想做的是预测第 11 年其中一个变量(而不是其他 19 个)的值。
我的数据结构为X.shape = [persons, years, variables] = [100000, 10, 20]
和Y.shape = [persons, variable] = [100000, 1]
。下面是我的 LSTM 模型的 Python 代码。
## LSTM model.
# Define model.
network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(128, activation = 'tanh',
input_shape = (X.shape[1], X.shape[2])))
network_lstm.add(layers.Dense(1, activation = None))
# Compile model.
network_lstm.compile(optimizer = 'adam', loss = 'mean_squared_error')
# Fit model.
history_lstm = network_lstm.fit(X, Y, epochs = 25, batch_size = 128)
Run Code Online (Sandbox Code Playgroud)
我有四个(相关的)问题,请:
我是否针对我拥有的数据结构正确编码了 Keras 模型?我从全连接网络(使用扁平数据)和 LSTM、GRU 和 1D CNN 模型获得的性能几乎相同,我不知道我是否在 Keras 中犯了错误,或者循环模型是否只是简单在这种情况下没有帮助。
我是否应该将 Y 作为具有 shape 的系列Y.shape = [persons, years] = [100000, 11]
,而不是将变量包含在 X 中,然后 X 就会具有 shape X.shape = [persons, years, variables] = [100000, 10, 19]
?如果是这样,如何让 RNN 输出预测序列?当我使用 时return_sequences = True
,Keras 返回错误。
这是利用我所拥有的数据进行预测的最佳方法吗?Keras RNN 模型甚至其他模型是否有更好的选择?
如何模拟与我所拥有的数据结构类似的数据,以便 RNN 模型的性能优于全连接网络?
更新:
我尝试过模拟,我希望是一个非常简单的情况,其中 RNN 应该优于 FNN。
虽然 LSTM 在隐藏层数较少 (4) 时往往优于 FNN,但在隐藏层数较多 (8+) 时,性能变得相同。有人能想到更好的模拟吗?在这种模拟中,RNN 有望超越具有相似数据结构的 FNN?
from keras import models
from keras import layers
from keras.layers import Dense, LSTM
import numpy as np
import matplotlib.pyplot as plt
Run Code Online (Sandbox Code Playgroud)
下面的代码模拟 10,000 个实例、10 个时间步长和 2 个变量的数据。如果第二个变量在第一个时间步长为 0,则 Y 为最后一个时间步长的第一个变量的值乘以 3。如果第二个变量在第一个时间步长为 1,则 Y 为最后一个时间步的第一个变量的值乘以 9。
我希望 RNN 将第一个时间步长的第二个变量的值保留在内存中,并使用它来知道最后一个时间步长的第一个变量乘以哪个值(3 或 9)。
## Simulate data.
instances = 10000
sequences = 10
X = np.zeros((instances, sequences * 2))
X[:int(instances / 2), 1] = 1
for i in range(instances):
for j in range(0, sequences * 2, 2):
X[i, j] = np.random.random()
Y = np.zeros((instances, 1))
for i in range(len(Y)):
if X[i, 1] == 0:
Y[i] = X[i, -2] * 3
if X[i, 1] == 1:
Y[i] = X[i, -2] * 9
Run Code Online (Sandbox Code Playgroud)
下面是 FNN 的代码:
## Densely connected model.
# Define model.
network_dense = models.Sequential()
network_dense.add(layers.Dense(4, activation = 'relu',
input_shape = (X.shape[1],)))
network_dense.add(Dense(1, activation = None))
# Compile model.
network_dense.compile(optimizer = 'rmsprop', loss = 'mean_absolute_error')
# Fit model.
history_dense = network_dense.fit(X, Y, epochs = 100, batch_size = 256, verbose = False)
plt.scatter(Y[X[:, 1] == 0, :], network_dense.predict(X[X[:, 1] == 0, :]), alpha = 0.1)
plt.plot([0, 3], [0, 3], color = 'black', linewidth = 2)
plt.title('FNN, Second Variable has a 0 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
plt.scatter(Y[X[:, 1] == 1, :], network_dense.predict(X[X[:, 1] == 1, :]), alpha = 0.1)
plt.plot([0, 9], [0, 9], color = 'black', linewidth = 2)
plt.title('FNN, Second Variable has a 1 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
Run Code Online (Sandbox Code Playgroud)
下面是 LSTM 的代码:
## Structure X data for LSTM.
X_lstm = X.reshape(X.shape[0], X.shape[1] // 2, 2)
X_lstm.shape
## LSTM model.
# Define model.
network_lstm = models.Sequential()
network_lstm.add(layers.LSTM(4, activation = 'relu',
input_shape = (X_lstm.shape[1], 2)))
network_lstm.add(layers.Dense(1, activation = None))
# Compile model.
network_lstm.compile(optimizer = 'rmsprop', loss = 'mean_squared_error')
# Fit model.
history_lstm = network_lstm.fit(X_lstm, Y, epochs = 100, batch_size = 256, verbose = False)
plt.scatter(Y[X[:, 1] == 0, :], network_lstm.predict(X_lstm[X[:, 1] == 0, :]), alpha = 0.1)
plt.plot([0, 3], [0, 3], color = 'black', linewidth = 2)
plt.title('LSTM, FNN, Second Variable has a 0 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
plt.scatter(Y[X[:, 1] == 1, :], network_lstm.predict(X_lstm[X[:, 1] == 1, :]), alpha = 0.1)
plt.plot([0, 9], [0, 9], color = 'black', linewidth = 2)
plt.title('LSTM, FNN, Second Variable has a 1 in the Very First Time Step')
plt.xlabel('Actual')
plt.ylabel('Predicted')
plt.show()
Run Code Online (Sandbox Code Playgroud)
是的,使用的代码对于您正在尝试执行的操作是正确的。10 年是用于预测下一年的时间窗口,因此这应该是模型中 20 个变量中每个变量的输入数量。100,000 个观测值的样本量与模型的输入形状无关。
您最初塑造因变量 Y 的方式是正确的。您预测 1 个变量的窗口期为 1 年,并且您有 100,000 个观测值。关键字参数return_sequences=True
将导致抛出错误,因为您只有一个 LSTM 层。True
如果要实现多个 LSTM 层并且相关层后面跟着另一个 LSTM 层,请将此参数设置为。
我希望我能为 3 提供一些指导,但在没有实际数据集的情况下,我不知道是否可以肯定地回答这个问题。
我想说的是,LSTM 的设计目的是解决常规 RNN 中存在的长期依赖问题。这个问题归结为,随着观察到相关信息的时间与该信息有用的时间之间的差距越来越大,标准 RNN 将更难学习它们之间的关系。考虑根据 3 天的活动与全年的活动来预测股票价格。
这就引出了第四点。如果我宽松地使用“类似”这个术语,并将时间窗口进一步拉长,比如 50 年而不是 10 年,那么使用 LSTM 获得的优势将变得更加明显。尽管我确信更有经验的人能够提供更好的答案,并且我期待看到它。
我发现此页面有助于理解 LSTM:
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
归档时间: |
|
查看次数: |
3220 次 |
最近记录: |