torch中 contiguous(), .view(), .reshape(), .permute(), .transpose()的区别与联系

文章详细介绍了PyTorch中张量的数据存储结构,包括张量的头信息和实际存储空间。讨论了张量的连续性,如何通过is_contiguous方法检查,并解释了.view()和.reshape()的区别,以及它们如何影响内存。同时,提到了.permute()和.transpose()的作用,它们改变数据的观察角度但不创建新副本。最后,文章总结了这些操作在处理张量时的适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、张量的数据存储

  • 在pytorch中,张量的存储实际上分为两个部分,一部分是张量的头信息,包括张量的shape,stride等。另一部分就是张量数据的实际存储空间,可以使用张量.storage() 方法来得到张量存储的数据,sorage() 是在data之上封装的一个接口。

2、张量的连续性:contiguous

  • 我们可以通过张量的is_contiguous()方法来判断张量是否连续。
  • is_contiguous直观的解释是Tensor底层一维数组元素的存储顺序与Tensor按行优先一维展开的元素顺序是否一致。

3、.view() 和 .reshape()

  • view() 只能对连续张量进行,其实质是将张量先展开成一维,然后再按照给定的shape进行排列,view()不会创建新的内存空间,我们可以理解为view() 是在原始数据上修改了张量的头文件,所以view() 其实是对张量的浅拷贝(这里把张量数据的存储相当于列表中的列表)

  • reshape() = view() 或者 contiguous() + view(),reshape可以作用于非连续的张量,其本质是先进行contiguous,再执行view。当张量是连续的时候reshape = view,也就是产生的还是浅拷贝,但是如果是不连续的张量,则reshape() = contiguous() + view(),而contiguous是对数据按照其shape进行深拷贝,此时reshape前后的张量不再共享内存中的数据。

4、.permute() 和 .transpose()

  • 可以理解为,没有改变张量的结构,只是改变了我们观察张量的角度,比如一个1224的图,转置以后变成2412,整个图片是没有改变的,只是改变了我们观察的角度

  • permute()和transpose() 也是浅拷贝,只改变张量的头元信息,而与原张量共享数据,但是通过这两者操作之后的张量不再满足连续性,因为此时张量在内存中的存储位置是没有变化的,但是张量头文件中的stride,shape发生了变化,使得张量按行展开以后不再与其在内存中的存储顺序一样了。所以这个时候只能先使用contiguous对转置后的数据进行深拷贝,并按照转置后的stride在内存中对数据进行重排。变成连续的,之后才可以使用view()

5、总结

  • permute()和transpose()是按照张量的数组坐标进行转置的,可以理解为我们只是换个角度观察张量,再换一种理解,张量中的维度实际上是数据排列的先后顺序,我们换维度,也就是换数据排列的先后顺序。
  • 😄感觉一般用reshape就好了,反正它等于.contiguous()+.view(),省事







参考链接:https://blog.csdn.net/xx_xjm/article/details/123301266

