reshape 和 view 方法有什么区别,为什么我们需要,我正在使用 pytorch 张量并致力于改变数据的形状,然后我开始了解这两个函数。如果我们使用较少的资源处理大数据,那么对内存的影响是什么?哪些消耗更多的内存,哪些成本更高。
x = torch.tensor([1, 2, 3, 4, 5], dtype = torch.float32)
x = x.reshape(-1, 1)
以及查看方法
x = x.view(x.shape[0], 1)
有什么区别以及我应该使用哪个
简短的回答:当重塑连续张量时,两种方法都会执行相同的操作(即提供给定张量的新视图),因此可以互换使用。当重塑非连续张量时,
reshape()
将从给定张量复制必要的内存部分以生成结果张量,而view()
将失败并出现RuntimeError
。
torch.Tensor.reshape()
和 torch.Tensor.view()
如何处理非连续张量。
要理解差异,我们需要了解什么是连续张量,以及什么是张量的视图:
现在回到这两种方法:
reshape()
和view()
都会生成给定张量内存的新视图,这样就避免了重复。reshape()
方法将复制必要的内存并返回一个张量,其内存不会与给定的张量共享。view()
方法将产生一个RuntimeError
。我们可以用下面的代码来演示这一点:
from torch import arange
contiguous = arange(16).view(4, 4) # Create contiguous 4×4 tensor
noncontiguous = arange(20).view(4, 5)[:, :4] # Create non-contiguous 4×4 tensor
contiguous_r = contiguous.reshape(16) # OK: produces a 1-d view
assert contiguous_r.data_ptr() == contiguous.data_ptr() # Same memory used
contiguous_v = contiguous.view(16) # OK: produces a 1-d view
assert contiguous_v.data_ptr() == contiguous.data_ptr() # Same memory used
noncontiguous_r = noncontiguous.reshape(16) # OK: produces a new 1-d array
assert noncontiguous_r.data_ptr() != noncontiguous.data_ptr() # New memory used
noncontiguous_v = noncontiguous.view(16) # ERROR: cannot produce view
最后一行将产生 RuntimeError:视图大小与输入张量的大小和步幅不兼容(至少一个维度跨越两个连续的子空间)。使用 .reshape(...) 代替。
也许在这一点上,我还应该提到张量的 stride 是什么:本质上,它是告诉我们如何将张量的索引映射到其底层内存的信息。您将找到有关步幅的更多信息,以及有关连续张量与非连续张量的一般信息,例如,在 PyTorch 论坛的此讨论中。
至于你的问题,我应该使用哪个?:
reshape()
:对于连续张量,reshape()
将执行与view()
完全相同的操作(即,生成关于给定的张量并且不复制其内存)。对于非连续张量,reshape()
将是唯一能产生结果的方法,而view()
将失败(见上文)。view()
。例如,如果您在内存不足的情况下工作,因此宁愿失败也不愿复制内存,这可能是有意义的。 view()
的另一个用例不是重新解释形状,而是重新解释底层内存的数据类型。我想这不是您的用例,但您可以在我上面链接的 view()
文档中找到更多相关信息。