3.8.2 转置而不复制
让我们现在尝试转置。 让我们看一下点张量,将其在行中具有单个点,在列中具有X和Y坐标,然后将其旋转以使单个点在列中。 我们借此机会介绍t函数,它是二维张量转置的一种简写形式:
# In[30]:
points = torch.tensor([[4.0, 1.0], [5.0, 3.0], [2.0, 1.0]])
points
# Out[30]:
tensor([[4., 1.],
[5., 3.],
[2., 1.]])
# In[31]:
points_t = points.t()
points_t
# Out[31]:
tensor([[4., 5., 2.],
[1., 3., 1.]])
提示:为帮助您深入了解张量的原理,在逐步阅读本节中的代码时,最好拿起一支铅笔,一张纸和一个涂鸦图,如图3.5所示。
我们可以轻松地验证两个张量共享相同的存储
# In[32]:
id(points.storage()) == id(points_t.storage())
# Out[32]:
True
并且它们只是形状和步幅不同:
# In[33]:
points.stride()
# Out[33]:
(2, 1)
# In[34]:
points_t.stride()
# Out[34]:
(1, 2)
这告诉我们,将第一个索引以点为单位增加一个,例如,从points [0,0]到points [1,0],将沿着存储跳过两个元素,在增加第二个索引(从点[0,0]到点[0,1]的同时)将沿着存储空间跳一。 换句话说,存储器将张量中的元素逐行顺序地保持。
我们可以将点转置为points_t,如图3.6所示。 我们按步幅改变元素的顺序。 之后,增加行(张量的第一个索引)将沿存储空间跳过一个,就像我们沿点的列移动时一样。 这就是转置的定义。 没有分配新的内存:仅通过创建步长顺序与原始步长顺序不同的新Tensor实例来获得转置。