在 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。
谢谢!
如何通过填充将维度为 (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。
谢谢!