Chociaż oba torch.view
i torch.reshape
są używane do zmiany kształtu tensorów, oto różnice między nimi.
- Jak sama nazwa wskazuje,
torch.view
tworzy jedynie widok oryginalnego tensora. Nowy tensor zawsze będzie udostępniać swoje dane oryginalnemu tensorowi. Oznacza to, że jeśli zmienisz oryginalny tensor, zmieniony tensor ulegnie zmianie i odwrotnie.
>>> z = torch.zeros(3, 2)
>>> x = z.view(2, 3)
>>> z.fill_(1)
>>> x
tensor([[1., 1., 1.],
[1., 1., 1.]])
- Aby upewnić się, że nowy tensor zawsze dzieli swoje dane z oryginałem,
torch.view
nakłada pewne ograniczenia ciągłości na kształty dwóch tensorów [ docs ]. Najczęściej nie jest to problemem, ale czasami torch.view
generuje błąd, nawet jeśli kształty dwóch tensorów są zgodne. Oto słynny kontrprzykład.
>>> 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
nie nakłada żadnych ograniczeń związanych z ciągłością, ale także nie gwarantuje udostępniania danych. Nowy tensor może być widokiem oryginalnego tensora lub może to być całkowicie nowy tensor.
>>> 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:
Jeśli chcesz tylko zmienić kształt tensorów, użyj torch.reshape
. Jeśli obawiasz się również użycia pamięci i chcesz mieć pewność, że te dwa tensory współużytkują te same dane, użyj torch.view
.