14. Tensores en PyTorch

14.1 Introducción

En el tema anterior vimos que PyTorch es la biblioteca que utilizaremos para trabajar con Deep Learning en forma práctica. También mencionamos que la estructura de datos más importante dentro de PyTorch es el tensor.

En este tema vamos a estudiar los tensores en detalle, porque prácticamente todo lo que hagamos más adelante dependerá de ellos. Las entradas de una red, los pesos, los bias, las salidas del modelo, los gradientes y hasta muchas métricas intermedias se representan mediante tensores.

Por eso, entender bien esta estructura no es un detalle menor: es una parte central del aprendizaje de PyTorch.

14.2 ¿Qué es un tensor?

Un tensor es una estructura que permite almacenar datos numéricos organizados en una o más dimensiones.

Si esta definición suena abstracta, conviene pensarla de forma gradual:

  • Un solo número puede verse como un tensor.
  • Una lista de números puede verse como un tensor.
  • Una tabla de filas y columnas también puede verse como un tensor.
  • Una colección más compleja de datos, como un conjunto de imágenes, también puede representarse con tensores.

En otras palabras, un tensor es una forma general de representar datos numéricos, sin importar si son simples o muy estructurados.

14.3 Por qué los tensores son tan importantes

Los tensores son importantes porque permiten expresar de manera uniforme casi todos los objetos con los que trabaja una red neuronal.

Por ejemplo:

  • Los datos de entrada suelen ser tensores.
  • Los parámetros del modelo también son tensores.
  • Las salidas generadas por el modelo son tensores.
  • Los gradientes calculados durante backpropagation también son tensores.

Esto simplifica mucho el trabajo, porque PyTorch puede aplicar un conjunto coherente de operaciones a todos esos elementos.

14.4 Relación entre escalar, vector, matriz y tensor

Muchas veces, al empezar, la palabra tensor parece más complicada de lo que realmente es. En realidad, un tensor puede verse como una ampliación de conceptos que probablemente ya conozcas.

  • Un escalar es un único valor, como 7 o 3.5.
  • Un vector es una lista de valores, como [2, 4, 6].
  • Una matriz es una tabla de filas y columnas.
  • Un tensor generaliza todos esos casos.

Por eso, cuando hablamos de tensores, no estamos introduciendo un objeto completamente ajeno, sino una forma más general de pensar estructuras numéricas.

14.5 Dimensiones de un tensor

Una idea clave para entender tensores es la de dimensión. La dimensión indica cuántos ejes necesitamos para describir la estructura del tensor.

Veamos los casos más comunes:

  • Un tensor de dimensión 0 contiene un solo valor.
  • Un tensor de dimensión 1 es una secuencia o lista.
  • Un tensor de dimensión 2 es una tabla.
  • Un tensor de dimensión 3 o más permite representar estructuras más complejas.

En Deep Learning aparecen con frecuencia tensores de varias dimensiones, especialmente al trabajar con imágenes, secuencias o lotes de ejemplos.

14.6 Algunos ejemplos intuitivos

Para que esta idea resulte más concreta, pensemos en algunos ejemplos típicos:

  • La edad de una persona puede representarse como un tensor de dimensión 0.
  • Las notas de un alumno en cinco materias pueden representarse como un tensor de dimensión 1.
  • Una planilla de alumnos por materias puede representarse como un tensor de dimensión 2.
  • Un lote de imágenes en color puede representarse con más dimensiones.

Estos ejemplos muestran que los tensores no son una rareza exclusiva de inteligencia artificial: son una forma general de organizar datos numéricos.

14.7 Crear un tensor manualmente

La forma más directa de crear un tensor en PyTorch es usar torch.tensor().

import torch
x = torch.tensor([1, 2, 3, 4])
print(x)

Aquí hemos creado un tensor de una dimensión que contiene cuatro números enteros.

Este es un buen punto de partida para entender que un tensor puede nacer a partir de datos escritos directamente por nosotros.

14.8 Crear un tensor escalar

Un tensor también puede contener un único valor:

import torch
x = torch.tensor(8)
print(x)

En este caso tenemos un tensor escalar. Aunque sea un solo número, sigue siendo un tensor para PyTorch.

Esto es importante porque muchas operaciones internas del entrenamiento producen valores escalares, por ejemplo una pérdida total.

14.9 Crear un tensor de dos dimensiones

Si usamos una lista de listas, podemos formar una estructura bidimensional:

import torch
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x)

El resultado representa una tabla con dos filas y tres columnas.

Este tipo de tensor aparece constantemente en Deep Learning, por ejemplo cuando una capa lineal procesa varias entradas al mismo tiempo.

14.10 La forma o shape de un tensor

Otro concepto fundamental es la forma del tensor, conocida habitualmente como shape.

