如何通过滑动 window 调整 PyTorch 张量的大小?

How can I resize a PyTorch tensor with a sliding window?

我有一个张量,大小为:torch.Size([118160, 1])。我想要做的是将它分成 n 个张量,每个张量有 100 个元素,一次滑动 50 个元素。使用 PyTorch 实现此目的的最佳方法是什么?

您的元素数量需要被 100 整除。如果不是这种情况,您可以使用填充进行调整。

您可以先对原始列表进行拆分。 然后对列表进行拆分,其中前 50 个元素从原始列表中删除。 如果您想保留原始顺序,则可以从 A 和 B 中交替抽样。

A = yourtensor
B = yourtensor[50:] + torch.zeros(50,1)
A_ = A.view(100,-1)
B_ = B.view(100,-1)

一个可能的解决方案是:

window_size = 100
stride = 50
splits = [x[i:min(x.size(0),i+window_size)] for i in range(0,x.size(0),stride)]

不过,最后几个元素会比window_size短。如果这是不希望的,你可以这样做:

splits = [x[i:i+window_size] for i in range(0,x.size(0)-window_size+1,stride)]

编辑:

更具可读性的解决方案:

# if keep_short_tails is set to True, the slices shorter than window_size at the end of the result will be kept 
def window_split(x, window_size=100, stride=50, keep_short_tails=True):
  length = x.size(0)
  splits = []

  if keep_short_tails:
    for slice_start in range(0, length, stride):
      slice_end = min(length, slice_start + window_size)
      splits.append(x[slice_start:slice_end])
  else:
    for slice_start in range(0, length - window_size + 1, stride):
      slice_end = slice_start + window_size
      splits.append(x[slice_start:slice_end])

  return splits

可以使用Pytorch的展开API。参考这个 https://pytorch.org/docs/stable/generated/torch.Tensor.unfold.html

示例:

x = torch.arange(1., 20)
x.unfold(0,4,2)

tensor([[ 1.,  2.,  3.,  4.],  
        [ 3.,  4.,  5.,  6.],  
        [ 5.,  6.,  7.,  8.],  
        [ 7.,  8.,  9., 10.],  
        [ 9., 10., 11., 12.],  
        [11., 12., 13., 14.],  
        [13., 14., 15., 16.],  
        [15., 16., 17., 18.]])