2017-04-22 27 views
0

我正在尝试在Keras的时间序列数据上训练ANN。我有三个数据向量被分解为滚动窗口序列(即向量l)。神经网络为所有输入产生类似的模式

np.array([l[i:i+window_size] for i in range(len(l) - window_size)]) 

靶载体类似地加窗,从而神经网络输出的时间的步骤的下一个数WINDOW_SIZE目标矢量的预测。所有数据都使用min-max缩放器进行标准化。它以形状=(nb_samples,window_size,3)形式输入神经网络。这里是3个输入向量的图。

input vector plots

我已经成功从ANN鼓起的唯一输出如下情节。蓝色目标矢量,红色预测(绘图放大,使预测模式更清晰)。预测向量以window_size间隔绘制,因此每个重复模式都是来自网络的一个预测。 enter image description here

我已经尝试了许多不同的模型架构,数量的时代,激活功能,短而胖的网络,瘦,高。这是我目前的(这里有一点)。

Conv1D(64,4, input_shape=(None,3)) -> 
Conv1d(32,4) -> 
Dropout(24) -> 
LSTM(32) -> 
Dense(window_size) 

但是我尝试的任何东西都不会影响输出这种重复模式的神经网络。我必须误解Keras的时间序列或LSTM。但是我现在非常失落,所以任何帮助都非常感谢。我已将完整的代码附加到此存储库。

https://github.com/jaybutera/dat-toy

回答

1

我打你的代码一点点,我觉得我有让你在正确的轨道上提供了一些建议。该代码似乎并不完全符合您的图形,但我认为自那时起你已经调整了一下。无论如何,有两个主要问题:

  1. 最大的问题是在您的数据准备步骤。你基本上有数据形状倒退,因为你有一个X的输入时间步和Y的时间序列。当你真正想要的是(18830,30,8)时,你的输入形状是(18830,1,8)这样完整的30步时间被送入LSTM。否则,LSTM只能在一个时间步上运行,并不是很有用。为了解决这个问题,我改了行中common.py

    X = X.reshape(X.shape[0], 1, X.shape[1])

    X = windowfy(X, winsize)

    同样,输出数据可能应该只值1,从我收集的您来自绘图功能的目标。肯定有一些情况下,你想预测整个时间序列,但我不知道这是否是你想要的这种情况。我将Y_train更改为使用fuels而不是fuels_w,因此它只需预测时间序列的一个步骤。

  2. 对于这个简单的网络体系结构,100个时期的培训可能太多了。在某些情况下,当我运行它时,看起来有些过度配合正在进行。观察网络中损失的减少,似乎只需要3-4个时期。

下面是我提到的调整3个训练时期后的预测图。这不是一个很好的预测,但现在看起来至少在正确的轨道上。祝你好运! Predictions after three epochs

编辑:实施例预测多输出时间步:

from sklearn import datasets, preprocessing 
import numpy as np 
from scipy import stats 
from keras import models, layers 

INPUT_WINDOW = 10 
OUTPUT_WINDOW = 5 # Predict 5 steps of the output variable. 
# Randomly generate some regression data (not true sequential data; samples are independent). 
np.random.seed(11798) 
X, y = datasets.make_regression(n_samples=1000, n_features=4, noise=.1) 
# Rescale 0-1 and convert into windowed sequences. 
X = preprocessing.MinMaxScaler().fit_transform(X) 
y = preprocessing.MinMaxScaler().fit_transform(y.reshape(-1, 1)) 
X = np.array([X[i:i + INPUT_WINDOW] for i in range(len(X) - INPUT_WINDOW)]) 
y = np.array([y[i:i + OUTPUT_WINDOW] for i in range(INPUT_WINDOW - OUTPUT_WINDOW, 
                len(y) - OUTPUT_WINDOW)]) 
print(np.shape(X)) # (990, 10, 4) - Ten timesteps of four features 
print(np.shape(y)) # (990, 5, 1) - Five timesteps of one features 

# Construct a simple model predicting output sequences. 
m = models.Sequential() 
m.add(layers.LSTM(20, activation='relu', return_sequences=True, input_shape=(INPUT_WINDOW, 4))) 
m.add(layers.LSTM(20, activation='relu')) 
m.add(layers.RepeatVector(OUTPUT_WINDOW)) 
m.add(layers.LSTM(20, activation='relu', return_sequences=True)) 
m.add(layers.wrappers.TimeDistributed(layers.Dense(1, activation='sigmoid'))) 
print(m.summary()) 

m.compile(optimizer='adam', loss='mse') 
m.fit(X[:800], y[:800], batch_size=10, epochs=60) # Train on first 800 sequences. 
preds = m.predict(X[800:], batch_size=10) # Predict the remaining sequences. 
print('Prediction:\n' + str(preds[0])) 
print('Actual:\n' + str(y[800])) 
# Correlation should be around r = .98, essentially perfect. 
print('Correlation: ' + str(stats.pearsonr(y[800:].flatten(), preds.flatten())[0])) 
+0

感谢您的响应。自从我提出这个问题以来,我一直在编辑代码,这是一个错误。事情是我想要预测未来一个多步的时间。当我问这个问题的时候,输入的形状是(18830,30,8),正如你所描述的那样,但是输出是无意义的。是否有另一种预测未来一个以上时间步骤的方法? – jay

+0

@jay我不太熟悉序列预测,但我添加了一个简单的例子,试图预测一些短序列。随机生成的数据不是真正的序列,因此没有可以学习的模式,所以输出并不意味着很多,但是可以看到一些结果。 – Nigel

+0

@jay实际上,我稍微改进了这个例子,它现在确实学到了一些东西,尽管数据仍然不是真正的顺序,所以前5个输入时间步可能实际上并不能帮助模型学习关于最后5个输出时间步的任何事情。也不是说,如果你的输入和输出序列的长度相同,你不需要'RepeatVector'业务,并且可以在整个模型中保持顺序。 – Nigel