在 pytorch 中用填充重塑张量

reshaping a tensor with padding in pytorch

如何通过填充将维度为 (30, 35, 49) 的张量整形为 (30, 35, 512)

最简单的解决方案是使用您的填充值和目标维度分配一个张量,并分配您拥有数据的部分:

target = torch.zeros(30, 35, 512)
source = torch.ones(30, 35, 49)
target[:, :, :49] = source

请注意,不能保证用零填充您的张量,然后将其与另一个张量相乘最终是否有意义,这取决于您。

虽然 @nemo 的解决方案工作正常,但有一个 pytorch 内部例程,torch.nn.functional.pad,它做同样的事情 - 并且它有几个 torch.ones(*sizes)*pad_value 解决方案没有的属性(即其他形式的填充,比如反射填充或复制填充......它还会检查一些与梯度相关的属性):

import torch.nn.functional as F
source = torch.rand((5,10))
# now we expand to size (7, 11) by appending a row of 0s at pos 0 and pos 6, 
# and a column of 0s at pos 10
result = F.pad(input=source, pad=(0, 1, 1, 1), mode='constant', value=0)

参数的语义是:

  • input:源张量,
  • pad:长度为 2 * len(source.shape) 的列表(开始最后一个轴,结束最后一个轴,从倒数第二个轴开始,倒数第二个轴结束,倒数第三个轴开始,等)说明应该在每个轴的开始和结束处添加多少维度,
  • mode'constant''reflect''replicate'。默认值:'constant' 用于不同类型的填充
  • value 用于常量填充。

一个可能更清晰、更适合这个问题的模块是torch.nn.ConstantPad1d,例如

import torch
from torch import nn

x = torch.ones(30, 35, 49)
padded = nn.ConstantPad1d((0, 512 - 49), 0)(x)

import torch.nn.functional as F
data = torch.ones(4, 4)
# pad(left, right, top, bottom)
new_data = F.pad(input=data, pad=(1, 1, 1, 1), mode='constant', value=0)
print(new_data)

这里的想法是使用 torch.cat 用你想要的张量填充特定维度。这个例子应该更清楚。

In [1]: import torch

In [2]: a = torch.randn(30, 35, 49)

In [3]: b = torch.randn(30, 35, 512)

In [4]: padder = torch.zeros(30,35,512 - 49)

In [5]: padded_a = torch.cat([a,padder], dim = 2) # Choose your desired dim

In [6]: padded_a.shape
Out[6]: torch.Size([30, 35, 512])

In [7]: target = torch.randn(30,35,512)

In [8]: target = torch.cat([target,padded_a], dim = 2)

In [9]: target.shape
Out[9]: torch.Size([30, 35, 1024])

只是想说明@ghchoi 给出的答案。因为我跟着它有点麻烦。

由于内核大小限制,我想将尺寸为 (N,1,28,28) 的标准 mnist 中的图像拟合到 LeNet(早在 1998 年就提出),希望输入的形状为 (N,1,32,32)。所以假设我们尝试通过填充来缓解这个问题。

填充前

在填充单个图像之前,它的大小为(1,28,28). 因此我们有三个维度。

填充后

填充后,创建大小为 (1,32,32) 的图像。注意 pad=(2,2,2,2,0,0)

这是因为我在第一个 (2,2) 之前和之后的 x 轴上添加了两个零,在 yaxis (2,2) 之后添加了两个零,因此单独留下通道列 (0,0)value 表示填充为 0。

谢谢!