La forma indica cuántos elementos hay en cada dimensión. Por ejemplo, si un tensor tiene dos filas y tres columnas, su forma será algo equivalente a:

torch.Size([2, 3])

Esto no solo nos dice que el tensor es bidimensional, sino también cómo está organizado internamente.

Consultar la forma es una de las operaciones más útiles al trabajar con PyTorch, porque muchos errores provienen de usar tensores con dimensiones incompatibles.

14.11 Consultar la forma

Para conocer la forma de un tensor, usamos la propiedad shape:

import torch
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.shape)

La salida nos indicará cuántas filas y columnas tiene el tensor.

Acostumbrarse a inspeccionar shape es una excelente práctica para evitar confusiones al empezar.

14.12 Cantidad de dimensiones

Además de la forma, muchas veces queremos saber cuántas dimensiones tiene un tensor. Para eso se puede usar ndim.

import torch
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.ndim)

En este caso, el resultado será 2 porque el tensor tiene dos dimensiones.

Esto ayuda a distinguir entre un vector, una matriz o estructuras más grandes.

14.13 Tamaño total de elementos

Otra propiedad útil es saber cuántos valores contiene en total un tensor. Para eso se puede usar numel().

import torch
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(x.numel())

El resultado será 6 porque hay seis números almacenados en total.

Este dato puede ser útil para verificar estructuras y comprender el tamaño real del objeto con el que estamos trabajando.

14.14 Tipos de datos en tensores

Así como en Python existen enteros, flotantes y booleanos, en PyTorch los tensores también tienen un tipo de dato.

Por ejemplo, un tensor puede almacenar:

  • Números enteros.
  • Números de punto flotante.
  • Valores booleanos.

Esto importa mucho porque no todas las operaciones funcionan igual con todos los tipos. En Deep Learning, con frecuencia se usan tensores de punto flotante, ya que los pesos y los gradientes suelen necesitar valores decimales.

14.15 Consultar el tipo de dato

Para ver el tipo de dato de un tensor, se puede usar dtype:

import torch
x = torch.tensor([1, 2, 3])
print(x.dtype)

La salida mostrará el tipo interno que PyTorch asignó a ese tensor.

Conocer esto es útil porque a veces una operación falla o se comporta distinto simplemente porque el tensor no tiene el tipo esperado.

14.16 Tensores con decimales

Si queremos representar valores decimales, podemos crear tensores con números flotantes:

import torch
x = torch.tensor([1.5, 2.0, 3.75])
print(x)

Este tipo de tensor es muy común en aprendizaje automático, porque muchas variables y parámetros no son enteros exactos.

14.17 Crear tensores con funciones útiles

Además de escribir los datos manualmente, PyTorch ofrece varias funciones para crear tensores de forma rápida.

Por ejemplo, podemos crear:

  • Tensores llenos de ceros.
  • Tensores llenos de unos.
  • Tensores con valores aleatorios.
  • Tensores con secuencias numéricas.

Estas funciones son muy útiles cuando queremos inicializar datos, pesos o estructuras temporales.

14.18 Tensores de ceros y unos

Dos funciones muy usadas son torch.zeros() y torch.ones().

import torch
a = torch.zeros((2, 3))
b = torch.ones((2, 3))
print(a)
print(b)

Esto crea dos tensores de dos filas por tres columnas: uno con ceros y otro con unos.

Son especialmente útiles para inicializaciones, máscaras y pruebas rápidas.

14.19 Tensores aleatorios

También es muy frecuente generar tensores con valores aleatorios:

import torch
x = torch.rand((2, 3))
print(x)

Este tensor tendrá forma 2 por 3 y sus valores serán decimales aleatorios.

La generación aleatoria es importante en Deep Learning porque muchas veces los pesos iniciales de una red se crean con métodos de este tipo.

14.20 Secuencias numéricas

PyTorch también permite crear secuencias numéricas de manera cómoda. Una función típica es torch.arange().

import torch
x = torch.arange(0, 10)
print(x)

Esto genera un tensor con valores desde 0 hasta 9.

Estas secuencias son útiles para pruebas, índices y construcciones auxiliares.

14.21 El dispositivo donde vive el tensor

Un tensor no solo tiene datos, forma y tipo. También está ubicado en un dispositivo.

En la práctica, normalmente ese dispositivo será:

  • CPU
  • GPU, si está disponible y la usamos

Esto importa porque en PyTorch las operaciones deben realizarse entre tensores que estén en dispositivos compatibles. Más adelante veremos este tema con mayor profundidad.

14.22 Copiar o convertir tensores

En muchos casos necesitaremos transformar un tensor: cambiar su tipo, moverlo a otro dispositivo o crear una variante del mismo.

