Pytorch的“折叠”和“展开”如何工作?

rma*_*c16 4 machine-learning computer-vision deep-learning pytorch

我已经看过官方文件了。我很难理解此功能的用途以及它的工作方式。有人可以用Layman解释吗?

尽管我使用的Pytorch版本与文档相匹配,但它们提供的示例却出现错误。也许纠正错误(应该这样做)应该教给我一些东西?文档中给出的代码段为:

   fold = nn.Fold(output_size=(4, 5), kernel_size=(2, 2))
   input = torch.randn(1, 3 * 2 * 2, 1)
   output = fold(input)
   output.size()
Run Code Online (Sandbox Code Playgroud)

固定的代码段是:

   fold = nn.Fold(output_size=(4, 5), kernel_size=(2, 2))
   input = torch.randn(1, 3 * 2 * 2, 3 * 2 * 2)
   output = fold(input)
   output.size()
Run Code Online (Sandbox Code Playgroud)

谢谢!

uke*_*emi 16

unfold 将张量想象成一个较长的张量,其中重复列/行的值“折叠”在彼此的顶部,然后“展开”:

  • size 确定折叠有多大
  • step 确定折叠的频率

例如,对于一个2×5张,具有展开它step=1,和补丁size=2跨越dim=1

x = torch.tensor([[1,2,3,4,5],
                  [6,7,8,9,10]])
Run Code Online (Sandbox Code Playgroud)
>>> x.unfold(1,2,1)
tensor([[[ 1,  2], [ 2,  3], [ 3,  4], [ 4,  5]],
        [[ 6,  7], [ 7,  8], [ 8,  9], [ 9, 10]]])
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

fold 与此操作大致相反,但“重叠”值在输出中求和。

  • 你的画让我大吃一惊!谢谢你! (4认同)
  • 关于“折叠”和“展开”的重要一点是内存不会被复制。这使得它们速度非常快。但还要注意,如果更改展开数组中的“2”条目,两个 2 都会更改,x 中的原始 2 也会更改。 (2认同)

pro*_*sti 15

一维展开很容易:

x = torch.arange(1, 9).float()
print(x)
# dimension, size, step
print(x.unfold(0, 2, 1))
print(x.unfold(0, 3, 2))
Run Code Online (Sandbox Code Playgroud)

出去:

tensor([1., 2., 3., 4., 5., 6., 7., 8.])
tensor([[1., 2.],
        [2., 3.],
        [3., 4.],
        [4., 5.],
        [5., 6.],
        [6., 7.],
        [7., 8.]])
tensor([[1., 2., 3.],
        [3., 4., 5.],
        [5., 6., 7.]])
Run Code Online (Sandbox Code Playgroud)

二维展开(也称为patching

x = torch.arange(1, 9).float()
print(x)
# dimension, size, step
print(x.unfold(0, 2, 1))
print(x.unfold(0, 3, 2))
Run Code Online (Sandbox Code Playgroud)
tensor([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.,
        14., 15.]) torch.Size([16])
tensor([[[[ 0.,  1.,  2.,  3.],
          [ 4.,  5.,  6.,  7.],
          [ 8.,  9., 10., 11.],
          [12., 13., 14., 15.]]]]) torch.Size([1, 1, 4, 4])
1
torch.Size([4, 1, 3, 3])

tensor([[[[ 0.,  1.,  2.],
          [ 4.,  5.,  6.],
          [ 8.,  9., 10.]]],


        [[[ 4.,  5.,  6.],
          [ 8.,  9., 10.],
          [12., 13., 14.]]],


        [[[ 1.,  2.,  3.],
          [ 5.,  6.,  7.],
          [ 9., 10., 11.]]],


        [[[ 5.,  6.,  7.],
          [ 9., 10., 11.],
          [13., 14., 15.]]]])
Run Code Online (Sandbox Code Playgroud)

修补

  • 可以添加相应的`.fold`操作来返回原始张量吗? (2认同)

Sha*_*hai 9

unfoldfold用于促进“滑动窗口”操作(如卷积)。
假设您要将功能foo应用于要素地图/图像中的每个5x5窗口:

from torch.nn import functional as f
windows = f.unfold(x, kernel_size=5)
Run Code Online (Sandbox Code Playgroud)

现在windows具有batch- size(5 * 5 * x.size(1))-num_windows,您可以foo在上申请windows

processed = foo(windows)
Run Code Online (Sandbox Code Playgroud)

现在,您需要“折叠” processed回原始大小x

out = f.fold(processed, x.shape[-2:], kernel_size=5)
Run Code Online (Sandbox Code Playgroud)

您需要保重paddingkernel_size这可能会影响您“折回” processed到的大小的能力x
此外,对重叠元素fold 求和,因此您可能需要将输出结果fold除以补丁大小。