PyTorch学习(1):torch.meshgrid的使用-CSDN博客
PyTorch学习(2):torch.device-CSDN博客
PyTorch学习(9):torch.topk-CSDN博客
PyTorch学习(10):torch.where-CSDN博客
1. 写在前面
在深度学习框架PyTorch中,view, reshape, permute, 和 transpose 是用于操作张量的重要函数。它们允许我们对张量的形状和维度进行变换,这在神经网络的设计和实现中是非常常见的。下面,我们将逐一介绍这些函数的功能和用法。
2. view函数
view 函数用于改变张量的形状而不改变其数据。它返回一个具有新形状的张量,该张量的元素数量必须与原始张量相同。如果新形状与原始形状不兼容,view 函数将引发错误。
import torch# 创建一个张量x = torch.arange(12)print("原始张量:", x)# 使用view改变形状x_view = x.view(3, 4)print("view后的张量:", x_view)print(f"x_view.is_contiguous: {x_view.is_contiguous()}")[点击并拖拽以移动]
得到如下结果:
原始张量: tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])view后的张量: tensor([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])x_view.is_contiguous: True
由上可以看出,view重新定义了x的形状,但并未改变x的内存存储情况。
3. reshape函数
reshape 函数与 view 类似,也用于改变张量的形状。不同之处在于,reshape 可以在必要时自动调整张量的内存布局,而 view 则要求连续的内存布局。这意味着 reshape 更加灵活,但可能会带来性能上的损失。
# 使用reshape改变形状x_reshape = x.reshape(3, 4)print("reshape后的张量:", x_reshape)
获得如下结果。
原始张量: tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])reshape后的张量: tensor([[ 0, 1, 2, 3],[ 4, 5, 6, 7],[ 8, 9, 10, 11]])x_reshape.is_contiguous: True
由上可以看到,reshape同样重新定义了x的形状,也同样没有改变内存的存储情况。
需要指出,view和reshape是有区别的,这在后面我们会一示例的情况给出讲解。
3. permute函数
permute 函数用于重新排列张量的维度。它接受一个包含新维度顺序的元组作为参数,并返回一个新的张量,其中所有维度按照指定的顺序重新排列。
# 创建一个三维张量x_3d = torch.randn(2, 3, 4)print("原始三维张量:", x_3d)# 使用permute重新排列维度x_3d_permute = x_3d.permute(2, 0, 1) # 将维度顺序改为4, 2, 3print("permute后的三维张量:", x_3d_permute)
运行以上程序获得如下的结果。
原始三维张量: tensor([[[-1.0659, -0.2152, -0.5032, 1.4046],[-0.0707, 0.4638, 0.0902, -0.2389],[-0.4463, 0.0115, 0.9082, 1.3913]],[[-0.1206, 0.2040, -0.6793, -0.1782],[-1.1659, -0.1593, -1.0143, -0.5418],[-0.0641, 0.6947, -0.0991, -0.8461]]])permute后的三维张量: tensor([[[-1.0659, -0.0707, -0.4463],[-0.1206, -1.1659, -0.0641]],[[-0.2152, 0.4638, 0.0115],[ 0.2040, -0.1593, 0.6947]],[[-0.5032, 0.0902, 0.9082],[-0.6793, -1.0143, -0.0991]],[[ 1.4046, -0.2389, 1.3913],[-0.1782, -0.5418, -0.8461]]])x_3d_permute.is_contiguous: False
经过permute后,重新排列的x_3d的维度,此时我们可以看到同样改变了x_3d的内存存储形式,已经不再连续。
我们继续执行如下转换。
x_3d_permute_reshape = x_3d_permute.reshape(3, 2, 4)
得到结果如下。
x_3d_permute_reshape.is_contiguous: True
我们得到一个阶段性结论,经过permute之后的tensor可以使用reshape继续进行形状的重新调整,此时得到的tensor又转换为内存连续存储。
我们将reshape换做view进行形状的调整。
得到如下的结果。
Traceback (most recent call last):File "PTTest.py", line 12, in <module>x_3d_permute_reshape = x_3d_permute.view(3, 2, 4)RuntimeError: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
提示我们,需要先对tensor进行contiguous()操作,在进行view的调整。
我们看到,经过permute调整维度后,tensor的存储内存不再连续,之后可以使用reshape进行形状调整。如果想使用view进行调整,需要先调整内存存储情况。具体执行情况如下。
x_3d_permute_reshape = x_3d_permute.reshape(3, 2, 4)或x_3d_permute = x_3d_permute.contiguous()x_3d_permute_reshape = x_3d_permute.view(3, 2, 4)
4. transpose函数
transpose 函数用于交换两个指定维度上的张量。它接受两个维度索引作为参数,并返回一个新的张量,其中这两个维度被交换。
import torch# 使用transpose交换维度x_3d = torch.randn(2, 3, 4)x_transpose = x_3d.transpose(0, 2) # 交换第1个和第3个维度print("transpose后的三维张量:", x_transpose)
得到如下结果。
transpose后的三维张量: tensor([[[-2.9029e-02, -1.9491e+00],[ 2.2509e+00, 4.8542e-01],[ 7.3283e-01, 5.6724e-01]],[[ 1.1965e+00, 5.6124e-02],[ 6.2344e-02, -1.3396e+00],[-1.7319e-01, 1.9378e-01]],[[-3.9400e-01, -5.7935e-01],[-9.6071e-01, -2.8746e-01],[ 1.6578e+00, 4.6559e-01]],[[ 1.7822e+00, -6.4085e-01],[-1.1714e+00, 1.5534e-03],[-2.2264e-01, -3.9514e-01]]])
shape变为shape(4, 3, 2)。