【发布时间】:2020-12-16 16:40:19
【问题描述】:
我有一个大小为:torch.Size([1, 63840]) 的张量,然后展开:
inp_unfolded = inp_seq.unfold(1, 160, 80)
这给了我一个形状:torch.Size([1, 797, 160])
我怎样才能重新fold 以获得torch.Size([1, 63840]) 的张量?
【问题讨论】:
我有一个大小为:torch.Size([1, 63840]) 的张量,然后展开:
inp_unfolded = inp_seq.unfold(1, 160, 80)
这给了我一个形状:torch.Size([1, 797, 160])
我怎样才能重新fold 以获得torch.Size([1, 63840]) 的张量?
【问题讨论】:
对于该特定配置,由于63840 可以被160 整除,并且步长是切片大小的倍数,您可以简单地选择沿该维度的每隔一个元素,然后选择flatten 生成的张量:
inp_unfolded[:, ::2, :].flatten(1, 2)
更一般地,对于t.unfold(i, n, s),如果t.shape[i] % n == 0 and n % s == 0 成立,那么您可以通过以下方式恢复原始张量:
index = [slice(None) for __ in t.shape]
index[i] = slice(None, None, n // s)
original = t.unfold(i, n, s)[tuple(index)].flatten(i, i+1)
当然,如果维度i 是已知的,您当然也可以使用切片表示法。例如 i == 1 在您的示例中:
original = t.unfold(1, n, s)[:, ::n//s, ...].flatten(1, 2)
【讨论】:
好吧,实际上给定t.unfold(i, n, s)的条件是:
n >= s(否则步骤会跳过一些原始数据,我们无法恢复)n + s <= t.shape[i]然后我们可以通过:
def roll(x, n, s, axis=1):
return torch.cat((p[0], p[1:][:, n-s:].flatten()), axis)
解释:
p[0] 是起始块,在开始时总是唯一的
p[1:][:, n-s:] - 然后,我们取其余的卷,n-s 描述了卷之间有多少元素重叠,所以我们想忽略它们,只取来自n-s 的元素
插图:
x.unfold(0, 5, 2)
tensor([[ 1., 2., 3., 4., 5.],
[ 3., 4., 5., 6., 7.], # 3, 4, 5 are repeated
[ 5., 6., 7., 8., 9.], # 5, 6, 7 are repeated...
[ 7., 8., 9., 10., 11.],
[ 9., 10., 11., 12., 13.],
[11., 12., 13., 14., 15.],
[13., 14., 15., 16., 17.]])
示例:
>> x = torch.arange(1., 18)
>> p = x.unfold(0, 5, 2)
>> roll(p, 5, 2, 0)
tensor([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14.,
15., 16., 17.])
你也可以试试
x = torch.arange(1., 18).reshape(1, 17)
和轴 1
【讨论】: