我正在尝试以长字符序列标记字母。数据的固有结构要求我使用双向方法。
此外,基于on this idea,我需要在每个时间步访问隐藏状态,而不仅仅是最后一个。
为了尝试这个想法,我使用了固定长度的方法。目前,我在更长的序列中使用了随机的,说60个字符的批处理,并运行了我的手工双向分类器,zero_state
是每60个字母的initial_state
。
这种方法效果很好,但显然不是完美的,因为实际上序列更长,而且我从原始来源中随机剪切的片段中的左右信息也丢失了。
现在,为了前进,我想处理整个序列。但是,它们的长度差异很大,而且我无法将整个序列(进一步批处理)安装到GPU上。
我在dynamic_rnn documentation中找到了swap_memory-参数。那会帮助吗?
我没有找到任何其他文档可以帮助我理解。而且我自己也无法真正轻松地进行尝试,因为我需要在每个时间步访问隐藏状态,因此我在不使用任何更高级别的包装器(例如dynamic_rnn)的情况下对当前图形进行了编码。尝试此操作将需要我从包装器中取出所有中间状态,据我所知,这是要执行的大量工作。
在尝试进行此操作之前,我想确保这确实可以解决我的内存问题。感谢任何提示!
最佳答案
TL; DR: swap_memory
不允许您使用伪无限序列,但是它将帮助您将更大(更长或更宽,或者更大批量)的序列放入内存中。伪无限序列有一个单独的技巧,但仅适用于单向RNN。
swap_memory
在训练期间,NN(包括RNN)通常需要在内存中保存一些激活信息-计算梯度需要它们。swap_memory
的作用是告诉RNN将它们存储在主机(CPU)内存中,而不是在设备(GPU)内存中,并在需要时将它们流回GPU。
有效地,这可以让您假装您的GPU拥有比其实际更多的内存(以CPU内存为代价,这往往更丰富)
您仍然需要支付使用非常长的序列的计算成本。更不用说您可能会用完主机内存。
要使用它,只需为该参数赋予True
值即可。
sequence_length
如果序列长度不同,请使用此参数。 sequence_length
的名称具有误导性-实际上是序列长度为或的数组。
如果所有序列都具有相同的长度(max_time
参数),则仍然需要与所需的内存一样多的内存
tf.nn.bidirectional_dynamic_rnn
TF包括双向RNN的现成实现,因此使用此RNN而不是自己的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?
关于tensorflow - dynamic_rnn中的swap_memory允许准无限序列吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44049192/