我正在寻找一种好的(有效且最好是简单的)方法,该方法可以根据长度/形状可变的序列创建填充张量。到目前为止,我能想象的最好的方法是这样的幼稚方法:
import torch
seq = [1,2,3] # seq of variable length
max_len = 5 # maximum length of seq
t = torch.zeros(5) # padding value
for i, e in enumerate(seq):
t[i] = e
print(t)
输出:
tensor([ 1., 2., 3., 0., 0.])
是否有更好的方法?
我还没有发现任何东西,但是我想肯定有更好的东西了。
我正在考虑一些功能,以使用所需的填充将序列张量扩展到所需的形状。或者直接从序列中创建填充张量的东西。但是当然也欢迎使用其他方法。
答案 0 :(得分:7)
将可变长度序列设为torch.Tensor
,然后使用torch.nn.functional.pad
import torch
import torch.nn.functional as F
seq = torch.Tensor([1,2,3]) # seq of variable length
print(F.pad(seq, pad=(0, 2), mode='constant', value=0))
1
2
3
0
0
[torch.FloatTensor of size 5]
F.pad
的签名是:
input
:输入张量是可变长度序列。pad
:m元素元组,其中(m / 2)≤输入尺寸,m为偶数。在1D情况下,第一个元素是序列左侧的填充量,第二个元素是序列右侧的填充量。mode
:用一个常数或通过复制边框或反映值填充填充。value
:如果您选择固定填充,则为填充值。答案 1 :(得分:6)
作为@iacolippo已经给出的答案的补充:
我刚刚偶然发现torch.nn.utils.rnn.pad_sequence
,因为@iacolippo的解决方案将其发布在这里,所以工作原理有所不同。
它获取一个可变长度的张量列表,并将它们组合成一个矩阵-将所有序列填充到最长的给定序列中。
代码示例:
import torch
a = torch.tensor([1,2,3])
b = torch.tensor([1,2])
c = torch.tensor([1])
torch.nn.utils.rnn.pad_sequence((a,b,c), batch_first=True)
输出-填充序列:
tensor([[ 1, 2, 3],
[ 1, 2, 0],
[ 1, 0, 0]])
torch.nn.utils.rnn.pad_sequence
的签名:
torch.nn.utils.rnn.pad_sequence (序列,batch_first = False,padding_value = 0)
- 序列(
list[Tensor]
)–可变长度序列的列表。- batch_first (
bool
,可选)–如果为True,则输出将在B x T x *
中;否则,将输出为T x B x *
- padding_value ({{1},可选)–填充元素的值。默认值:
float
。