简介在PyTorch中view、reshape、permute和transpose都是用于改变张量Tensor形状或维度的操作但它们的实现机制、使用限制和底层原理存在关键区别。下面我将为你详细解析它们的功能、区别与联系。接口主要功能核心特点view改变张量形状返回新张量与原张量共享内存要求张量在内存中是连续的。reshape改变张量形状功能与view类似但更灵活能处理非连续张量。permute重排所有维度顺序返回新张量交换维度不改变元素总数。transpose交换两个指定维度permute的特例专门用于交换两个维度。实例1、view与reshape创建一个 2×3 的张量importtorch xtorch.arange(6).reshape(2,3)print(x)print(x.shape)输出tensor([[0,1,2],[3,4,5]])torch.Size([2,3])view改变形状y_viewx.view(6)print(y_view)输出tensor([0,1,2,3,4,5])transpose交换两个指定维度会使张量在内存中变得不在连续y_transposex.transpose(0,1)print(y_transpose)print(y_transpose.is_contiguous())输出由原始的23变为32tensor([[0,3],[1,4],[2,5]])False直接对x_transpose使用view会报错因为view只能处理在内存中连续的张量y_transpose_viewy_transpose.view(6)print(y_transpose_view)输出RuntimeError: view size is not compatible with input tensors size and stride(at least one dimension spans across two contiguous subspaces). Use .reshape(...)instead.必须先使用contiguous()把张量变为连续y_transpose_viewy_transpose.contiguous().view(6)print(y_transpose_view)输出tensor([0,3,1,4,2,5])reshape会自动处理不连续的情况y_reshapey_transpose.reshape(6)print(y_reshape)输出tensor([0,3,1,4,2,5])2、permute和transpose创建出一个三维张量importtorch ztorch.randn(2,3,4)print(z.shape)输出torch.Size([2,3,4])transpose:交换最后两个维度z_transposez.transpose(1,2)print(f交换维度后的形状{z_transpose.shape})输出原来的形状是[2, 3, 4]​ 0,1,2 交换1和2 也就是 [2, 4, 3]交换维度后的形状torch.Size([2,4,3])permute将维度顺序完全颠倒z_permutez.permute(2,1,0)print(f重排维度后的形状{z_permute.shape})输出原来的形状是[2, 3, 4]​ 0,1,2 维度变为 2,1,0 也就变为[4, 3, 2]如果permute(2,0,1) 则是 [4, 2, 3]重排维度后的形状torch.Size([4,3,2])对比viewvsreshape: 改变形状这两个方法都用于改变张量的“外观”形状而不改变其内部元素的总数。view工作原理它只是创建了一个指向原始数据的新“视图”不会复制数据。因此修改view返回的张量也会影响原始张量。关键限制它要求原始张量在内存中是**连续存储contiguous**的。如果你对张量进行了transpose或permute等操作它在内存中的存储顺序会变得不连续此时直接调用view会报错。解决方法在不连续的张量上调用view前必须先调用.contiguous()方法使其在内存中变为连续。reshape工作原理它是view的一个更“智能”和“宽容”的版本。如果原始张量是连续的reshape的行为和view完全一样共享内存。如果张量不连续reshape会自动复制数据创建一个新的连续张量并返回。优点使用更方便不用担心连续性问题。缺点由于可能触发数据复制在某些情况下性能开销会比view稍大。一句话总结在确定张量是连续的情况下优先使用view如果不确定或想图省事就用reshape。permutevstranspose: 交换维度这两个方法都用于改变张量的维度顺序而不是改变形状本身。permute功能可以对张量的所有维度进行任意顺序的重排。你需要传入一个包含所有维度索引的元组。示例一个形状为(C, H, W)的图像张量如果想变为(H, W, C)就需要使用tensor.permute(1, 2, 0)。transpose功能是permute的一个特例专门用于交换两个指定的维度。示例一个形状为(N, C)的二维矩阵进行转置操作tensor.transpose(0, 1)后形状变为(C, N)。对于二维张量transpose(0, 1)和permute(1, 0)的效果是完全一样的。一句话总结当只需要交换两个维度时使用transpose更直观当需要重排多个维度时必须使用permute。核心区别与联系功能目的不同view/reshape用于改变形状例如将[2, 3]变为[6]。permute/transpose用于改变维度顺序例如将[2, 3]变为[3, 2]。内存连续性要求不同view对内存连续性有严格要求。reshape、permute和transpose通常不要求张量是连续的reshape会自动处理permute/transpose会返回一个非连续的新视图。联系reshape可以看作是view的“超集”功能上包含了view。transpose是permute在二维情况下的特例。一个常见的组合操作是先使用permute或transpose交换维度然后调用.contiguous()最后使用view来改变形状。完整代码importtorch# view 与 reshapextorch.arange(6).reshape(2,3)print(x)print(x.shape)y_viewx.view(6)print(y_view)y_transposex.transpose(0,1)print(y_transpose)print(y_transpose.is_contiguous())y_transpose_viewy_transpose.contiguous().view(6)print(y_transpose_view)y_reshapey_transpose.reshape(6)print(y_reshape)# permute 与 transposeztorch.randn(2,3,4)print(z.shape)z_transposez.transpose(1,2)print(f交换维度后的形状{z_transpose.shape})z_permutez.permute(2,1,0)print(f重排维度后的形状{z_permute.shape})