在pytorch中使用填充重塑张量

在pytorch中使用填充重塑张量,pytorch,Pytorch,我有一个维度为(30,35,49)的张量。我想把它重塑成(30,35,512),以便能够与另一个张量相乘,这个张量的形状也是(30,35,512) 我想用(30,35,49)维度填充张量,使其(30,35,512)维度 如何做到这一点?最简单的解决方案是使用填充值和目标尺寸分配张量,并分配有数据的部分: target = torch.zeros(30, 35, 512) source = torch.ones(30, 35, 49) target[:, :, :49] = source 请注意

我有一个维度为
(30,35,49)
的张量。我想把它重塑成
(30,35,512)
,以便能够与另一个张量相乘,这个张量的形状也是
(30,35,512)

我想用
(30,35,49)
维度填充张量,使其
(30,35,512)
维度


如何做到这一点?

最简单的解决方案是使用填充值和目标尺寸分配张量,并分配有数据的部分:

target = torch.zeros(30, 35, 512)
source = torch.ones(30, 35, 49)
target[:, :, :49] = source
请注意,不能保证用零填充张量,然后用另一个张量相乘,这最终是有意义的,这取决于您。

虽然@nemo的解决方案运行良好,但有一个pytorch内部例程也可以执行相同的操作,它有两个属性,
torch.ones(*size)*pad_value
解决方案没有(即其他形式的填充,如反射填充或复制填充……它还检查一些与渐变相关的属性):

import torch.nn.功能为F
来源=火炬兰特((5,10))
#现在我们通过在位置0和位置6追加一行0来扩展到大小(7,11),
#在位置10处有一列0
结果=F.pad(输入=源,pad=(0,1,1,1),模式=常数,值=0)
参数的语义是:

  • 输入
    :源张量
  • pad
    :表格长度
    2*len(source.shape)
    (开始最后一个轴、结束最后一个轴、开始第二个到最后一个轴、结束第二个到最后一个轴、开始第三个到最后一个轴等)的列表,说明每个轴的开始和结束应添加多少尺寸
  • 模式
    “常量”
    “反射”
    “复制”
    。默认值:
    “常量”
    用于不同类型的填充
  • 用于常量填充

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

      导入火炬
      从火炬进口
      x=火炬。一个(30、35、49)
      填充=nn.ConstantPad1d((0,512-49),0)(x)
      


      这里的想法是使用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,0,0)

      这是因为我在第一个
      (2,2)
      之前和之后向x轴添加了两个零,在yaxis
      (2,2)
      之后添加了两个零,因此只保留通道列
      (0,0)
      <代码>值表示填充为0


      谢谢

      实际上,维度的顺序是相反的。因此,pad输入中的前两个值对应于最后一个维度(请参见),padding a tensor是否会影响渐变的值?如果是,怎么做?是的,填充会影响渐变的值。如何操作取决于操作。我的建议是写出要填充输入的函数,然后做一些数学步骤,看看函数的输出如何依赖于填充值。前两个维度仍然相同,这在我的实验中大多数情况下都不会发生,这将破坏计算图:a=torch.zero((2,10)B=火炬= Runn(10,AddiSrGrad=TRUE)A(0)=B损失=SUM()损失.BuffWrd()RunTimeError:叶变量已经被移动到图内部,谢谢,如果我在训练的中间进行PADD,这会保留原始张量的梯度吗?
      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])