Home Articles

为什么我们在pytorch中“打包”序列?

Asked
Viewed 363 times
13

我试图复制How to use packing for variable-length sequence inputs for rnn但我想我首先需要理解为什么我们需要"pack"序列 .

我理解为什么我们需要"pad"但是为什么"packing"(通过 pack_padded_sequence )是必要的?

任何高级别的解释将不胜感激!

2 Answers

  • 19

    我偶然发现了这个问题,下面就是我想到的 .

    在训练RNN(LSTM或GRU或vanilla-RNN)时,很难对可变长度序列进行批处理 . 例如:如果8号批次的序列长度是[4,6,8,5,4,3,7,8],你将填充所有序列,这将产生8个长度为8的序列 . 你会最终做了64次计算(8x8),但你只需要进行45次计算 . 此外,如果你想做一些像使用双向RNN这样的事情,那么仅仅通过填充就更难进行批量计算,你可能最终会进行比所需更多的计算 .

    相反,pytorch允许我们打包序列,内部打包序列是两个列表的元组 . 一个包含序列的元素 . 元素按时间步长交错(参见下面的示例),其他元素包含每个步骤的批量大小的每个序列的大小 . 这有助于恢复实际序列以及告知RNN每个时间步的批量大小 . @Aaron指出了这一点 . 这可以传递给RNN,它将在内部优化计算 .

    我可能在某些方面不清楚,所以让我知道,我可以添加更多的解释 .

    a = [torch.tensor([1,2,3]), torch.tensor([3,4])]
     b = torch.nn.utils.rnn.pad_sequence(a, batch_first=True)
     >>>>
     tensor([[ 1,  2,  3],
        [ 3,  4,  0]])
     torch.nn.utils.rnn.pack_padded_sequence(b, batch_first=True, lengths=[3,2]
     >>>>PackedSequence(data=tensor([ 1,  3,  2,  4,  3]), batch_sizes=tensor([ 2,  2,  1]))
    
  • 6

    除了Umang的回答,我发现这很重要 .

    返回的 pack_padded_sequence 元组中的第一项是包含打包序列的数据(张量) - 张量 . 第二项是整数的张量,在每个序列步骤中保存有关批量大小的信息 .

    这里重要的是第二项(批量大小)表示批次中每个序列步骤的元素数量,而不是传递给 pack_padded_sequence 的变化序列长度 .

    例如,给定数据 abcx :class: PackedSequence 将包含带有 batch_sizes=[2,1,1] 的数据 axbc .

Related