我正在建立一个LSTM时间序列预测模型(在TF v = 1.13.1,Keras v = 2.2.4中),该模型采用间歇振荡的时域信号作为输入。每次振荡之间的时间呈指数分布(beta=5
),振荡具有正态分布长度(mean length=2sec
,variance=1sec
),每次振荡的频率也呈正态分布(mean frequency=22hz
,variance=3hz
) 。
我已经阅读了DanielMöller在Keras / TF上有关LSTM的几乎所有Stackoverflow优秀文章。我还为模型试验了不同数量的时间步长,有状态与无状态LSTM,不同的损耗函数(mean absolute error
与mean squared error
)以及不同的网络宽度/深度。该模型几乎总是捕获到某些事物在振荡,但是在顺序预测步骤中未能重新创建其断续的特征和正弦曲线形状。
最小可复制示例:
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# Import Data
data = np.loadtxt('./my_data.csv')
# Reshape data into batches of 500 timesteps - 1 dim per timestep
# For now, we do not split into testing/training sets
# Assume all data is for training
data_pre = data.reshape(-1, 500, 1)[:,:-1,:] # Shift input data backward by 1
data_post = data.reshape(-1, 500, 1)[:,1:,:] # Shift input data forward by 1
# Build LSTM Model for Training:
# Allow flexible number of timesteps per input (shape=(None,1))
inputs = tf.keras.layers.Input(shape=(None,1))
lstm_1 = tf.keras.layers.CuDNNLSTM(units=512, return_sequences=True)(inputs)
lstm_2 = tf.keras.layers.CuDNNLSTM(units=256, return_sequences=True)(lstm_1)
# Activate dense layer with linear activation func for regression
outputs = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(units=1, activation='linear'))(lstm_2)
lstm_model = tf.keras.Model(inputs=inputs, outputs=outputs)
lstm_model.compile('adam', loss='mae', metrics=['mae','mse'])
lstm_model.fit(x=data_pre, y = data_post, epochs=100, batch_size=16, shuffle=False) # I have trained up to 500 epochs and while the loss decreases there is no increase in prediction performance.
# Build Stateful LSTM Model for Sample-by-Sample Prediction
# Assume 1 timestep per input of dim=1
inputs = tf.keras.layers.Inputs(shape=(1,1,1))
lstm_1 = tf.keras.layers.CuDNNLSTM(units=512, return_sequences=True, stateful=True)(inputs)
lstm_2 = tf.keras.layers.CuDNNLSTM(units=256, return_sequences=True, stateful=True)(lstm_1)
outputs = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(units=1, activation='linear'))
prediction_model = tf.keras.Model(inputs=inputs, outputs=outputs)
# Copy weights from trained, non-stateful model:
prediction_model.set_weights(lstm_model.get_weights())
#Reset network state
prediction_model.reset_states()
#Initialize model internal state with a single sample from the input data shifted by 1 unit backwards
seed = prediction_model.predict(data_pre[0][0][None, None, :])
# Predict 20secs of data
output_array = np.zeros((10000,1,1)) # Allocate Memory
for i in range(0,10000):
temp = prediction_model.predict(seed) # Iteratively predict next sample value
output_array[i] = temp
seed = temp
原始数据图:
模型输出
最佳答案
您是否考虑过通过每一层提供多个输入?例如:
假设您要通过模型输入变量x
。重塑数据看起来像这样。
import numpy as np
look_back = 5 ## This is the number of points to include in each iteration
x = np.arange(0,100)
new_array = []
for num in range(0, len(x)-look_back):
new_array.append(x[num:num+look_back])
new_array = np.array(new_array)
print (np.array(x).shape) ## old array = (100,)
print (new_array.shape) ## new array = (95,5)
如果具有足够的历史背景,这可以帮助您的模型了解下一步的发展。基于振荡方差,我想说这是从您的网络中淘汰出来的,它只是简单地取平均值。