【问题标题】:Non-linear multivariate time-series response prediction using RNN使用 RNN 进行非线性多元时间序列响应预测
【发布时间】:2018-02-22 13:59:16
【问题描述】:

考虑到内部和外部气候,我正在尝试预测墙壁的湿热响应。根据文献研究,我认为使用 RNN 应该可以做到这一点,但我无法获得良好的准确性。

数据集有 12 个输入特征(外部和内部气候数据的时间序列)和 10 个输出特征(湿热响应的时间序列),均包含 10 年的每小时值。该数据是使用湿热模拟软件创建的,没有丢失数据。

数据集特征:

数据集目标:

与大多数时间序列预测问题不同,我想预测每个时间步长输入特征时间序列的响应,而不是时间序列的后续值(例如金融时间序列预言)。我还没有找到类似的预测问题(在类似或其他领域),所以如果你知道一个,非常欢迎参考。


我认为 RNN 应该可以做到这一点,所以我目前正在使用 Keras 的 LSTM。在训练之前,我通过以下方式预处理我的数据:

  1. 丢弃第一年的数据,因为墙的湿热响应的第一个时间步长受初始温度和相对湿度的影响。
  2. 分成训练集和测试集。训练集包含前 8 年的数据,测试集包含剩下的 2 年。
  3. 使用来自 Sklearn 的 StandardScaler 标准化训练集(零均值,单位方差)。使用训练集的均值方差类似地对测试集进行归一化。

这会导致:X_train.shape = (1, 61320, 12)y_train.shape = (1, 61320, 10)X_test.shape = (1, 17520, 12)y_test.shape = (1, 17520, 10)

由于这些是长时间序列,我使用有状态 LSTM 并使用 stateful_cut() 函数按照 here 的说明切割时间序列。我只有 1 个样本,所以 batch_size 是 1。对于 T_after_cut,我尝试了 24 和 120 (24*5); 24 似乎给出了更好的结果。这导致X_train.shape = (2555, 24, 12)y_train.shape = (2555, 24, 10)X_test.shape = (730, 24, 12)y_test.shape = (730, 24, 10)

接下来,我构建并训练 LSTM 模型如下:

model = Sequential()
model.add(LSTM(128, 
               batch_input_shape=(batch_size,T_after_cut,features), 
               return_sequences=True,
               stateful=True,
               ))
model.addTimeDistributed(Dense(targets)))
model.compile(loss='mean_squared_error', optimizer=Adam())

model.fit(X_train, y_train, epochs=100, batch_size=batch=batch_size, verbose=2, shuffle=False)

很遗憾,我没有得到准确的预测结果;甚至对于训练集也没有,因此该模型具有很高的偏差。

The prediction results of the LSTM model for all targets


如何改进我的模型?我已经尝试了以下方法:

  1. 不丢弃数据集的第一年 -> 没有显着差异
  2. 区分输入特征的时间序列(从当前值中减去以前的值)-> 结果稍差
  3. 最多四个堆叠的 LSTM 层,都具有相同的超参数 -> 结果没有显着差异,但训练时间更长
  4. LSTM 层之后的 Dropout 层(尽管这通常用于减少方差并且我的模型具有较高的偏差)-> 结果略好,但差异可能没有统计学意义

我对有状态 LSTM 做错了吗?我需要尝试不同的 RNN 模型吗?我应该以不同的方式预处理数据吗?

此外,训练非常慢:上面的模型大约需要 4 个小时。因此我不愿意做一个广泛的超参数网格搜索......

【问题讨论】:

    标签: machine-learning time-series lstm prediction recurrent-neural-network


    【解决方案1】:

    最后,我设法通过以下方式解决了这个问题:

    • 使用更多样本进行训练,而不是仅使用 1 个(我使用 18 个样本进行训练,6 个样本进行测试)
    • 保留第一年的数据,因为所有样本的输出时间序列具有相同的“起点”,模型需要这些信息来学习
    • 标准化输入和输出特征(零均值,单位方差)。我发现这提高了预测准确性和训练速度
    • here 所述使用有状态 LSTM,但在 epoch 之后添加重置状态(代码见下文)。我使用了batch_size = 6T_after_cut = 1460。如果T_after_cut更长,训练更慢;如果T_after_cut 更短,准确度会略有下降。如果有更多样本可用,我认为使用更大的batch_size 会更快。
    • 使用 CuDNNLSTM 代替 LSTM,这样可以加快训练时间 x4!
    • 我发现更多的单元会导致更高的准确度和更快的收敛(更短的训练时间)。我还发现,对于相同数量的单元,GRU 与 LSTM 坚韧的收敛速度一样准确。
    • 在训练期间监控验证损失并使用提前停止

    LSTM 模型的构建和训练如下:

    def define_reset_states_batch(nb_cuts):
      class ResetStatesCallback(Callback):
        def __init__(self):
          self.counter = 0
    
        def on_batch_begin(self, batch, logs={}):
        # reset states when nb_cuts batches are completed
          if self.counter % nb_cuts == 0:
            self.model.reset_states()
          self.counter += 1
    
        def on_epoch_end(self, epoch, logs={}):
        # reset states after each epoch
          self.model.reset_states()
          return(ResetStatesCallback)    
    
    model = Sequential()
    model.add(layers.CuDNNLSTM(256, batch_input_shape=(batch_size,T_after_cut ,features),
      return_sequences=True,
      stateful=True))
    model.add(layers.TimeDistributed(layers.Dense(targets, activation='linear')))
    
    optimizer = RMSprop(lr=0.002)
    model.compile(loss='mean_squared_error', optimizer=optimizer)
    
    earlyStopping = EarlyStopping(monitor='val_loss', min_delta=0.005, patience=15, verbose=1, mode='auto')
    ResetStatesCallback = define_reset_states_batch(nb_cuts)
    model.fit(X_dev, y_dev, epochs=n_epochs, batch_size=n_batch, verbose=1, shuffle=False, validation_data=(X_eval,y_eval), callbacks=[ResetStatesCallback(), earlyStopping])
    

    这给了我非常令人满意的准确度(R2 超过 0.98): 该图显示了 2 年内墙壁的温度(左)和相对湿度(右)(训练中未使用的数据),红色为预测,黑色为真实输出。残差表明误差非常小,并且 LSTM 学会了捕捉长期依赖关系来预测相对湿度。

    【讨论】:

    • 我不是在尝试预测,而是尝试根据输入序列预测响应序列。输入和输出序列是同时的。 y[t1] 是 X[t1] 上的响应,而 y[t1] 对预测 X[t2] 上的响应 y[t2] 很重要,依此类推。因此,基于输入序列,我可以预测整个输出序列。
    猜你喜欢
    • 2018-12-23
    • 2016-06-27
    • 2023-04-08
    • 2017-05-16
    • 1970-01-01
    • 2018-01-05
    • 2021-10-17
    • 2018-06-18
    • 2020-11-14
    相关资源
    最近更新 更多