Bien que les deux torch.view
et torch.reshape
sont utilisés pour transformer les tenseurs, voici les différences entre eux.
- Comme son nom l'indique,
torch.view
crée simplement une vue de l'tenseur d'origine. Le nouveau tenseur sera toujours partager ses données avec le tenseur d'origine. Cela signifie que si vous modifiez le tenseur d'origine, une reconfiguration du tenseur de change et vice versa.
>>> z = torch.zeros(3, 2)
>>> x = z.view(2, 3)
>>> z.fill_(1)
>>> x
tensor([[1., 1., 1.],
[1., 1., 1.]])
- Pour s'assurer que le nouveau tenseur toujours partage ses données avec l'original,
torch.view
impose certaines contraintes de contiguïté sur les formes des deux tenseurs [docs]. Le plus souvent ce n'est pas un problème, mais parfois, torch.view
déclenche une erreur, même si les formes des deux tenseurs sont compatibles. Voici un célèbre contre-exemple.
>>> 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().
-
torch.reshape
n'impose pas la contiguïté des contraintes, mais aussi de ne pas garantir le partage des données. Le nouveau tenseur peut être une vue de l'tenseur d'origine, ou il peut être un nouveau tenseur complètement.
>>> 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:
Si vous voulez juste pour remodeler les tenseurs, utilisez torch.reshape
. Si vous êtes aussi préoccupé par l'utilisation de la mémoire et vous voulez vous assurer que les deux tenseurs de partager les mêmes données, utilisez torch.view
.