一直在阅读有关 LSTM 及其在时间序列中的使用的一些信息,这很有趣,但同时也很困难。我难以理解的一件事是向已经是时间序列特征列表的内容添加附加特征的方法。假设您的数据集如下所示:
t-3,t-2,t-1,输出
现在假设您知道您有一个确实会影响输出的功能,但它不一定是时间序列功能,可以说是外面的天气。这是你可以添加的东西,LSTM 将能够区分什么是时间序列方面,什么不是?
一直在阅读有关 LSTM 及其在时间序列中的使用的一些信息,这很有趣,但同时也很困难。我难以理解的一件事是向已经是时间序列特征列表的内容添加附加特征的方法。假设您的数据集如下所示:
t-3,t-2,t-1,输出
现在假设您知道您有一个确实会影响输出的功能,但它不一定是时间序列功能,可以说是外面的天气。这是你可以添加的东西,LSTM 将能够区分什么是时间序列方面,什么不是?
对于 RNN(例如 LSTM 和 GRU),层输入是一个时间步长列表,每个时间步长是一个特征张量。这意味着你可以有一个像这样的输入张量(用 Pythonic 表示法):
# Input tensor to RNN
[
# Timestep 1
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
# Timestep 2
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
# Timestep 3
[ temperature_in_paris, value_of_nasdaq, unemployment_rate ],
...
]
因此,绝对可以在每个时间步拥有多个特征。在我看来,天气是一个时间序列特征:我住的地方,它恰好是时间的函数。因此,将天气信息编码为每个时间步的特征之一是非常合理的(使用适当的编码,如 cloudy=0、sunny=1 等)。
但是,如果您有非时间序列数据,那么通过 LSTM 传递它实际上没有意义。也许 LSTM 无论如何都会起作用,但即使它起作用,它也可能会以每次训练时间更高的损失/更低的准确度为代价。
或者,您可以通过附加层将这种“额外”信息引入 LSTM 之外的模型中。您可能有这样的数据流:
TIME_SERIES_INPUT ------> LSTM -------\
*---> MERGE ---> [more processing]
AUXILIARY_INPUTS --> [do something] --/
因此,您可以将辅助输入合并到 LSTM 输出中,并从那里继续您的网络。现在您的模型只是多输入。
例如,假设在您的特定应用程序中,您只保留 LSTM 输出序列的最后一个输出。假设它是一个长度为 10 的向量。您的辅助输入可能是您的编码天气(所以是一个标量)。您的合并层可以简单地将辅助天气信息附加到 LSTM 输出向量的末尾以生成长度为 11 的单个向量。但您不需要只保留最后一个 LSTM 输出时间步:如果 LSTM 输出 100 个时间步,每个使用 10 个特征向量,您仍然可以添加辅助天气信息,从而产生 100 个时间步长,每个时间步长由一个包含 11 个数据点的向量组成。
Keras 关于其功能 API的文档对此进行了很好的概述。
在其他情况下,正如@horaceT 指出的那样,您可能希望将 LSTM 用于非时间数据。例如,在给定位置预测明天的天气。在这种情况下,这里有三个建议,每个都有正面/负面:
让第一个时间步包含您的条件数据,因为它将有效地“设置”您的 RNN 的内部/隐藏状态。坦率地说,我不会这样做,原因有很多:你的条件数据需要与你的其他特征具有相同的形状,这使得创建有状态的 RNN 变得更加困难(就非常小心地跟踪你如何提供数据而言进入网络),网络可能会在足够长的时间内“忘记”调节数据(例如,长训练序列或长预测序列)等。
将数据作为时态数据本身的一部分。因此,特定时间步长的每个特征向量都包含“大部分”时间序列数据,但随后将条件数据附加到每个特征向量的末尾。网络会学会识别这一点吗?可能,但即便如此,您通过使用非序列信息污染序列数据来创建更难的学习任务。所以我也会劝阻这一点。
可能最好的方法是在零时刻直接影响 RNN 的隐藏状态。这是Karpathy 和 Fei-Fei以及Vinyals 等人采用的方法。这是它的工作原理:
这种方法在“理论上”是最正确的,因为它可以根据您的非时间输入正确调节 RNN,自然地解决形状问题,并且还避免使用额外的非时间信息污染您的输入时间步长。缺点是这种方法通常需要对您的架构进行图级控制,因此如果您使用像 Keras 这样的更高级别的抽象,您会发现很难实现,除非您添加自己的层类型。
基于这个线程的所有好的答案,我编写了一个库来调节辅助输入。它抽象了所有复杂性,并被设计为尽可能用户友好:
https://github.com/philipperemy/cond_rnn/(张量流)
希望能帮助到你!
亚当的回答似乎最有意义,但是,我不确定第二个陈述“用非顺序信息污染顺序数据”。
所以最近我训练了一个字符级的 LSTM 模型,我只是在序列特征的末尾附加了一个非序列特征。该模型学会了如何很好地区分这一点。
如果我按照 Adam 的方式完成,模型是否会表现得更好,这个问题仍有待测试。但是对于那些不想加倍努力的人来说,将非序列特征附加到序列特征上就可以了。
keras LSTM 中有一个功能reset_states(states)
。
然而,参数状态是两个状态的串联,隐藏状态 h 和单元状态。
States = [h, c]
知道您是否应该初始化h
或c
根据上述论文中的方法会很有趣。