torch.view
ha existido durante mucho tiempo. Devolverá un tensor con la nueva forma. El tensor devuelto compartirá los datos subyacentes con el tensor original. Consulte la documentación aquí .
Por otro lado, parece que torch.reshape
se ha introducido recientemente en la versión 0.4 . Según el documento , este método
Devuelve un tensor con los mismos datos y número de elementos que la entrada, pero con la forma especificada. Cuando sea posible, el tensor devuelto será una vista de entrada. De lo contrario, será una copia. Las entradas contiguas y las entradas con pasos compatibles se pueden remodelar sin copiar, pero no debe depender del comportamiento de copia frente a visualización.
Significa que torch.reshape
puede devolver una copia o una vista del tensor original. No puedes contar con eso para devolver una vista o una copia. Según el desarrollador:
si necesita una copia, use clone () si necesita el mismo almacenamiento, use view (). La semántica de reshape () es que puede o no compartir el almacenamiento y usted no lo sabe de antemano.
Otra diferencia es que reshape()
puede operar tanto en tensor contiguo como no contiguo mientras view()
que solo puede operar en tensor contiguo. Vea también aquí el significado de contiguous
.
Aunque ambos
torch.view
ytorch.reshape
se utilizan para remodelar tensores, aquí están las diferencias entre ellos.torch.view
simplemente crea una vista del tensor original. El nuevo tensor siempre compartirá sus datos con el tensor original. Esto significa que si cambia el tensor original, el tensor remodelado cambiará y viceversa.>>> z = torch.zeros(3, 2) >>> x = z.view(2, 3) >>> z.fill_(1) >>> x tensor([[1., 1., 1.], [1., 1., 1.]])
torch.view
impone algunas restricciones de contigüidad en las formas de los dos tensores [ docs ]. La mayoría de las veces, esto no es un problema, pero a vecestorch.view
arroja un error incluso si las formas de los dos tensores son compatibles. He aquí un famoso contraejemplo.>>> 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
no impone restricciones de contigüidad, pero tampoco garantiza el intercambio de datos. El nuevo tensor puede ser una vista del tensor original o puede ser un nuevo tensor por completo.>>> 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 solo desea remodelar tensores, use
torch.reshape
. Si también le preocupa el uso de la memoria y desea asegurarse de que los dos tensores compartan los mismos datos, utilicetorch.view
.fuente
x
yy
superior son ambos contiguos). ¿Quizás esto pueda aclararse? ¿Quizás un comentario sobre cuándo la remodelación hace y no copia sería útil?Tensor.reshape()
es más robusto. Funcionará en cualquier tensor, mientras queTensor.view()
solo funcionará en el tensort
dondet.is_contiguous()==True
.Explicar sobre no contiguo y contiguo es otra historia de tiempo, pero siempre puede hacer que el tensor sea
t
contiguo si llamat.contiguous()
y luego puede llamarview()
sin el error.fuente