Aunque aún no entraremos en todas esas operaciones, conviene saber desde ahora que los tensores son estructuras muy flexibles y que PyTorch ofrece métodos para adaptarlos a distintas necesidades.

Esta flexibilidad resulta esencial en proyectos reales, donde los datos rara vez llegan exactamente en la forma ideal.

14.23 El papel de los tensores en una red neuronal

Para entender por qué este tema es tan importante, conviene mirar cómo intervienen los tensores en una red neuronal típica.

  • Las entradas del modelo son tensores.
  • Los pesos de cada capa son tensores.
  • Los bias son tensores.
  • Las salidas intermedias de cada capa son tensores.
  • La salida final también es un tensor.
  • La pérdida calculada al final puede expresarse como un tensor escalar.

Esto significa que aprender PyTorch es, en gran medida, aprender a pensar y trabajar con tensores.

14.24 requires_grad y aprendizaje automático

Una propiedad especialmente importante en PyTorch es requires_grad. Cuando está activada, PyTorch entiende que debe seguir las operaciones hechas sobre ese tensor para luego poder calcular derivadas.

Esto es fundamental en Deep Learning porque los parámetros entrenables de una red necesitan gradientes para poder actualizarse.

Por ejemplo, un tensor podría crearse así:

import torch
x = torch.tensor([2.0], requires_grad=True)

No hace falta dominar aún todos los detalles de esta propiedad, pero sí entender que conecta directamente al tensor con el proceso de aprendizaje del modelo.

14.25 Diferencia entre tensor y lista de Python

Una duda muy frecuente es: si Python ya tiene listas, ¿por qué necesitamos tensores?

La respuesta es que una lista de Python sirve como estructura general de programación, pero no está pensada específicamente para cálculo numérico intensivo.

En cambio, los tensores ofrecen ventajas clave:

  • Están diseñados para operaciones numéricas eficientes.
  • Se integran con el cálculo automático de gradientes.
  • Pueden trabajar con GPU.
  • Forman parte del ecosistema completo de PyTorch.

En otras palabras, una lista puede servir para almacenar datos, pero un tensor está diseñado para ser procesado matemáticamente dentro del flujo de Deep Learning.

14.26 Errores comunes al comenzar con tensores

Al principio, muchos errores tienen que ver con no prestar atención a la estructura del tensor. Algunos de los más comunes son:

  • Confundir una dimensión con la cantidad total de elementos.
  • No revisar la forma antes de aplicar una operación.
  • Mezclar enteros y flotantes sin advertirlo.
  • No entender si un tensor es escalar, vector o matriz.
  • Crear datos con una forma distinta de la esperada por el modelo.

Estos problemas son muy normales. Por eso, una buena costumbre es inspeccionar frecuentemente shape, dtype y ndim.

14.27 Buenas prácticas para estudiantes

Si estás empezando con tensores en PyTorch, algunas recomendaciones útiles son:

  • Crear ejemplos pequeños y fáciles de entender.
  • Imprimir el tensor y también su forma.
  • Comparar casos de una, dos y tres dimensiones.
  • Prestar atención al tipo de dato.
  • No avanzar demasiado rápido hacia modelos grandes sin dominar primero estas bases.

Estas prácticas hacen que el aprendizaje posterior sea mucho más sólido.

14.28 Relación con el próximo tema

En este tema nos concentramos en comprender qué es un tensor, cómo se representa y por qué es tan importante en PyTorch.

El siguiente paso natural es aprender a operar con ellos: sumar, multiplicar, transformar formas y realizar otras manipulaciones que aparecen constantemente en modelos de Deep Learning.

Es decir, primero entendemos el objeto; luego aprendemos a trabajar activamente con él.

14.29 Qué debes recordar de este tema

  • Un tensor es la estructura de datos central de PyTorch.
  • Puede representar escalares, vectores, matrices y estructuras de más dimensiones.
  • La forma del tensor indica cómo están organizados sus datos.
  • El tipo de dato también es importante y afecta las operaciones posibles.
  • Los tensores pueden crearse manualmente o con funciones como zeros, ones, rand y arange.
  • Los tensores son la base de entradas, parámetros, salidas y gradientes en Deep Learning.
  • Entender bien los tensores simplifica enormemente el aprendizaje de PyTorch.

14.30 Conclusión

Los tensores son el lenguaje básico con el que PyTorch expresa casi todo lo que ocurre en un modelo de Deep Learning. Aunque al principio puedan parecer una idea nueva, en realidad son una extensión natural de conceptos conocidos como números, listas y matrices.

Dominar tensores significa construir una base firme sobre la cual luego será mucho más fácil entender operaciones matemáticas, capas, entrenamiento y evaluación de modelos.

En el próximo tema daremos el siguiente paso: aprenderemos a realizar operaciones básicas con tensores en PyTorch.