【发布时间】:2019-01-29 06:02:38
【问题描述】:
我一直在阅读有关 Keras RNN 模型(LSTM 和 GRU)的文章,作者似乎主要关注语言数据或使用由先前时间步长组成的训练实例的单变量时间序列。我的数据有点不同。
我有 20 个变量在 10 年内每年测量 100,000 人作为输入数据,并将第 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)
我有四个(相关)问题,请:
我是否为我拥有的数据结构正确编码了 Keras 模型?我从全连接网络(使用扁平数据)和 LSTM、GRU 和 1D CNN 模型获得的性能几乎相同,我不知道我是否在 Keras 中犯了错误,或者循环模型是否只是简单的在这种情况下没有帮助。
我是否应该将 Y 作为一个形状为
Y.shape = [persons, years] = [100000, 11]的系列,而不是在 X 中包含变量,然后它的形状为X.shape = [persons, years, variables] = [100000, 10, 19]?如果是这样,我怎样才能让 RNN 输出预测的序列?当我使用return_sequences = True时,Keras 返回错误。这是使用我拥有的数据进行预测的最佳方式吗? Keras RNN 模型甚至其他模型中是否有更好的选项可供选择?
如何模拟类似于我拥有的数据结构的数据,以使 RNN 模型的性能优于全连接网络?
更新:
我尝试了一个模拟,我希望这是一个非常简单的案例,RNN 应该有望胜过 FNN。
虽然当 LSTM 的隐藏层较少 (4) 时,LSTM 的性能往往优于 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
下面的代码模拟了 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
下面是 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()
下面是 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()
【问题讨论】:
标签: python keras time-series recurrent-neural-network