分别沿不同的两个轴连接二维张量列表,得到张量 A,B,其中 A.T==B,但它们沿同一轴的平均值略有不同
(A.T.mean(axis=0) != B.mean(axis=0))
,为什么?理论上它们是相同的。
从形状为 (10,2,1) 的 3d 列表开始
In [4]: tmp
Out[4]:
[[[0.3471660912036896], [0.652833878993988]],
[[0.5512792468070984], [0.4487205743789673]],
[[0.5454527139663696], [0.4545471668243408]],
[[0.3661797344684601], [0.6338202953338623]],
[[0.2655346989631653], [0.7344651222229004]],
[[0.28296780586242676], [0.717032253742218]],
[[0.28441378474235535], [0.7155864238739014]],
[[0.3660774230957031], [0.6339224576950073]],
[[0.3515346944332123], [0.6484655141830444]],
[[0.3660774230957031], [0.6339224576950073]]]
tmp
转换为张量列表In [7]: tensor_list = [torch.tensor(x) for x in tmp]
...: tensor_list
Out[7]:
[tensor([[0.3472],
[0.6528]]),
tensor([[0.5513],
[0.4487]]),
tensor([[0.5455],
[0.4545]]),
tensor([[0.3662],
[0.6338]]),
tensor([[0.2655],
[0.7345]]),
tensor([[0.2830],
[0.7170]]),
tensor([[0.2844],
[0.7156]]),
tensor([[0.3661],
[0.6339]]),
tensor([[0.3515],
[0.6485]]),
tensor([[0.3661],
[0.6339]])]
其中 A.shape == B.shape
In [11]: A = torch.cat([x.T for x in tensor_list], dim=0)
...: A.shape
Out[11]: torch.Size([10, 2])
In [12]: B = torch.cat(tensor_list, dim=1).T
...: B.shape
Out[12]: torch.Size([10, 2])
步骤3.检查A和B之间的一致性。我们可以在下面看到它们的逐元素差异之和为零,并且逐元素比较显示每个元素与另一个张量中的元素相同。
In [13]: (A - B).abs().sum()
Out[13]: tensor(0.)
In [14]: A == B
Out[14]:
tensor([[True, True],
[True, True],
[True, True],
[True, True],
[True, True],
[True, True],
[True, True],
[True, True],
[True, True],
[True, True]])
步骤 4. 检查它们沿轴 (0) 的平均值。奇怪的是,略有不同。
In [15]: A.mean(dim=0) - B.mean(dim=0)
Out[15]: tensor([5.9605e-08, 0.0000e+00])
虽然它们的平均值之间的差异很小,可以忽略不计,但我想知道为什么会发生这种情况。 torch.cat() 是如何工作的?
[环境信息]
张量具有相同的形状和值,但它们的构造导致它们具有不同的内存布局。您可以使用 stride 函数看到这一点:
tmp = torch.randn(10,2,1)
tensor_list = [x for x in tmp]
A = torch.cat([x.T for x in tensor_list], dim=0)
B = torch.cat(tensor_list, dim=1).T
print(A.stride())
> (2, 1)
print(B.stride())
> (1, 10)
步幅告诉我们需要沿着轴移动多少字节才能从一个值到达另一个值。
由于内存布局不同,因此
mean
操作以不同的顺序处理每个张量的值。不同的平均结果来自于不同的运算顺序以及数值精度问题。
作为比较,如果您从列表中重新创建
A
和 B
(创建一个全新的张量),您将得到两个具有相同步幅且没有均值差的张量。
C = torch.tensor(A.tolist())
D = torch.tensor(B.tolist())
print(C.stride())
> (2, 1)
print(D.stride())
> (2, 1)
C.mean(dim=0) - D.mean(dim=0)
> tensor([0., 0.])