使用 Tensorflow 进行 LSTM 单步预测
Posted
技术标签:
【中文标题】使用 Tensorflow 进行 LSTM 单步预测【英文标题】:LSTM one-step-ahead prediction with Tensorflow 【发布时间】:2017-09-14 14:16:42 【问题描述】:我正在使用 Tensorflow 的 GRUCell
+ MultiRNNCell
+ dynamic_rnn
组合来生成多层 LSTM 来预测一系列元素。
在我见过的几个例子中,比如字符级语言模型,一旦训练阶段完成,生成似乎是通过一次只输入一个“字符”(或任何元素)来获得下一个预测,然后根据第一个预测得到下面的“字符”,等等。
我的问题是,由于 Tensorflow 的 dynamic_rnn
将 RNN 图展开为任意数量的步骤,无论序列长度如何,一旦预测逐渐出现,一次只输入一个元素有什么好处?建成?通过每个预测步骤逐渐收集更长的序列并将其重新输入到图表中不是更有意义吗? IE。在生成第一个预测后,反馈一个由 2 个元素组成的序列,然后是 3 个,等等?
我目前正在尝试预测阶段,首先输入 15 个元素(实际历史数据)的序列,获取预测的最后一个元素,然后用该预测值替换原始输入中的一个元素,等等在 N 个预测步骤的循环中。
与一次只输入一个元素相比,这种方法的缺点是什么?
【问题讨论】:
【参考方案1】:我不确定你的方法实际上是在做你想做的事。
假设我们有一个经过训练可以生成字母表的 LSTM 网络。现在,为了让网络生成一个序列,我们从一个干净的状态 h0
开始,并输入第一个字符 a
。网络输出一个新状态h1
,以及它的预测b
,我们将其附加到我们的输出中。接下来,我们希望网络根据当前输出预测下一个字符ab
。如果我们在这一步将状态为h1
的网络提供给ab
,它的感知序列将是aab
,因为h1
是在第一个a
之后计算的,现在我们放入另一个@987654331 @ 和 b
。或者,我们可以将ab
和干净状态h0
输入网络,这将提供正确的输出(基于ab
),但是我们将对除b
之外的整个序列执行不必要的计算,因为我们已经计算了状态h1
,它对应于读取序列a
的网络,所以为了得到下一个预测和状态,我们只需要输入下一个字符b
。
所以要回答你的问题,一次给网络输入一个字符是有意义的,因为网络只需要看到每个字符一次,而多次输入同一个字符只是不必要的计算。
【讨论】:
感谢反馈,有道理!在这种情况下,您认为在网络开始生成预测输出之前“预热”网络的最佳方式是什么。如果我有一些“实际”观察的数据点,那么通过这些观察首先以某种方式预热状态是否有意义? 绝对是的。我不会将此称为“预热”网络,而是基于起始序列而不是起始字符生成文本,这基本上是一个 seq2seq 模型。我见过的一个例子是从函数签名生成函数代码 - 首先输入签名的各个字符,然后一次生成一个字符的代码。 所以你的意思是,如果你有一个 15 个元素的起始序列,那么你一次输入所有 15 个元素以生成第 16 个元素作为第一个预测,然后从那个预测中继续一个一次元素并重用 15 长序列的原始通道中的状态?还是先一个一个地遍历这 15 个元素?我想这应该不重要吧? 是的,没关系,是的,您首先输入 15 个元素,获取输出状态和预测,然后从那里一个接一个地进行。【参考方案2】:这是一个很好的问题,我问了一些非常相似的here。
这个想法不是跨时间共享权重(正如您所描述的那样,一次一个元素),每个时间步骤都有自己的一组权重。
我认为一次训练一步有几个原因,主要是计算复杂度和训练难度。每个时间步,您需要训练的权重数量呈线性增长。你需要一些非常运动的硬件来训练长序列。同样对于长序列,您需要一个 非常 大的数据集来训练所有这些权重。但是恕我直言,我仍然乐观地认为,对于正确的问题,如果有足够的资源,它会有所改善。
【讨论】:
谢谢,我会看看你的其他问题。澄清一下:我说的是在一次训练一个训练之后生成,而不是按顺序训练。 (即测试已经训练好的模型)。就训练本身而言,我在长序列中进行,移动 1 以生成 Y。你是对的,很多硬件要求,但这些天在云中似乎是可行的......以上是关于使用 Tensorflow 进行 LSTM 单步预测的主要内容,如果未能解决你的问题,请参考以下文章
Tensorflow - Tutorial : 利用 RNN/LSTM 进行手写数字识别
具有 LSTM 网络的连体模型无法使用 tensorflow 进行训练
在 TensorFlow 中使用多对多 LSTM 进行视频分类
Tensorflow - Tutorial : 利用 RNN/LSTM 进行手写数字识别