Tensorflow 中使用 LSTM 的时间序列预测模型预测一个常数
Time Series Forecasting model with LSTM in Tensorflow predicts a constant
我正在使用卫星数据构建飓风路径预测器。我在多层 LSTM 模型中有多个输出,输入和输出数组遵循结构 [samples[time[features]]]。作为输入和输出的特征,我有飓风、WS 和其他维度的坐标。
问题是错误减少,因此,模型预测总是一个常数。阅读了几篇文章后,我对数据进行了标准化,删除了一些不必要的层,但模型始终预测相同的输出。
我认为模型足够大,激活函数有意义,因为输出都在 [-1;1] 范围内。
所以我的问题是:我做错了什么?
模型如下:
class Stacked_LSTM():
def __init__(self, training_inputs, training_outputs, n_steps_in, n_steps_out, n_features_in, n_features_out, metrics, optimizer, epochs):
self.training_inputs = training_inputs
self.training_outputs = training_outputs
self.epochs = epochs
self.n_steps_in = n_steps_in
self.n_steps_out = n_steps_out
self.n_features_in = n_features_in
self.n_features_out = n_features_out
self.metrics = metrics
self.optimizer = optimizer
self.stop = EarlyStopping(monitor='loss', min_delta=0.000000000001, patience=30)
self.model = Sequential()
self.model.add(LSTM(360, activation='tanh', return_sequences=True, input_shape=(self.n_steps_in, self.n_features_in,))) #, kernel_regularizer=regularizers.l2(0.001), not a good idea
self.model.add(layers.Dropout(0.1))
self.model.add(LSTM(360, activation='tanh'))
self.model.add(layers.Dropout(0.1))
self.model.add(Dense(self.n_features_out*self.n_steps_out))
self.model.add(Reshape((self.n_steps_out, self.n_features_out)))
self.model.compile(optimizer=self.optimizer, loss='mae', metrics=[metrics])
def fit(self):
return self.model.fit(self.training_inputs, self.training_outputs, callbacks=[self.stop], epochs=self.epochs)
def predict(self, input):
return self.model.predict(input)
备注
1)在这个特定的问题中,时间序列数据不是"continuous",因为一个时间序列属于特定的飓风。因此,我针对每场飓风调整了时间序列的训练和测试样本。这意味着我不能在我的层中使用函数 stateful=True
,因为这意味着模型不会在不同的飓风之间产生任何差异(如果我的理解是正确的)。
2) 没有图像数据,因此不需要卷积模型。
几点建议,根据我的经验:
4层LSTM太多了。坚持两个,最多三个。
不要使用 relu
作为 LSTM 的激活。
不要将 BatchNormalization
用于时间序列。
除此之外,我还建议移除两个 LSTM 层之间的密集层。
我正在使用卫星数据构建飓风路径预测器。我在多层 LSTM 模型中有多个输出,输入和输出数组遵循结构 [samples[time[features]]]。作为输入和输出的特征,我有飓风、WS 和其他维度的坐标。
问题是错误减少,因此,模型预测总是一个常数。阅读了几篇文章后,我对数据进行了标准化,删除了一些不必要的层,但模型始终预测相同的输出。
我认为模型足够大,激活函数有意义,因为输出都在 [-1;1] 范围内。 所以我的问题是:我做错了什么?
模型如下:
class Stacked_LSTM():
def __init__(self, training_inputs, training_outputs, n_steps_in, n_steps_out, n_features_in, n_features_out, metrics, optimizer, epochs):
self.training_inputs = training_inputs
self.training_outputs = training_outputs
self.epochs = epochs
self.n_steps_in = n_steps_in
self.n_steps_out = n_steps_out
self.n_features_in = n_features_in
self.n_features_out = n_features_out
self.metrics = metrics
self.optimizer = optimizer
self.stop = EarlyStopping(monitor='loss', min_delta=0.000000000001, patience=30)
self.model = Sequential()
self.model.add(LSTM(360, activation='tanh', return_sequences=True, input_shape=(self.n_steps_in, self.n_features_in,))) #, kernel_regularizer=regularizers.l2(0.001), not a good idea
self.model.add(layers.Dropout(0.1))
self.model.add(LSTM(360, activation='tanh'))
self.model.add(layers.Dropout(0.1))
self.model.add(Dense(self.n_features_out*self.n_steps_out))
self.model.add(Reshape((self.n_steps_out, self.n_features_out)))
self.model.compile(optimizer=self.optimizer, loss='mae', metrics=[metrics])
def fit(self):
return self.model.fit(self.training_inputs, self.training_outputs, callbacks=[self.stop], epochs=self.epochs)
def predict(self, input):
return self.model.predict(input)
备注
1)在这个特定的问题中,时间序列数据不是"continuous",因为一个时间序列属于特定的飓风。因此,我针对每场飓风调整了时间序列的训练和测试样本。这意味着我不能在我的层中使用函数 stateful=True
,因为这意味着模型不会在不同的飓风之间产生任何差异(如果我的理解是正确的)。
2) 没有图像数据,因此不需要卷积模型。
几点建议,根据我的经验:
4层LSTM太多了。坚持两个,最多三个。
不要使用
relu
作为 LSTM 的激活。不要将
BatchNormalization
用于时间序列。
除此之外,我还建议移除两个 LSTM 层之间的密集层。