← Volver al blog

Gradient Descent with Python

El descenso por gradiente es el motor detrás del entrenamiento de casi toda red neuronal moderna. La idea es sorprendentemente simple: desplazarse iterativamente en la dirección opuesta al gradiente de la función objetivo para bajar "cuesta abajo" hasta un mínimo.

En cada paso:

\[x_{n+1} = x_n - \eta \cdot f'(x_n)\]

donde \(\eta\) es el learning rate o tamaño de paso. Si es muy pequeño, converge lento; si es muy grande, puede oscilar o divergir.

Para ilustrarlo, minimicemos \(f(x) = x^2 + 2x - 4\). El mínimo analítico está en \(x^* = -1\) con \(f(x^*) = -5\).

#Function to be minimized
def f(x):
    return x**2 + 2*x - 4

#Derivative of the function
def df(x):
    return 2*x + 2

#Beginning of the Gradient Descent algorithm
#===========================================

#Initial parameters
x0 = 2
learning_rate = 0.1
iterations = 100

for i in range(iterations):
    x0 = x0 - learning_rate*df(x0)

#Showing the final value of x0 and f(x0)
print(f"Value of x0: {x0:.4f}")
print(f"Minimum value of f(x): {f(x0):.4f}")

Ejecutándolo obtenemos:

Value of x0: -1.0000
Minimum value of f(x): -5.0000

El método converge al mínimo real en prácticamente las primeras 20 iteraciones:

Gradient descent trajectory

Cada paso divide la distancia al óptimo por un factor de \((1 - 2\eta) = 0.8\) (porque aquí \(f''(x) = 2\) es constante). A este tipo de convergencia se le llama lineal — exponencialmente rápida en teoría, pero en problemas reales con múltiples mínimos locales la trayectoria puede quedarse atrapada.

De 1D a aprendizaje profundo:

La misma idea se generaliza a vectores: \(\vec{w}_{n+1} = \vec{w}_n - \eta \cdot \nabla L(\vec{w}_n)\), donde \(\vec{w}\) son los pesos de la red y \(L\) es la función de pérdida. En la práctica se usan variantes como:

  • SGD con momentum — acelera en direcciones consistentes
  • Adam / RMSprop — ajustan \(\eta\) individualmente por parámetro
  • Mini-batch — estima \(\nabla L\) sobre un subconjunto aleatorio del dataset

Instalación:

No requiere librerías — Python estándar basta. Para problemas más grandes:

pip install numpy
← Volver al blog