Jaja TTpro
Quiero remodelar un vector de forma. (5,)
en una matriz de forma (1, 5)
.
Con numpy, puedo hacer:
>>> import numpy as np
>>> a = np.array([1, 2, 3, 4, 5])
>>> a.shape
(5,)
>>> a = np.reshape(a, (1, 5))
>>> a.shape
(1, 5)
>>> a
array([[1, 2, 3, 4, 5]])
Pero, ¿cómo hago esto con PyTorch?
Jaja TTpro
Usar torch.unsqueeze(input, dim, out=None)
:
>>> import torch
>>> a = torch.Tensor([1, 2, 3, 4, 5])
>>> a
1
2
3
4
5
[torch.FloatTensor of size 5]
>>> a = a.unsqueeze(0)
>>> a
1 2 3 4 5
[torch.FloatTensor of size 1x5]
podrías usar
a.view(1,5)
Out:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
-
Tenga en cuenta que esto no es modificar el tensor original
a
. Simplemente crea una vista.– kmario23
6 de diciembre de 2017 a las 5:37
stackoverflowuser2010
Hay varias formas de remodelar un tensor de PyTorch. Puede aplicar estos métodos en un tensor de cualquier dimensionalidad.
Vamos a empezar con un bidimensional 2 x 3
tensor:
x = torch.Tensor(2, 3)
print(x.shape)
# torch.Size([2, 3])
Para agregar algo de robustez a este problema, remodelemos el 2 x 3
tensor agregando una nueva dimensión en el frente y otra dimensión en el medio, produciendo un 1 x 2 x 1 x 3
tensor.
Enfoque 1: agregar dimensión con None
Usa el estilo NumPy inserción de None
(también conocido como np.newaxis
) para agregar dimensiones donde quieras. Ver aquí.
print(x.shape)
# torch.Size([2, 3])
y = x[None, :, None, :] # Add new dimensions at positions 0 and 2.
print(y.shape)
# torch.Size([1, 2, 1, 3])
Enfoque 2: descomprimir
Usar torch.Tensor.unsqueeze(i)
(también conocido como torch.unsqueeze(tensor, i)
o la versión in situ unsqueeze_()
) para agregar una nueva dimensión en la i-ésima dimensión. El tensor devuelto comparte los mismos datos que el tensor original. En este ejemplo, podemos usar unqueeze()
dos veces para sumar las dos nuevas dimensiones.
print(x.shape)
# torch.Size([2, 3])
# Use unsqueeze twice.
y = x.unsqueeze(0) # Add new dimension at position 0
print(y.shape)
# torch.Size([1, 2, 3])
y = y.unsqueeze(2) # Add new dimension at position 2
print(y.shape)
# torch.Size([1, 2, 1, 3])
En la práctica con PyTorch, agregar una dimensión adicional para el lote puede ser importante, por lo que a menudo puede ver unsqueeze(0)
.
Enfoque 3: ver
Usar torch.Tensor.view(*shape)
para especificar todas las dimensiones. El tensor devuelto comparte los mismos datos que el tensor original.
print(x.shape)
# torch.Size([2, 3])
y = x.view(1, 2, 1, 3)
print(y.shape)
# torch.Size([1, 2, 1, 3])
Enfoque 4: reformar
Usar torch.Tensor.reshape(*shape)
(también conocido como torch.reshape(tensor, shapetuple)
) para especificar todas las dimensiones. Si los datos originales son contiguos y tienen el mismo paso, el tensor devuelto será una vista de entrada (que comparte los mismos datos); de lo contrario, será una copia. Esta función es similar a la NumPy reshape()
función que le permite definir todas las dimensiones y puede devolver una vista o una copia.
print(x.shape)
# torch.Size([2, 3])
y = x.reshape(1, 2, 1, 3)
print(y.shape)
# torch.Size([1, 2, 1, 3])
Además, del libro O’Reilly 2019 Programación de PyTorch para aprendizaje profundoel autor escribe:
Ahora te preguntarás cuál es la diferencia entre view()
y reshape()
. la respuesta es que view()
opera como una vista en el tensor original, por lo que si se cambian los datos subyacentes, la vista también cambiará (y viceversa). Sin embargo, view()
puede arrojar errores si la vista requerida no es contigua; es decir, no comparte el mismo bloque de memoria que ocuparía si se creara desde cero un nuevo tensor de la forma requerida. Si esto sucede, usted tiene que llamar tensor.contiguous()
antes de que puedas usar view()
. Sin embargo, reshape()
hace todo eso entre bastidores, por lo que, en general, recomiendo usar reshape()
más bien que view()
.
Enfoque 5: redimensionar_
Usar la función en el lugar torch.Tensor.resize_(*sizes)
para modificar el tensor original. La documentación dice:
ADVERTENCIA. Este es un método de bajo nivel. El almacenamiento se reinterpreta como C-contiguo, ignorando los pasos actuales (a menos que el tamaño objetivo sea igual al tamaño actual, en cuyo caso el tensor no se modifica). Para la mayoría de los propósitos, querrá usar view()
que verifica la contigüidad, o reshape()
, que copia los datos si es necesario. Para cambiar el tamaño en el lugar con pasos personalizados, consulte set_()
.
print(x.shape)
# torch.Size([2, 3])
x.resize_(1, 2, 1, 3)
print(x.shape)
# torch.Size([1, 2, 1, 3])
mis observaciones
Si desea agregar solo una dimensión (por ejemplo, para agregar una dimensión 0 para el lote), use unsqueeze(0)
. Si quieres cambiar totalmente la dimensionalidad, usa reshape()
.
Ver también:
¿Cuál es la diferencia entre remodelar y ver en pytorch?
¿Cuál es la diferencia entre view() y unsqueeze()?
En PyTorch 0.4, se recomienda usar reshape
que view
¿cuando sea posible?
kmario23
Para en su lugar modificación de la forma del tensor, debe utilizar
tensor.resize_()
:
In [23]: a = torch.Tensor([1, 2, 3, 4, 5])
In [24]: a.shape
Out[24]: torch.Size([5])
# tensor.resize_((`new_shape`))
In [25]: a.resize_((1,5))
Out[25]:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
In [26]: a.shape
Out[26]: torch.Size([1, 5])
En PyTorch, si hay un guión bajo al final de una operación (como tensor.resize_()
) entonces esa operación hace in-place
modificación del tensor original.
Además, simplemente puede usar np.newaxis
en un soplete Tensor para aumentar la dimensión. Aquí hay un ejemplo:
In [34]: list_ = range(5)
In [35]: a = torch.Tensor(list_)
In [36]: a.shape
Out[36]: torch.Size([5])
In [37]: new_a = a[np.newaxis, :]
In [38]: new_a.shape
Out[38]: torch.Size([1, 5])
o puede usar esto, el ‘-1’ significa que no tiene que especificar el número de elementos.
In [3]: a.view(1,-1)
Out[3]:
1 2 3 4 5
[torch.FloatTensor of size 1x5]
saetch_g
Esta pregunta ya ha sido respondida a fondo, pero quiero agregar para los desarrolladores de python menos experimentados que pueden encontrar la *
operador útil junto con view()
.
Por ejemplo, si tiene un tamaño de tensor particular al que desea que se ajuste un tensor de datos diferente, puede intentar:
img = Variable(tensor.randn(20,30,3)) # tensor with goal shape
flat_size = 20*30*3
X = Variable(tensor.randn(50, flat_size)) # data tensor
X = X.view(-1, *img.size()) # sweet maneuver
print(X.size()) # size is (50, 20, 30, 3)
Esto funciona con numpy shape
también:
img = np.random.randn(20,30,3)
flat_size = 20*30*3
X = Variable(tensor.randn(50, flat_size))
X = X.view(-1, *img.shape)
print(X.size()) # size is (50, 20, 30, 3)
prosti
antorcha.reformar() está hecho para engañar al remodelar numpy método.
Llegó después de la vista() y antorcha.resize_() y esta dentro del dir(torch)
paquete.
import torch
x=torch.arange(24)
print(x, x.shape)
x_view = x.view(1,2,3,4) # works on is_contiguous() tensor
print(x_view.shape)
x_reshaped = x.reshape(1,2,3,4) # works on any tensor
print(x_reshaped.shape)
x_reshaped2 = torch.reshape(x_reshaped, (-1,)) # part of torch package, while view() and resize_() are not
print(x_reshaped2.shape)
Afuera:
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, 19, 20, 21, 22, 23]) torch.Size([24])
torch.Size([1, 2, 3, 4])
torch.Size([1, 2, 3, 4])
torch.Size([24])
Pero, ¿sabía que también puede funcionar como reemplazo de estrujar() y descomprimir()
x = torch.tensor([1, 2, 3, 4])
print(x.shape)
x1 = torch.unsqueeze(x, 0)
print(x1.shape)
x2 = torch.unsqueeze(x1, 1)
print(x2.shape)
x3=x.reshape(1,1,4)
print(x3.shape)
x4=x.reshape(4)
print(x4.shape)
x5=x3.squeeze()
print(x5.shape)
Afuera:
torch.Size([4])
torch.Size([1, 4])
torch.Size([1, 1, 4])
torch.Size([1, 1, 4])
torch.Size([4])
torch.Size([4])