<think>好的,我现在需要理解用户的问题:“torch.transpose是怎么操作的”。用户之前问过一个关于多维数组的例子,特别是倒数第三维是2的情况,现在转向了PyTorch中的transpose函数。这说明用户可能在处理张量维度变换,可能在深度学习或数据处理中遇到了需要调整维度的情况。 首先,我需要回顾transpose的基本概念。在PyTorch中,transpose函数是用来交换张量的两个维度的。用户可能已经知道一些基础的维度操作,比如viewpermute,但transpose是更直接的交换两个轴。我需要明确transpose的输入参数和输出结果。 接下来,我需要确认transpose的用法。函数签名通常是torch.transpose(input, dim0, dim1),其中dim0和dim1是要交换的两个维度索引。这里的维度索引可以是正数,也可以是负数,表示从后往前数。例如,对于一个三维张量,dim0=0和dim1=2,或者dim0=-3和dim1=-1,效果是一样的。需要提醒用户注意索引的有效性,避免越界。 然后,我应该用一个具体的例子来说明。比如,假设有一个形状为(2,3,4)的三维张量,交换第0维和第2维后,形状变为(4,3,2)。需要详细解释每个维度是如何变化的,可能通过具体数值来展示变换前后的结构变化。这样用户能更直观地理解。 另外,用户之前的提问中涉及到了倒数第三维,可能对负数索引比较关注。需要特别说明transpose也支持负数索引,例如在四维张量中,交换-3和-1维的效果。这时候需要结合之前的例子,确保用户能正确应用在实际情况中。 还需要注意transposepermute区别transpose只能交换两个维度,而permute可以重新排列所有维度。用户可能混淆这两者,所以需要简单比较,指出各自的适用场景。例如,transpose适合快速交换两个轴,而permute适合复杂的多维度重排。 另外,要提到transpose之后的内存布局问题。转置操作后的张量可能不再是连续的,这可能会影响后续操作,如视图(view)会报错。这时候需要建议在必要时使用contiguous()方法,使张量内存连续。 用户可能的误区包括:认为transpose会改变原张量(其实不会,返回新张量),或者对维度索引的理解有误。需要明确指出这些点,避免用户犯错。 最后,总结transpose的关键点:交换指定维度,支持正负索引,不改变原张量,可能导致内存不连续。可能还需要给出一个实际应用的例子,比如在处理图像数据时,通道位置的调整(如HWC转CHW)可能需要用到transpose。 现在,我需要组织这些思考点,用清晰的结构和例子来回答用户的问题,确保涵盖函数用法、示例、索引说明、注意事项以及其他函数的对比,帮助用户全面理解transpose的操作。</think>在PyTorch中,`torch.transpose` 是用于交换张量两个维度的操作。我们通过具体示例说明其工作机制: --- ### **核心操作** 函数签名: ```python torch.transpose(input, dim0, dim1) → Tensor ``` - **`dim0`** 和 **`dim1`** 是要交换的两个维度索引(支持正负索引) - **输出**:交换后的新张量(原张量不改变) --- ### **示例说明** #### **示例1:三维张量交换维度** 假设原始张量形状为 `(2, 3, 4)`: ```python import torch x = torch.arange(24).reshape(2, 3, 4) # 形状 [2,3,4] y = torch.transpose(x, 0, 2) # 交换第0维和第2维 ``` 变换过程: ``` 原维度顺序:dim0=0 → 2个块 dim1=1 → 3行 dim2=2 → 4列 交换后维度顺序:dim0=2 → 4个块 dim1=1 → 3行(未变) dim2=0 → 2列 最终形状变为 [4, 3, 2] ``` #### **数值验证**: ```python print("原始张量形状:", x.shape) # torch.Size([2, 3, 4]) print("转置后形状:", y.shape) # torch.Size([4, 3, 2]) # 验证特定位置数据: print("原始x[1, 2, 3] =", x[1, 2, 3].item()) # 23 print("转置y[3, 2, 1] =", y[3, 2, 1].item()) # 23(值跟随维度交换) ``` --- ### **关键特性** 1. **负数索引支持**: ```python # 对形状 [5,3,2,4] 的四维张量 z = torch.transpose(tensor, -3, -1) # 交换倒数第三维和最后一维 ``` 2. **内存连续性**: ```python y = x.transpose(0, 1) y.is_contiguous() # 可能返回False y = y.contiguous() # 使其内存连续 ``` 3. **permute区别**: ```python # transpose只能交换两个维度 x.transpose(0, 1) # 交换第0维和第1维 # permute可自由排列所有维度 x.permute(2, 0, 1) # 新维度顺序为原第2维→第0维,第0维→第1维,第1维→第2维 ``` --- ### **典型应用场景** 1. **图像通道转换**: ```python # 将形状 [H, W, C] 转换为 [C, H, W] image = torch.randn(224, 224, 3) # HWC格式 image = image.transpose(0, 2).transpose(1, 2) # 先交换0-2得[C,W,H],再交换1-2得[C,H,W] ``` 2. **矩阵转置**: ```python matrix = torch.tensor([[1, 2], [3, 4]]) matrix.T == matrix.transpose(0, 1) # 等价操作 ``` --- ### **注意事项** - **维度索引有效性**:索引值需满足 `-dim <= idx < dim` - **视图操作限制**:转置后若需要调用 `view()`,需先执行 `contiguous()` - **广播机制影响**:转置可能改变广播规则的行为 通过这种方式,`torch.transpose` 可以高效地调整张量的维度布局,适用于各种需要维度变换的深度学习任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

#苦行僧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值