Saltar al contenido

← Deep Learning

Configuración del Entorno de Trabajo

Preview gratis Sección 1 · Fundamentos de Deep Learning

Configuración del Entorno de Trabajo

Antes de entrenar tu primera red, necesitas un entorno que entienda dos cosas: cómo representar datos numéricos y cómo calcular gradientes de forma automática. PyTorch resuelve ambas con un solo objeto, el torch.Tensor, y con su motor de diferenciación, autograd. Con Python 3.13, una build de CPU de torch 2.x, NumPy, scikit-learn y matplotlib tienes todo lo necesario para aprender deep learning sin una GPU.

El tensor y su relación con NumPy

Un tensor es un arreglo multidimensional de números, muy parecido a un ndarray de NumPy, pero con dos superpoderes: puede vivir en GPU y puede registrar las operaciones que lo producen para derivarlas después. La interoperabilidad es directa: torch.from_numpy(arr) crea un tensor que comparte memoria con el array de origen, así que modificar uno afecta al otro. En cambio, torch.tensor(arr) siempre copia los datos.

El segundo pilar es autograd. Cuando un tensor lleva requires_grad=True, PyTorch graba cada operación en un grafo acíclico dirigido. Al llamar .backward() sobre un escalar, recorre ese grafo hacia atrás y acumula las derivadas en el atributo .grad de cada hoja. Ese gradiente es exactamente lo que el optimizador necesita para ajustar los pesos.

La idea central del entrenamiento es minimizar una pérdida $L$ moviendo cada peso $w$ en sentido contrario a su gradiente:

$$w \leftarrow w - \eta \, \frac{\partial L}{\partial w}$$

donde $\eta$ es la tasa de aprendizaje. Autograd calcula ese $\frac{\partial L}{\partial w}$ por ti; tú solo defines la operación hacia adelante.

Verificación e instalación

Tras instalar, confirma la versión y si hay GPU disponible. En una build de CPU, torch.cuda.is_available() devuelve False, y eso está bien: para entender los fundamentos, la CPU es suficiente. El siguiente bloque crea tensores, registra una operación, retropropaga y lee el gradiente.

import torch

torch.manual_seed(42)  # reproducibilidad
device = "cuda" if torch.cuda.is_available() else "cpu"
print(torch.__version__, device)

# tensor con seguimiento de gradiente
w = torch.tensor([3.0], requires_grad=True)
x = torch.tensor([2.0])
loss = (w * x).sum()  # operacion hacia adelante

loss.backward()       # retropropagacion
print(w.grad)         # dL/dw = x = 2.0

El valor de w.grad es $2.0$, que coincide con $\frac{\partial (w x)}{\partial w} = x$. Verificar a mano un gradiente simple es la mejor forma de confiar en el motor antes de usarlo en redes grandes.

Trampas comunes

  • Olvidar torch.manual_seed(42): sin semilla, cada ejecución parte de pesos iniciales distintos y tus resultados dejan de ser reproducibles.
  • Confundir un tensor con un array de NumPy: comparten gran parte de la API, pero solo el tensor lleva grafo de autograd y puede ir a GPU.
  • No llamar optimizer.zero_grad() antes de cada .backward(): los gradientes se acumulan y, si no los reinicias, sumas los del paso anterior.
  • Asumir que necesitas GPU: para aprender, la build de CPU rinde de sobra; la GPU solo acelera modelos grandes.
  • Mezclar tensores en distintos dispositivos: una operación entre un tensor en CPU y otro en GPU lanza un error; mueve todo con .to(device).

Con el entorno listo y un gradiente verificado a mano, ya dominas la mecánica que sostiene cualquier red neuronal: representar datos como tensores, registrar operaciones y derivarlas en automático. El siguiente paso es construir capas sobre esa base. En el notebook de redes básicas pondrás esto en práctica: ejecutarás autograd y entrenarás tu primer perceptrón multicapa sobre datos reales.