【问题标题】:Tensor Entry Selection Logic Divergence in PyTorch & NumpyPyTorch 和 Numpy 中的张量入口选择逻辑发散
【发布时间】:2020-01-16 01:30:05
【问题描述】:

说明

我正在设置一个torch.Tensor 用于屏蔽目的。当尝试通过索引选择条目时,使用numpy.ndarraytorch.Tensor 保存索引数据的行为是不同的。我希望能够访问框架和解释差异的相关文档中的设计。

复制步骤

环境

官方发布的容器中的 Pytorch 1.3:pytorch/pytorch:1.3-cuda10.1-cudnn7-devel

示例

假设我需要将mask 设置为torch.Tensor 形状为[3,3,3] 的对象,并将条目(0,0,1)(1,2,0) 的值设置为1。下面的代码解释了不同之处。

mask = torch.zeros([3,3,3])
indices = torch.tensor([[0, 1],
                        [0, 2],
                        [1, 0]])

mask[indices.numpy()] = 1 # Works
# mask[indices] = 1 # Incorrect result

我注意到当使用mask[indices.numpy()] 时,形状为[2] 的新torch.Tensor,而mask[indices] 返回形状为[3, 2, 3, 3] 的新torch.Tensor,这表明张量切片逻辑存在差异。

【问题讨论】:

    标签: python numpy pytorch


    【解决方案1】:

    您会得到不同的结果,因为这就是 Pytorch 中实现索引的方式。如果您将数组作为索引传递,那么它会被“解包”。例如:

    indices = torch.tensor([[0, 1], [0, 2], [1, 0]])
    
    mask = torch.arange(1,28).reshape(3,3,3)
    
    # tensor([[[ 1,  2,  3],
    #          [ 4,  5,  6],
    #          [ 7,  8,  9]],
    
    #         [[10, 11, 12],
    #          [13, 14, 15],
    #          [16, 17, 18]],
    
    #         [[19, 20, 21],
    #          [22, 23, 24],
    #          [25, 26, 27]]])
    

    mask[indices.numpy()]等价于mask[[0, 1], [0, 2], [1, 0]],即indices.numpy()的第i行元素用于沿第i轴选择mask的元素。所以它返回tensor([mask[0,0,1], mask[1,2,0]]),即tensor([2, 16])

    另一方面,当将张量作为索引传递时(我不知道数组和张量之间这种区分索引的确切原因),它不像数组那样“解包”,并且 i 的元素indices 张量的第 - 行用于选择沿轴 0 的 mask 的元素。即mask[indices]等价于mask[[[0, 1], [0, 2], [1, 0]], :, :]

    >>> mask[ind]
    
    tensor([[[[ 1,  2,  3],
              [ 4,  5,  6],
              [ 7,  8,  9]],
    
             [[10, 11, 12],
              [13, 14, 15],
              [16, 17, 18]]],
    
    
            [[[ 1,  2,  3],
              [ 4,  5,  6],
              [ 7,  8,  9]],
    
             [[19, 20, 21],
              [22, 23, 24],
              [25, 26, 27]]],
    
    
            [[[10, 11, 12],
              [13, 14, 15],
              [16, 17, 18]],
    
             [[ 1,  2,  3],
              [ 4,  5,  6],
              [ 7,  8,  9]]]])
    

    基本上是tensor(mask[[0,1], :, :], mask[[0,2],: ,:], mask[[1,0], :, :]),形状为indices.shape + mask[0,:,:].shape == (3,2,3,3)。因此,整个“工作表”被选择并堆叠成新的维度。请注意,这不是一个新的张量,而是mask 的特殊视图。因此,如果你分配mask[indices] = 1,加上这个特定的indices,那么mask 的所有元素都将变为1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-28
      • 2020-10-02
      • 2018-09-20
      • 2021-04-24
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多