我正在尝试用长字符序列标记字母。数据的固有结构要求我使用双向方法。
此外,基于on this idea我需要在每个时间步进入隐藏状态,而不仅仅是最后一个。
为了尝试这个想法,我采用了固定长度的方法。我目前在我的更长的序列中使用每批60个字符的随机片段,并运行我的手工双向分类器,zero_state
为每个60个字母的initial_state
。
这很好,但显然并不完美,因为实际上序列较长,而且我从原始源中随机剪切的部分左右信息丢失。
现在为了推进我想要使用整个序列。它们的长度差异很大,我无法将整个序列(进一步批量)放到GPU上。
我在dynamic_rnn documentation中找到了swap_memory - 参数。那会有帮助吗?
我没有找到任何有助于我理解的文档。而且我不能轻易地自己尝试这个,因为我需要在每个时间步都访问隐藏状态,因此我编写了当前图形而不使用任何更高级别的包装器(例如dynamic_rnn)。尝试这一点需要我从包装器中获取所有中间状态,据我所知,这是很多工作要实现的。
在经历尝试这个问题的麻烦之前,我很想确定这确实会解决我的记忆问题。 Thx任何提示!
答案 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)