torch.view
existiert schon lange. Es wird ein Tensor mit der neuen Form zurückgegeben. Der zurückgegebene Tensor teilt die zugrunde liegenden Daten mit dem ursprünglichen Tensor. Siehe die Dokumentation hier .
Andererseits scheint es, dass torch.reshape
es kürzlich in Version 0.4 eingeführt wurde . Laut dem Dokument wird diese Methode
Gibt einen Tensor mit denselben Daten und der gleichen Anzahl von Elementen wie die Eingabe zurück, jedoch mit der angegebenen Form. Wenn möglich, ist der zurückgegebene Tensor eine Ansicht der Eingabe. Andernfalls handelt es sich um eine Kopie. Aneinandergrenzende Eingaben und Eingaben mit kompatiblen Schritten können ohne Kopieren umgeformt werden, Sie sollten sich jedoch nicht auf das Kopier- oder Anzeigeverhalten verlassen.
Dies bedeutet, dass torch.reshape
möglicherweise eine Kopie oder eine Ansicht des ursprünglichen Tensors zurückgegeben wird. Darauf können Sie nicht zählen, um eine Ansicht oder eine Kopie zurückzugeben. Nach Angaben des Entwicklers:
Wenn Sie eine Kopie benötigen, verwenden Sie clone (), wenn Sie dieselbe Speicheranwendungsansicht () benötigen. Die Semantik von reshape () ist, dass es den Speicher gemeinsam nutzen kann oder nicht und Sie es vorher nicht wissen.
Ein weiterer Unterschied besteht darin, dass reshape()
sowohl mit zusammenhängenden als auch mit nicht zusammenhängenden Tensoren gearbeitet werden view()
kann, während nur mit zusammenhängenden Tensoren gearbeitet werden kann. Siehe auch hier über die Bedeutung von contiguous
.
Obwohl beide
torch.view
undtorch.reshape
zur Umformung von Tensoren verwendet werden, sind hier die Unterschiede zwischen ihnen.torch.view
lediglich eine Ansicht des ursprünglichen Tensors erstellt. Der neue Tensor wird immer seine Daten mit der Original - Tensor teilen. Dies bedeutet, dass sich der umgeformte Tensor ändert, wenn Sie den ursprünglichen Tensor ändern, und umgekehrt.>>> z = torch.zeros(3, 2) >>> x = z.view(2, 3) >>> z.fill_(1) >>> x tensor([[1., 1., 1.], [1., 1., 1.]])
torch.view
den Formen der beiden Tensoren einige Kontiguitätsbeschränkungen auferlegt [ docs ]. Meistens ist dies kein Problem,torch.view
wirft aber manchmal einen Fehler aus, selbst wenn die Formen der beiden Tensoren kompatibel sind. Hier ist ein berühmtes Gegenbeispiel.>>> 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
legt keine Kontiguitätsbeschränkungen fest, garantiert aber auch nicht den Datenaustausch. Der neue Tensor kann eine Ansicht des ursprünglichen Tensors sein, oder er kann insgesamt ein neuer Tensor sein.>>> 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:
Wenn Sie nur Tensoren umformen möchten, verwenden Sie
torch.reshape
. Wenn Sie auch Bedenken hinsichtlich der Speichernutzung haben und sicherstellen möchten, dass die beiden Tensoren dieselben Daten verwenden, verwenden Sietorch.view
.quelle
x
undy
oben sind beide zusammenhängend). Vielleicht kann das geklärt werden? Vielleicht wäre ein Kommentar dazu hilfreich, wann eine Umformung kopiert und wann nicht?Tensor.reshape()
ist robuster. Es funktioniert auf jedem Tensor, während esTensor.view()
nur auf Tensor funktioniert,t
wot.is_contiguous()==True
.Nicht zusammenhängend und zusammenhängend zu erklären, ist eine andere Zeitgeschichte, aber Sie können den Tensor immer zusammenhängend machen, wenn
t
Sie anrufen,t.contiguous()
und dann können Sieview()
ohne Fehler anrufen .quelle