为啥我们有 pack_sequence() 时还需要 pack_padded_sequence()?
Posted
技术标签:
【中文标题】为啥我们有 pack_sequence() 时还需要 pack_padded_sequence()?【英文标题】:Why do we need pack_padded_sequence() when we have pack_sequence()?为什么我们有 pack_sequence() 时还需要 pack_padded_sequence()? 【发布时间】:2020-05-13 06:21:51 【问题描述】:在阅读了this 问题的答案后,我仍然对整个 PackedSequence 对象感到有些困惑。据我了解,这是一个针对循环模型中可变大小序列的并行处理进行了优化的对象,零填充是一个[不完美的]解决方案。似乎给定一个 PackedSequence 对象,Pytorch RNN 会将批处理中的每个序列处理到最后,而不是继续处理填充。那么为什么这里需要填充呢?为什么同时有 pack_padded_sequence() 和 pack_sequence() 方法?
【问题讨论】:
【参考方案1】:主要是出于历史原因; torch.nn.pack_padded_sequence()
是在 torch.nn.pack_sequence()
之前创建的(如果我没看错的话,这是第一次出现在 0.4.0
中),我认为没有理由删除此功能并破坏向后兼容性。
此外,您的输入pad
的最佳/最快方式并不总是很清楚,而且您使用的数据差异很大。如果事先以某种方式填充数据(例如,您的数据已预先填充并提供给您),使用pack_padded_sequence()
会更快(请参阅source code of pack_sequence
,它会为您计算每个数据点的length
并调用@987654329 @ 后跟 pack_padded_sequence
内部)。可以说,pad_packed_sequence
现在很少使用了。
最后,请注意 enforce_sorted
参数自 1.2.0
版本以来为这两个函数提供。不久前,用户必须将他们的数据(或批次)以最长的序列在前,最短的序列在后,现在当此参数设置为 False
时,可以在内部完成。
【讨论】:
谢谢。为什么pad_packed_sequence
已过时?如何解压一个PackedSequence
对象?我编写了以下对我有用的 lambda。有没有更好的办法? unpack = lambda packed_seq_obj: [tnsr[:ln] for tnsr, ln in zip(*pad_packed_sequence(packed_seq_obj, batch_first=True))]
它并没有过时,我提到它是一个错字,抱歉。这是一种方法,这取决于你愿意用它做什么(有时不需要unpack
,例如当你需要最后一个时间戳时)。您的解包代码是可行的方法,该 AFAIK 没有内置功能。
以上是关于为啥我们有 pack_sequence() 时还需要 pack_padded_sequence()?的主要内容,如果未能解决你的问题,请参考以下文章
请教一下数据库字段是varchar,我们做排序的时候为啥999比1111大