swap_memory in dynamic_rnn 允许准无限序列?
swap_memory in dynamic_rnn allows quasi-infinite sequences?
我正在尝试标记长字符序列中的字母。数据的固有结构要求我使用双向方法。
进一步基于on this idea我需要在每个时间步访问隐藏状态,而不仅仅是最后一个。
为了尝试这个想法,我使用了固定长度的方法。我目前使用的是我更长的序列中的每批 60 个字符的随机片段和 运行 我手工制作的双向分类器,其中 zero_state
是每个 60 个字母片段的 initial_state
。
这很好用,但显然不完美,因为实际上序列更长,我从原始来源随机剪切的片段的左右信息都丢失了。
现在为了推进我想处理整个序列。尽管它们的长度差异很大,但我无法将整个序列(进一步批处理)放入 GPU。
我在 dynamic_rnn documentation 中找到了 swap_memory - 参数。会有帮助吗?
我没有找到任何进一步的文档来帮助我理解。而且我自己真的不能轻易地尝试这个,因为我需要在每个时间步访问隐藏状态,因此我在不使用任何更高级别的包装器(例如 dynamic_rnn)的情况下对当前图形进行编码。尝试这个将需要我从包装器中获取所有中间状态,据我所知,这需要大量的工作来实现。
在经历这个麻烦之前,我很想确定这确实会解决我的记忆问题。感谢任何提示!
TL;DR: swap_memory
不会让你使用伪无限序列,但它会帮助你适应更大(更长,或更宽,或大批量)内存中的序列。伪无限序列有一个单独的技巧,但它只适用于单向 RNNs。
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 时处理非常长的序列,人们会做 其他事情:他们保存 final 每个批次的隐藏状态,并将它们用作下一批次的 初始 隐藏状态(为此,下一批次必须由前几批的序列)
这些线程讨论了如何在 TF 中完成此操作:
我正在尝试标记长字符序列中的字母。数据的固有结构要求我使用双向方法。
进一步基于on this idea我需要在每个时间步访问隐藏状态,而不仅仅是最后一个。
为了尝试这个想法,我使用了固定长度的方法。我目前使用的是我更长的序列中的每批 60 个字符的随机片段和 运行 我手工制作的双向分类器,其中 zero_state
是每个 60 个字母片段的 initial_state
。
这很好用,但显然不完美,因为实际上序列更长,我从原始来源随机剪切的片段的左右信息都丢失了。
现在为了推进我想处理整个序列。尽管它们的长度差异很大,但我无法将整个序列(进一步批处理)放入 GPU。
我在 dynamic_rnn documentation 中找到了 swap_memory - 参数。会有帮助吗?
我没有找到任何进一步的文档来帮助我理解。而且我自己真的不能轻易地尝试这个,因为我需要在每个时间步访问隐藏状态,因此我在不使用任何更高级别的包装器(例如 dynamic_rnn)的情况下对当前图形进行编码。尝试这个将需要我从包装器中获取所有中间状态,据我所知,这需要大量的工作来实现。
在经历这个麻烦之前,我很想确定这确实会解决我的记忆问题。感谢任何提示!
TL;DR: swap_memory
不会让你使用伪无限序列,但它会帮助你适应更大(更长,或更宽,或大批量)内存中的序列。伪无限序列有一个单独的技巧,但它只适用于单向 RNNs。
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 时处理非常长的序列,人们会做 其他事情:他们保存 final 每个批次的隐藏状态,并将它们用作下一批次的 初始 隐藏状态(为此,下一批次必须由前几批的序列)
这些线程讨论了如何在 TF 中完成此操作: