5 Funciones Tensoriales Útiles para PyTorch

Últimamente, PyTorch ha ganado mucha popularidad entre la comunidad de ciencia de datos, como una de las bibliotecas de Deep Learning más utilizadas. Esta biblioteca se basa en tensores, que pueden entenderse como una matriz de n dimensiones a partir de la cual se pueden realizar operaciones matemáticas y construir modelos de aprendizaje profundo. En este artículo, vamos a presentar cinco funciones tensoriales útiles que puedes utilizar en PyTorch.

torch.Tensor.expand(*sizes)
Esta función permite establecer la cantidad de elementos por dimensión.
x = torch.tensor([[1], [2], [3]]) # Creamos un tensor de 2 dimensiones con 3 filas y 1 columna
print(x.size())
print(x.expand(3, 4)) # Para los argumentos de la función de expansión, utilizamos la misma longitud para la primera dimensión (3), y aumentamos la segunda dimensión de 1 a 4
torch.Size([3, 1]) tensor([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]])
Aquí, creamos un tensor «x» con 3 filas y 1 columna. Luego, aplicamos a nuestro tensor la función expand() para aumentar su número de columnas a 4. Como puedes ver, las columnas se replicaron 3 veces.
print(x.expand(-1, 4)) # -1 significa no cambiar el tamaño de esa dimensión
tensor([[1, 1, 1, 1], [2, 2, 2, 2], [3, 3, 3, 3]])
Este ejemplo proporciona el mismo resultado, pero en lugar de usar «3» como primer argumento, usamos «-1», que calcula el tamaño original de esa dimensión.
print(x.expand(3, 4, 7))
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-13-0d5b196f7923> in <module>() ----> 1 print(x.expand(3, 4, 7)) RuntimeError: The expanded size of the tensor (4) must match the existing size (3) at non-singleton dimension 1. Target sizes: [3, 4, 7]. Tensor sizes: [3, 1]
Aquí podemos ver lo que sucede cuando intentamos agregar más dimensiones al tensor desde el método de expansión. Recibimos un error porque eso no se puede hacer usando ese método.
Esta función es muy útil cuando desea remodelar un tensor para hacerlo compatible con otros tensores para operaciones aritméticas. Dos tensores son compatibles cuando para cada par de dimensiones son iguales.
torch.reshape(input, shape)
Esta función devuelve un tensor con los mismos datos y número de elementos que la entrada, pero con la forma especificada. Una sola dimensión puede ser -1, en cuyo caso se infiere a partir de las dimensiones restantes y el número de elementos de entrada.
In [14]:
a = torch.arange(4.) # tensor de 1 dimensión
print(a)
torch.reshape(a, (2, 2)) # remodelar a un tensor de 2 dimensiones
tensor([0., 1., 2., 3.])
Out[14]:
tensor([[0., 1.], [2., 3.]])
Aquí, hemos creado un tensor de 1 dimensión con 4 elementos. Luego usamos la función reshape para convertirlo en un tensor de 2 dimensiones, con 2 filas y 2 columnas.
In [15]:
b = torch.tensor([[0, 1], [2, 3]]) # Tensor de 2 dimensiones
print(b)
torch.reshape(b, (-1,)) # Remodelar a tensor de 1 dimensión
tensor([[0, 1], [2, 3]])
Out[15]:
tensor([0, 1, 2, 3])
En este ejemplo, hemos creado un tensor de 2 dimensiones con 4 elementos. A continuación, utilizamos la función de remodelación para convertirlo en un tensor de 1 dimensión.
In [16]:
a = torch.arange(4.) # tensor de 1 dimensión
print(a)
torch.reshape(a, (2, 3)) # Utilizamos la función reshape con una forma no válida
tensor([0., 1., 2., 3.])
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-16-456a28a19a6c> in <module>()
1 a = torch.arange(4.) # 1-dimension tensor
2 print(a)
----> 3 torch.reshape(a, (2, 3)) # Utilizamos la función reshape con una forma no válida
RuntimeError: shape '[2, 3]' is invalid for input of size 4
Si utilizas una forma incompatible con la cantidad de elementos del tensor, obtendrás un error como éste.
Al igual que la función anterior, ésta es muy útil cuando se desea remodelar un tensor para hacerlo compatible con otros tensores para operaciones aritméticas.
torch.add(input, other, alpha=1, out=None)
Añade otro (puede ser un escalar o un tensor) a cada elemento del tensor de entrada y devuelve un nuevo tensor resultante.
Cuando alpha está establecido, funciona como multiplicador escalar para other.
In [17]:
a = torch.randn(4) # tensor de 1 dimensión
print(a)
torch.add(a, 20)
tensor([-0.1182, -0.1796, 1.7664, 0.4416])
Out[17]:
tensor([19.8818, 19.8204, 21.7664, 20.4416])
En este caso, estamos añadiendo un escalar (20) al tensor utilizando la función add().
In [18]:
a = torch.randn(4) print(a) b = torch.randn(4, 1) print(b) torch.add(a, b, alpha=10)
tensor([-0.6033, 1.4754, 0.4251, 2.3262]) tensor([[ 0.6813], [-0.0768], [-1.0175], [ 0.1177]])
Out[18]:
tensor([[ 6.2099, 8.2886, 7.2383, 9.1393], [ -1.3715, 0.7072, -0.3431, 1.5580], [-10.7783, -8.6996, -9.7499, -7.8489], [ 0.5734, 2.6521, 1.6018, 3.5028]])
En este ejemplo, estamos sumando el tensor a con el producto del escalar alfa por el tensor b.
In [19]:
a = torch.randn(4)
print(a)
torch.add(a, (20, 25, 30, 35)) # No se puede añadir un tensor con una tupla
tensor([ 1.1978, 0.6394, -1.5532, -1.4733])
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-19-33cc2e2ea12f> in <module>() 2 print(a) 3 ----> 4 torch.add(a, (20, 25, 30, 35)) # You can not add a tensor with a tuple TypeError: add(): argument 'other' (position 2) must be Tensor, not tuple
Cuando realices operaciones aritméticas con tensores, asegúrate de hacerlo con escalares o tensores. En este caso, podemos ver que obtenemos un error cuando intentamos sumar un tensor con una tupla.
Esta es una de las funciones que utilizaremos cuando queramos hacer operaciones aritméticas sobre tensores.
torch.t(input)
Espera que la entrada sea <= tensor 2-D y transpone las dimensiones 0 y 1.
Los tensores 0-D y 1-D se devuelven tal cual. Cuando la entrada es un tensor 2D, esto es equivalente a transponer(entrada, 0, 1).
In [20]:
x = torch.randn(()) # aquí, creamos un tensor de dimensión 0
print(x)
torch.t(x) # obtener la transposición del tensor
tensor(0.5451)
Out[20]:
tensor(0.5451)
Cuando se obtiene la transposición de un tensor de dimensión 0, se obtiene el mismo tensor.
In [21]:
x = torch.randn((3)) # aquí, creamos un tensor de 1 dimensión
print(x)
torch.t(x)
tensor([-0.3837, -0.9967, -0.2112])
Out[21]:
tensor([-0.3837, -0.9967, -0.2112])
Cuando se obtiene la transposición de un tensor de 1 dimensión, se obtiene el mismo tensor.
In [22]:
x = torch.randn(2, 3) # Creamos un tensor con 2 filas y 3 columnas, y lo rellenamos con valores aleatorios
print(x)
torch.t(x)
tensor([[ 0.9592, 0.4125, 1.0104], [-0.3084, 1.5123, -2.2628]])
Out[22]:
tensor([[ 0.9592, -0.3084], [ 0.4125, 1.5123], [ 1.0104, -2.2628]])
Cuando se obtiene la transposición de un tensor de 2 dimensiones, se obtiene una versión conmutada de sus filas con sus columnas.
In [23]:
x = torch.randn(2, 3, 4) # Tensor de 3 dimensiones
print(x)
torch.t(x)
tensor([[[ 0.5688, 0.4226, -0.6718, -0.0961], [ 1.1667, 0.7585, -2.1319, 0.2441], [ 0.4130, -1.1373, -1.2946, 0.4909]], [[-0.7102, 0.2270, 1.4272, -0.4438], [ 1.4970, -0.5961, -0.6305, 0.4257], [-1.4224, -0.3125, 0.0097, 1.2551]]])
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-23-90e71df1462f> in <module>() 1 x = torch.randn(2, 3, 4) # 3-dimensions tensor 2 print(x) ----> 3 torch.t(x) RuntimeError: t() expects a tensor with <= 2 dimensions, but self is 3D
En este ejemplo, podemos ver que si transponemos un tensor con 3 o más dimensiones, obtendremos un error.
Podemos obtener la transposición de un tensor cuando queremos revelar algunas propiedades de la transformación lineal, como la simetría.
torch.numel(input)
Devuelve el número total de elementos del tensor de entrada.
In [24]:
a = torch.randn(1, 2, 3, 4, 5) # tensor de 5 dimensiones
print(a)
torch.numel(a)
tensor([[[[[ 0.5683, 0.3660, 0.1169, 0.6211, 0.1339], [ 0.7302, 0.4227, 0.5289, 0.0528, -1.2226], [-1.5867, 0.2716, -1.9211, -0.2082, 1.2038], [ 1.2828, 0.8668, -0.8027, -0.6341, 0.1237]], [[-0.7317, -1.2314, -0.3423, 1.9565, -0.9173], [ 1.1375, 0.9102, 0.1213, 0.6792, 1.3508], [ 0.5755, -0.1915, -1.0419, -2.0169, 1.9030], [-0.8302, 0.0087, 1.0707, 1.6864, 0.7094]], [[ 0.8155, -0.3658, 0.5485, -1.0085, -0.0369], [ 1.1497, 0.8193, -2.2531, 0.2470, -0.9620], [ 0.9751, -1.6460, 0.5189, -1.3889, -0.8977], [-0.0137, 0.7719, 0.0343, 0.6531, -1.4094]]], [[[-2.1804, -1.0201, 0.0127, -2.3253, -0.2246], [-0.4352, 1.8872, -0.3121, 0.1729, 0.5579], [ 1.1935, -0.7444, -1.4449, 1.0257, 0.4009], [-1.4843, -0.2777, 0.7592, 0.2888, 1.3752]], [[-0.4171, 0.6554, 1.5389, -0.6104, -0.9522], [-0.1757, 0.7910, -0.2597, -2.4339, 0.1102], [-0.5576, 0.0128, -0.2287, 1.6276, 1.6970], [ 1.3917, 0.1737, -0.1108, 0.5641, -0.8908]], [[ 0.1575, 0.2302, 0.3282, -0.3098, -1.2024], [-1.3616, -0.7325, 0.0336, -1.7040, -0.1361], [ 0.7067, 0.2282, -0.5501, 0.3377, 1.1849], [-1.0774, 1.1304, -0.2066, 0.2518, 0.1125]]]]])
Out[24]:
120
En este ejemplo, hemos creado un tensor de 5 dimensiones y hemos obtenido el número de elementos.
In [25]:
a = torch.zeros(4,4) # Tensor de 2 dimensiones
print(a)
torch.numel(a)
tensor([[0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 0.]])
Out[25]:
16
Aquí, creamos un tensor de 2 dimensiones, y obtuvimos el número de elementos.
In [26]:
a = [2,3] print(a) torch.numel((2,3))
[2, 3]
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-26-403f38c975eb> in <module>() 1 a = [2,3] 2 print(a) ----> 3 torch.numel((2,3)) TypeError: numel(): argument 'input' (position 1) must be Tensor, not tuple
Asegúrate de pasar un tensor como parámetro de la función numel. De lo contrario, obtendrás un error como éste.
Podemos utilizar la función numel cuando queramos saber el número de elementos que manejamos en un tensor.
Conclusión
Como puedes ver en este breve artículo, PyTorch tiene muchas funcionalidades que te ayudan a manejar tensores. Hay muchas más funcionalidades que puedes revisar en la documentación oficial de PyTorch.
Referencia
- Documentación oficial para
torch.Tensor
: https://pytorch.org/docs/stable/tensors.html