dynamic_rnn中的swap_memory允许准无限序列?

时间:2017-05-18 13:31:00

标签: tensorflow lstm recurrent-neural-network

我正在尝试用长字符序列标记字母。数据的固有结构要求我使用双向方法。

此外,基于on this idea我需要在每个时间步进入隐藏状态,而不仅仅是最后一个。

为了尝试这个想法,我采用了固定长度的方法。我目前在我的更长的序列中使用每批60个字符的随机片段,并运行我的手工双向分类器,zero_state为每个60个字母的initial_state

这很好,但显然并不完美,因为实际上序列较长,而且我从原始源中随机剪切的部分左右信息丢失。

现在为了推进我想要使用整个序列。它们的长度差异很大,我无法将整个序列(进一步批量)放到GPU上。

我在dynamic_rnn documentation中找到了swap_memory - 参数。那会有帮助吗?

我没有找到任何有助于我理解的文档。而且我不能轻易地自己尝试这个,因为我需要在每个时间步都访问隐藏状态,因此我编写了当前图形而不使用任何更高级别的包装器(例如dynamic_rnn)。尝试这一点需要我从包装器中获取所有中间状态,据我所知,这是很多工作要实现的。

在经历尝试这个问题的麻烦之前,我很想确定这确实会解决我的记忆问题。 Thx任何提示!

1 个答案:

答案 0 :(得分:4)

TL; DR: swap_memory不允许您使用伪无限序列,但它可以帮助您适应更大(更长,更宽或更大批量)的序列在记忆中。伪无限序列有一个单独的技巧,但它只适用于单向RNN。

<强> swap_memory

在训练期间,NN(包括RNN)通常需要在内存中保存一些激活 - 它们是计算梯度所必需的。

swap_memory的作用是告诉您的RNN将它们存储在主机(CPU)内存而不是设备(GPU)内存中,并在需要时将它们传回GPU。

实际上,这可以让你假装你的GPU拥有比实际更多的内存(以CPU内存为代价,而内存往往更丰富)

您仍需支付使用超长序列的计算成本。更不用说你可能会耗尽主机内存。

要使用它,只需为该参数赋值True

<强> sequence_length

如果序列长度不同,请使用此参数。 sequence_length有一个误导性的名称 - 它实际上是序列长度 s 的数组。

如果所有序列长度相同(max_time参数)

,您仍然需要尽可能多的内存。

<强> tf.nn.bidirectional_dynamic_rnn

TF包括双向RNN的现成实现,因此使用它可能更容易,而不是自己的。

有状态的RNN

为了在训练单向 RNN时处理非常长的序列,人们会其他:它们会保存每批的最终隐藏状态,并将它们用作下一批次的初始隐藏状态(为此,下一批必须由前一批次序列的延续组成)

这些主题讨论如何在TF中完成这项工作:

TensorFlow: Remember LSTM state for next batch (stateful LSTM)

How do I set TensorFlow RNN state when state_is_tuple=True?