# 在某些情况下,即使形状不同,我们仍然可以通过调用 广播机制(broadcasting mechanism)来执行按元素操作。这种机制的工作方式如下: # 1. 通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状; # 2. 对生成的数组执行按元素操作。 a = torch.arange(3).reshape(3, 1) b = torch.arange(2).reshape(1, 2) a, b
(tensor([[0],
[1],
[2]]),
tensor([[0, 1]]))
""" 矩阵a将复制列, 矩阵b将复制行,然后再按元素相加。 a -> tensor([[0, 0], [1, 1], [2, 2]]) b -> tensor([[0, 1], [0, 1], [0, 1]])) """ a + b
# 语句Y = Y + X会为新结果分配内存,而不是原地更新变量Y,我们需要一种方法可以原地更新变量Y以节省内存 # 在机器学习中,我们可能有数百兆的参数,并且在一秒内多次更新所有参数。通常情况下,我们希望原地执行这些更新; # 如果我们不原地更新,其他引用仍然会指向旧的内存位置,这样我们的某些代码可能会无意中引用旧的参数。 # 执行原地操作非常简单,可以使用切片表示法将操作的结果分配给先前分配的数组 Z = torch.zeros_like(Y) #使用zeros_like来分配一个全0的块,形状与张量Y相同 print('id(Z):', id(Z)) Z[:] = X + Y print('id(Z):', id(Z))
id(Z): 2403882846624
id(Z): 2403882846624
# 如果在后续计算中没有重复使用X, 我们也可以使用X[:] = X + Y或X += Y来减少操作的内存开销。 # 观察:在torch中,X = X + Y 与 X += Y 可能是不一样的,一个开辟新的内存空间,一个原地更新 before = id(X) X += Y id(X) == before
True
2.1.6. 转换为其他Python对象
# 使用numpy方法或torch.tensor方法来在numpy张量和torch张量间转换 A = X.numpy() B = torch.tensor(A) type(A), type(B)
(numpy.ndarray, torch.Tensor)
# 要将大小为1的张量转换为Python标量,我们可以调用item函数或Python的内置函数。 a = torch.tensor([3.5]) a, a.item(), float(a), int(a)