pytorch 计算成对差异:NumPy 与 PyTorch 和不同 PyTorch 版本的结果不正确
pytorch compute pairwise difference: Incorrect result in NumPy vs PyTorch and different PyTorch versions
假设我有两个数组,我想计算两个相同形状的矩阵的每两行之间的逐行差异,如下所示。这就是程序在 numpy 中的样子,我想在 pytorch 中复制同样的东西。
>>> a = np.array([[1,2,3],[4,5,6]])
>>> b = np.array([[3,4,5],[5,3,2]])
>>> c = a[np.newaxis,:,:] - b[:,np.newaxis,:]
>>> print(c)
[[[-2 -2 -2]
[ 1 1 1]]
[[-4 -1 1]
[-1 2 4]]]
顺便说一句,我用 pytorch 尝试了同样的事情,但它不起作用。无论如何我们可以在 pytorch
中完成同样的事情吗?
>>> import torch
>>> a = torch.from_numpy(a)
>>> b = torch.from_numpy(b)
>>> c1 = a[None,:,:]
>>> c2 = b[:,None,:]
>>> diff = c1 - c2
>>> print(diff.size())
torch.Size([1, 2, 3])
我实际上是在寻找 torch.Size([2,2,3])
。 (P.S。我也尝试从 pytorch 解压,但它不起作用)。
问题的出现是因为使用了PyTorch 0.1。如果使用 PyTorch 1.0.1,NumPy 的相同操作可以推广到 PyTorch,没有任何修改和问题。这是 Colab 中 运行 的快照。
正如我们所见,我们确实得到了相同的结果。
这里尝试重现您因获得错误结果而遇到的错误:
>>> t1 = torch.from_numpy(a)
>>> t2 = torch.from_numpy(b)
>>> t1[np.newaxis, ...] - t2[:, np.newaxis, ...]
(0 ,.,.) =
-2 -2 -2
-1 2 4
[torch.LongTensor of size 1x2x3]
>>> torch.__version__
'0.1.12_1'
所以,请将您的 PyTorch 版本升级到 1.0.1!
深入了解详情:
它在PyTorch 0.1版本中不起作用的主要原因是当时广播还没有完全实现。基本上,将张量提升为 3D,然后进行减法可以分两步实现,如(在版本 1.0.1 中):
>>> t1[:1, ] - t2
>>> tensor([[-2, -2, -2], # t1_r1
[-4, -1, 1]]) # t1_r2
>>> t1[1:, ] - t2
>>> tensor([[ 1, 1, 1], # t2_r1
[-1, 2, 4]]) # t2_r2
以上两个操作的结果按(t1_r1、t2_r1、t1_r2、t2_r2的顺序堆叠在一起的行,在每一行之后作为 2D 会给我们形状 (2, 2, 3)
.
现在,在 0.1 版本中尝试执行上述两个步骤,它会抛出错误:
RuntimeError: inconsistent tensor size at /opt/conda/conda-bld/pytorch_1501971235237/work/pytorch-0.1.12/torch/lib/TH/generic/THTensorMath.c:831
我使用的是最新版本的Pytorch 1.0.1。这个解决方案对我有用:
a = torch.tensor([[1,2,3],[4,5,6]])
b = torch.tensor([[3,4,5],[5,3,2]])
c = a.view(1, 2, 3) - b.view(2, 1, 3)
"""
tensor([[[-2, -2, -2],
[ 1, 1, 1]],
[[-4, -1, 1],
[-1, 2, 4]]])
"""
c.size()
"""
torch.Size([2, 2, 3])
"""
假设我有两个数组,我想计算两个相同形状的矩阵的每两行之间的逐行差异,如下所示。这就是程序在 numpy 中的样子,我想在 pytorch 中复制同样的东西。
>>> a = np.array([[1,2,3],[4,5,6]])
>>> b = np.array([[3,4,5],[5,3,2]])
>>> c = a[np.newaxis,:,:] - b[:,np.newaxis,:]
>>> print(c)
[[[-2 -2 -2]
[ 1 1 1]]
[[-4 -1 1]
[-1 2 4]]]
顺便说一句,我用 pytorch 尝试了同样的事情,但它不起作用。无论如何我们可以在 pytorch
中完成同样的事情吗?>>> import torch
>>> a = torch.from_numpy(a)
>>> b = torch.from_numpy(b)
>>> c1 = a[None,:,:]
>>> c2 = b[:,None,:]
>>> diff = c1 - c2
>>> print(diff.size())
torch.Size([1, 2, 3])
我实际上是在寻找 torch.Size([2,2,3])
。 (P.S。我也尝试从 pytorch 解压,但它不起作用)。
问题的出现是因为使用了PyTorch 0.1。如果使用 PyTorch 1.0.1,NumPy 的相同操作可以推广到 PyTorch,没有任何修改和问题。这是 Colab 中 运行 的快照。
正如我们所见,我们确实得到了相同的结果。
这里尝试重现您因获得错误结果而遇到的错误:
>>> t1 = torch.from_numpy(a)
>>> t2 = torch.from_numpy(b)
>>> t1[np.newaxis, ...] - t2[:, np.newaxis, ...]
(0 ,.,.) =
-2 -2 -2
-1 2 4
[torch.LongTensor of size 1x2x3]
>>> torch.__version__
'0.1.12_1'
所以,请将您的 PyTorch 版本升级到 1.0.1!
深入了解详情:
它在PyTorch 0.1版本中不起作用的主要原因是当时广播还没有完全实现。基本上,将张量提升为 3D,然后进行减法可以分两步实现,如(在版本 1.0.1 中):
>>> t1[:1, ] - t2
>>> tensor([[-2, -2, -2], # t1_r1
[-4, -1, 1]]) # t1_r2
>>> t1[1:, ] - t2
>>> tensor([[ 1, 1, 1], # t2_r1
[-1, 2, 4]]) # t2_r2
以上两个操作的结果按(t1_r1、t2_r1、t1_r2、t2_r2的顺序堆叠在一起的行,在每一行之后作为 2D 会给我们形状 (2, 2, 3)
.
现在,在 0.1 版本中尝试执行上述两个步骤,它会抛出错误:
RuntimeError: inconsistent tensor size at /opt/conda/conda-bld/pytorch_1501971235237/work/pytorch-0.1.12/torch/lib/TH/generic/THTensorMath.c:831
我使用的是最新版本的Pytorch 1.0.1。这个解决方案对我有用:
a = torch.tensor([[1,2,3],[4,5,6]])
b = torch.tensor([[3,4,5],[5,3,2]])
c = a.view(1, 2, 3) - b.view(2, 1, 3)
"""
tensor([[[-2, -2, -2],
[ 1, 1, 1]],
[[-4, -1, 1],
[-1, 2, 4]]])
"""
c.size()
"""
torch.Size([2, 2, 3])
"""