pytorch中的重塑和视图有什么区别?
pytorch
43
0

在numpy中,我们使用ndarray.reshape()重塑数组。

我注意到在pytorch中,人们出于相同的目的使用torch.view(...) ,但同时也存在一个torch.reshape(...)

所以我想知道它们之间有什么区别,什么时候应该使用它们中的任何一个?

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

Tensor.reshape()更健壮。它可以在任何张量上工作,而Tensor.view()仅在t.is_contiguous()==True张量tt.is_contiguous()==True

解释不连续和连续是另一回事,但始终可以通过调用t.contiguous()来使张量t连续,然后可以调用view()而不会出现错误。

收藏
评论

torch.view已经存在很长时间了。它将返回具有新形状的张量。返回的张量将与原始张量共享基础数据。请参阅此处文档

另一方面,似乎torch.reshape 最近已在版本0.4中引入 。根据文档 ,此方法将

返回具有与输入相同的数据和元素数量,但具有指定形状的张量。如果可能,返回的张量将是输入视图。否则,它将是副本。连续输入和具有兼容步幅的输入可以在不复制的情况下进行重塑,但是您不应该依赖复制与查看行为。

这意味着torch.reshape可能返回原始张量的副本或视图。您不能指望它返回视图或副本。根据开发商的说法:

如果需要复制,请使用clone();如果需要相同的存储,请使用view()。 reshape()的语义是它可能共享或可能不共享存储,并且您事先不知道。

另一个区别是reshape()可以在连续和非连续的张量上运行,而view()只能在连续的张量上运行。另请参见此处有关contiguous的含义。

收藏
评论

尽管torch.viewtorch.reshape都用于torch.reshape张量, torch.reshape是它们之间的区别。

  1. 顾名思义, torch.view仅创建原始张量的视图 。新的张量将始终与原始张量共享其数据。这意味着,如果您更改原始张量,则重塑的张量将更改,反之亦然。
>>> z = torch.zeros(3, 2)
>>> x = z.view(2, 3)
>>> z.fill_(1)
>>> x
tensor([[1., 1., 1.],
        [1., 1., 1.]])
  1. 为了确保新的张量始终共享其数据与原始, torch.view强加给两个张量[的形状有些连续性约束文档 。通常这不是一个问题,但是有时即使两个张量的形状兼容, torch.view引发错误。这是一个著名的反例。
>>> z = torch.zeros(3, 2)
>>> y = z.t()
>>> y.size()
torch.Size([2, 3])
>>> y.view(6)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: invalid argument 2: view size is not compatible with input tensor's
size and stride (at least one dimension spans across two contiguous subspaces).
Call .contiguous() before .view().
  1. torch.reshape不会施加任何连续性约束,但也不能保证数据共享。新张量可以是原始张量的视图,也可以是全新的张量。
>>> z = torch.zeros(3, 2)
>>> y = z.reshape(6)
>>> x = z.t().reshape(6)
>>> z.fill_(1)
tensor([[1., 1.],
        [1., 1.],
        [1., 1.]])
>>> y
tensor([1., 1., 1., 1., 1., 1.])
>>> x
tensor([0., 0., 0., 0., 0., 0.])

TL; DR:
如果只想重塑张量,请使用torch.reshape 。如果您还担心内存使用情况,并且要确保两个张量共享相同的数据,请使用torch.view

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题