python pytorch中的四维Tensor上采样

kuuvgm7e  于 2023-03-06  发布在  Python
关注(0)|答案(1)|浏览(267)

我创建了以下大小的4DTensor。(B,C,H,W)
我想把这个Tensor重新整形成如下大小。(B,C,2H,2W)
每个值扩展为4个值,但只有原始Tensor中具有与索引Tensor中的值相对应的索引的元素保持与原始Tensor的值相同。
索引遵循以下规则。
0 1
2 3
下面是一个例子:

original tensor:
torch.Size([1, 1, 2, 2])
tensor([[[[1.0000, 0.4000],
          [0.2000, 0.5000]]]])

index tensor:
torch.Size([1, 1, 2, 2])
tensor([[[[0, 2],
          [1, 1]]]])
output tensor:
torch.Size([1, 1, 4, 4])
tensor([[[[1.0000, 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.4000, 0.0000],
          [0.0000, 0.2000, 0.0000, 0.5000],
          [0.0000, 0.0000, 0.0000, 0.0000]]]])

我怎样才能有效地转换这个Tensor,同时充分利用GPU?(也许我们可以使用torch. tensor. scatter_)

2w2cym1i

2w2cym1i1#

我最初的想法是,您可以利用nn.MaxUnpool2d层将原始Tensorxindex解池到所需的位置。然而,您当前的设置使用基于平方0, 1, 2, 3布局的本地索引。这意味着,为了有效地使用解池层,我们首先需要正确地转换您当前的索引Tensor:

tensor([[[[0, 2],
          [1, 1]]]])

变成这样:

tensor([[[[0,  6],
          [9, 11]]]])

如果每个索引指的是位置,则移动窗口将以x为单位放置值。
为此,我们需要对index执行以下操作
1.首先将索引Tensor转换为一位热码编码表示,以使用nn.functional.one_hot扩展元素数量:

>>> one_hot(index, 4)
tensor([[[[[1, 0, 0, 0],      # [[[[[a0, a1, a2, a3],
           [0, 0, 1, 0]],     #     [b0, b1, b2, b3]],

          [[0, 1, 0, 0],      #    [[c0, c1, c2, c3],
           [0, 1, 0, 0]]]]])  #     [d0, d1, d2, d3]]]]]

然后我们需要将当前Tensor转换为以下布局:

# [[[[[a0, a1, b0, b1],
#     [a2, a3, b2, b3]],

#    [[c0, c1, d0, d2],
#     [c2, c3, d2, d3]]]]]

1.首先将Tensor展平为一组2x2:

>>> ohe = one_hot(index, 4).view(2,2,2,2)
tensor([[[[1, 0],     # [[[[a0, a1],
          [0, 0]],    #    [a2, a3]],

         [[0, 0],     #   [[b0, b1],
          [1, 0]]],   #    [b2, b3]],

        [[[0, 1],     #  [[[c0, c1],
          [0, 0]],    #   [[c2, c3]],

         [[0, 1],     #   [[d0, d1],
          [0, 0]]]])  #    [d2, d3]]]]

1.现在所采取的一系列步骤允许使用恢复所需的布局,而不必拆分和连接元素。* 您可以查看此other answer * 上的过程的详细说明。

>>> y = ohe.transpose(-1,-2).reshape(2,-1,2).transpose(-1,-2)
tensor([[[1, 0, 0, 0],      # [[[[[a0, a1, b0, b1],
         [0, 0, 1, 0]],     #     [a2, a3, b2, b3]],

        [[0, 1, 0, 1],      #    [[c0, c1, d0, d2],
         [0, 0, 0, 0]]])    #     [c2, c3, d2, d3]]]]]

1.然后,通过乘以一组值来展平和分解指数:

>>> y.reshape(-1)
tensor([ 1,  0,  0,  0,  0,  0,  1,  0,  0,  1,  0,  1,  0,  0,  0, 0])

>>> i = y.reshape(-1)*(torch.arange(4*x.numel())+1)
tensor([ 1,  0,  0,  0,  0,  0,  7,  0,  0, 10,  0, 12,  0,  0,  0, 0])

1.所需的折射率Tensor为:

>>> unpool_i = i.nonzero().view_as(x)
tensor([[[[ 0,  6],
          [ 9, 11]]]])

1.最后,您可以使用以下命令应用取消池化层:

>>> unpool = nn.MaxUnpool2d(kernel_size=2, stride=2)
>>> unpool(x, unpool_i)
tensor([[[[1.0000, 0.0000, 0.0000, 0.0000],
          [0.0000, 0.0000, 0.4000, 0.0000],
          [0.0000, 0.2000, 0.0000, 0.5000],
          [0.0000, 0.0000, 0.0000, 0.0000]]]])

相关问题