Keras LSTM模式中Y特征的初值

3qpi33ja  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(130)

我正在尝试使用Functional API在Keras中训练一个ConvLSTM 2D模型,有一点我很困惑,我已经阅读了一整天了,我不确定我是否真的理解我在做什么,简单来说,我认为我不需要使用有状态模型,但我在尝试找出如何让模型考虑到初始值(在t0处)目标特征(Y),然后预测序列的其余部分的目标值(在t1处到任何时候)。
这个任务有点像预测降雨:在时间t在位置x、y处降雨量是各种不同特征的乘积(比如风速,海拔等),当然还有前期的降水量,因为如果已经下雨了,就更有可能继续下雨,因为现在的天气状况应该可以帮助我们预测未来的天气,目标值偏移(或滞后)一个时间步长,因此t0处的x预测t1处的y。
我从另一个团队那里继承了一些代码,他们和我一样无知,但对自己的能力更有信心。(具体来说,是他们编写数据生成器的方式)是他们对X和Y数组使用相同的特征向量(对Y阵列应用移位),不幸的结果是他们预测了所有的特征,而不仅仅是感兴趣的那一个。模型定义和训练代码看起来像这样:

inputs = layers.Input(shape = (sequence_length, x_grid_length, y_grid_length, num_features))
outputs = layers.ConvLSTM2D(filters = 32,
                            kernel_size = (5,5),
                            padding = "same",
                            return_sequences = True,
                            stateful = False,
                            activation = "relu")(inputs)
outputs = layers.ConvLSTM2D(filters = 32,
                            kernel_size = (3,3),
                            padding = "same",
                            return_sequences = True,
                            stateful = False,
                            activation = "relu")(outputs)
outputs = layers.Conv3D(filters = 1,
                        kernel_size = (3, 3, 3),
                        padding = "same",
                        activation = "sigmoid")(outputs)
model = keras.models.Model(inputs = inputs, outputs = outputs)
loss = keras.losses.mean_squared_error
opt = keras.optimizers.Adam(learning_rate = 0.001)
model.compile(loss = loss, optimizer = opt)

history = model.fit(training_data,
                    epochs = 8,
                    verbose = 2,
                    validation_data = val_data)

这里,变量training_dataval_data是Keras Sequence的自定义子类的示例。我修改了sequence类,只返回目标值Y(即雨的量),并将“return_sequence”设置为True,同时仍然返回整个特性集,包括目标列,作为X。
在第一次尝试训练后,我意识到我有一个问题:如果我尝试从测试集进行预测,我会将降水量的正确值输入到预测中,当然最后一个时间步长除外--这有点违背了RNN的目的。这显然是不正确的,所以我修改了序列类,只提供X的非目标特征。但这也是不正确的,因为如果在序列开始时已经下雨了,这些信息没有进入模型。
阅读了很多之后,我认为我不需要有状态模型,因为我只关心t0时的目标值(我正在训练重叠的序列,从t0、t1、t2等开始,这不适合有状态模型,在有状态模型中,我希望使用一个序列的最后一个状态作为下一个序列的第一个状态)。我意识到即使使用无状态模型,我可以使用reset_state来指定初始状态--但是我想指定目标特性的初始值,而不是指定隐藏层的初始状态。

ttisahbt

ttisahbt1#

在进一步阅读和睡个好觉之后,我想我已经有了答案,不过我还不打算做标记,以防有人有更好的答案。正如我上面写的,这里真实的的问题是预测。实际上,这个问题甚至不影响模型训练,但我确实需要做一些额外的工作,才能使用模型预测未来的多个时间步。
对于模型训练来说,将目标值作为X数组中的一个特征和Y数组中的实际目标(当然,滞后/偏移了一个时间段)输入模型并没有什么错,这只是自回归(或类似的深度学习),统计学家几十年来一直在使用时间序列数据。
然而,预测是另一回事,因为我真正需要做的是预测未来的多个步骤。当前的模型定义和Sequence子类可以很好地预测未来的一个时间步骤--也就是说,当您的目标值落后一个时间步骤时会发生什么。进行多个步骤更棘手。
我确实有数据来预测多个时间步长:我有49个步骤的每个运行,出于训练目的,允许我为每个运行创建等于49减去序列长度的序列数(这允许提供目标的滞后值所需的额外步骤)。然后技巧是取得第一时间步骤的目标值的预测,然后将其反馈到X阵列中,使用它们代替原始数据作为未来步骤的目标值。这将需要修改我的Sequence子类,以包括一个将前一步的预测作为输入的预测模式,或者创建一个全新的子类,或者只是一个接一个地输入用于预测的序列(这比较慢,但这不是一个大的考虑因素,除非你想做很多预测)。
为这些多步预测生成损失统计数据可能也是一个好主意,因为Keras在训练过程中计算的损失仅用于一步预测;为此,我必须添加代码,将预测的目标值与原始数据中的目标值进行比较。
编辑:我还想到,我看不出有什么理由将最后一个ConvLSTM 2D层中的“return_sequences”设置为True--最初的团队,出于某种原因,试图预测整个序列,但我真的只需要每个序列的最终输出。

相关问题