Optimización numérica · Tema 30

Descenso por gradiente

Cómo transformar la dirección de máximo crecimiento en un algoritmo iterativo para minimizar funciones con muchas variables.

01 · Del cálculo al algoritmo

Buscar un mínimo paso a paso

Resolver ∇f=0 de forma simbólica puede ser difícil o imposible cuando f tiene miles o millones de variables. El descenso por gradiente reemplaza esa resolución por una sucesión de aproximaciones.

Desde un punto inicial x₀, calcula el gradiente y avanza en la dirección opuesta:

xk+1=xk−αk∇f(xk)
  • ¿Por qué el gradiente negativo hace disminuir la función?
  • ¿Cómo elegir la tasa de aprendizaje α?
  • ¿Cuándo converge el algoritmo y hacia qué punto?
  • ¿Por qué algunos valles producen zigzag?
  • ¿Cómo decidir cuándo detener las iteraciones?
  • ¿Qué cambia con datos masivos o funciones no convexas?

02 · La dirección de descenso

Por qué aparece −∇f

Para un desplazamiento pequeño h, la aproximación lineal da:

f(x+h)≈f(x)+∇f(x)·h

Si fijamos ||h||=ε, Cauchy–Schwarz muestra que el producto escalar es mínimo cuando h apunta en sentido opuesto al gradiente:

h=−ε ∇f(x)/||∇f(x)||

El algoritmo absorbe longitud y normalización en α, usando h=−α∇f(x). Si el gradiente es grande, el paso también lo será; cerca de un punto estacionario se vuelve naturalmente pequeño.

Esta propiedad es local: no afirma que cualquier α produzca descenso ni que el camino más empinado sea el más corto hasta el mínimo.

03 · Ciclo iterativo

Inicializar, actualizar y detener

  1. 1
    Elegí un punto inicial.

    Puede venir de conocimiento previo, una heurística o una inicialización aleatoria.

  2. 2
    Calculá f y ∇f.

    Guardá el valor para monitorear el progreso y detectar resultados no finitos.

  3. 3
    Determiná α.

    Usá una tasa fija, un calendario o una búsqueda de línea.

  4. 4
    Actualizá las variables.

    Aplicá simultáneamente x←x−α∇f(x); no mezcles valores nuevos y antiguos.

  5. 5
    Comprobá la parada.

    Revisá norma del gradiente, cambio del objetivo, tamaño del paso y máximo de iteraciones.

  6. 6
    Diagnosticá.

    Informá convergencia, estancamiento, divergencia o agotamiento del presupuesto.

Una implementación confiable conserva un historial mínimo: iteración, valor, norma del gradiente, α y parámetros. Sin esas métricas es difícil distinguir convergencia lenta de un error de código.

04 · El modelo más transparente

Una cuadrática en una variable

Para f(x)=x²/2, el gradiente es x y la actualización queda:

xk+1=(1−α)xk

Por repetición, xk=(1−α)kx₀. De aquí surge un panorama completo:

  • 0<α<1: converge sin cambiar de signo.
  • α=1: llega al mínimo en un paso.
  • 1<α<2: converge oscilando.
  • α=2: oscila sin acercarse.
  • α>2: diverge.

La existencia de un mínimo no garantiza la convergencia: el paso debe ser compatible con la curvatura.

05 · Tasa de aprendizaje

Ni demasiado pequeña ni demasiado grande

Una α pequeña produce pasos seguros pero puede requerir demasiadas iteraciones. Una α grande avanza rápido en regiones planas, aunque puede saltar sobre el valle, oscilar o hacer crecer f.

Estrategias habituales

  • Constante: simple y predecible cuando se conoce la escala del problema.
  • Decreciente: pasos grandes al comienzo y refinamiento posterior.
  • Búsqueda de línea: elige α en cada iteración para lograr descenso suficiente.
  • Adaptativa por coordenada: ajusta escalas a partir del historial de gradientes.

Una regla de Armijo reduce α hasta cumplir una desigualdad de descenso suficiente. Evita aceptar un paso solo porque f disminuye una cantidad insignificante o accidental.

06 · Qué puede garantizarse

Suavidad, convexidad y curvatura

Si el gradiente es L-Lipschitz, su variación está acotada:

||∇f(x)−∇f(y)||≤L||x−y||

Para una función convexa y suave, un paso fijo 0<α<2/L permite convergencia bajo condiciones estándar. El valor 1/L es una elección conservadora frecuente.

  • Si f es convexa, todo mínimo local es global.
  • Si es fuertemente convexa, el mínimo es único y la convergencia puede ser geométrica.
  • Si no es convexa, el método puede llegar a mínimos locales, sillas o regiones planas.

07 · Valles estrechos

El condicionamiento controla la velocidad

En la cuadrática f(x,y)=(x²+κy²)/2, las curvaturas principales son 1 y κ. Si κ es grande, una tasa segura para la dirección y resulta diminuta para la dirección x.

La razón entre la mayor y la menor curvatura es el número de condición. Un valor alto produce trayectorias en zigzag y convergencia lenta.

Cómo mejorarlo

  • Escalar variables para que tengan magnitudes comparables.
  • Normalizar características en modelos de datos.
  • Usar precondicionamiento: x←x−αP∇f.
  • Incorporar información de curvatura mediante Newton o métodos cuasi-Newton.

La geometría depende de las coordenadas: cambiar unidades puede convertir un valle casi circular en uno extremadamente alargado.

08 · Saber cuándo terminar

Criterios de parada complementarios

Ningún criterio aislado cubre todos los casos. Conviene combinar:

CriterioLecturaRiesgo
||∇f||≤εgCasi estacionarioPuede ser silla o meseta.
||xk+1−xk||≤εxPaso pequeñoα puede ser demasiado pequeña.
|fk+1−fk|≤εfPoco progresoLa escala de f afecta el umbral.
k≥kmaxPresupuesto agotadoNo implica convergencia.

Los umbrales relativos, escalados por 1+||x|| o 1+|f|, se adaptan mejor a problemas de distinta magnitud.

09 · Obtener derivadas en programas

Analítico, numérico o automático

  • Derivación analítica: rápida y precisa, pero susceptible a errores de implementación.
  • Diferencias finitas: fáciles de programar; sirven para verificar, aunque introducen error de truncamiento y redondeo.
  • Diferenciación automática: aplica la regla de la cadena al grafo de operaciones y produce derivadas con precisión de máquina.

Una prueba útil compara el gradiente implementado con diferencias centrales:

∂if(x)≈[f(x+hei)−f(x−hei)]/(2h)

El valor de h no debe ser ni muy grande ni extremadamente pequeño. En doble precisión, valores cercanos a √ε multiplicados por la escala de la variable suelen ser un punto de partida.

10 · Datos y aceleración

Mini-lotes, momento y adaptatividad

Si f=(1/N)Σℓᵢ contiene millones de términos, calcular el gradiente completo en cada paso es costoso.

  • Gradiente estocástico (SGD): usa una muestra; es barato y ruidoso.
  • Mini-lote: promedia un grupo pequeño; aprovecha paralelismo y reduce ruido.
  • Momento: acumula una velocidad para amortiguar zigzag y sostener avance.
  • Adam y similares: combinan momentos y escalas adaptativas por parámetro.
vk+1=βvk+∇f(xk),   xk+1=xk−αvk+1

Estas variantes cambian la dinámica, pero no eliminan la necesidad de validar el objetivo, ajustar hiperparámetros y monitorear generalización.

11 · Paisajes con varias cuencas

La inicialización importa

En una función no convexa distintos puntos iniciales pueden converger a mínimos diferentes. Además aparecen puntos silla, donde el gradiente se anula aunque exista una dirección de descenso.

Prácticas útiles:

  • realizar varias inicializaciones y comparar resultados;
  • agregar perturbaciones ante estancamiento;
  • visualizar cortes o proyecciones cuando sea posible;
  • separar el valor de entrenamiento de una métrica de validación;
  • conservar la mejor solución visitada, no solo la última.

En alta dimensión, las sillas son frecuentes. El ruido de mini-lotes y el momento pueden ayudar a abandonarlas, aunque no ofrecen una garantía universal de óptimo global.

12 · Fallos observables

Leer la historia de optimización

SíntomaCausa probableRespuesta
f crece o se vuelve infinitaα grande o gradientes explosivosReducir α, escalar y limitar normas.
Oscilación regularCurvatura alta en alguna direcciónReducir α o precondicionar.
Progreso extremadamente lentoα pequeña o mal condicionamientoEscalar, buscar línea o usar momento.
Gradiente NaNDominio inválido o desbordamientoRevisar operaciones, datos y estabilidad.
Parada lejos del mínimoCriterio débil o mínimo localCombinar métricas y reiniciar.

Registrar valores finitos antes y después de cada actualización permite detenerse de manera controlada y conservar el último estado válido.

13 · Exploración interactiva

Laboratorio: trayectorias de descenso

Elegí una superficie, el punto inicial, α y la cantidad de iteraciones. La línea blanca muestra la trayectoria; el círculo azul es el inicio y el rojo, el último punto calculado.

EXPERIMENTO 30

Del gradiente a la trayectoria

f(x,y)=(x²+20y²)/2

Los resultados aparecen debajo.
Punto final−
Valor final−
Norma del gradiente−
Pasos ejecutados−

Calculando trayectoria…

Los colores codifican el valor de la función con una escala comprimida. Los segmentos revelan avance directo, zigzag, oscilación o divergencia.

Preguntas para explorar

  1. En el valle estrecho, compará α=0,02 y α≈0,09. ¿Cómo cambia el zigzag?
  2. Aumentá α por encima de 0,1: la dirección de mayor curvatura deja de ser estable.
  3. Compará el mismo α en el cuenco y en el valle para aislar el efecto del condicionamiento.
  4. En Rosenbrock, usá una tasa cercana a 0,002 y aumentá iteraciones.
  5. En la función no convexa, cambiá el inicio y observá a qué cuenca converge.

14 · Implementación

Programar descenso por gradiente

Versión general con historial

function descensoGradiente(funcion, gradiente, inicio, opciones = {}) {
  const alfa = opciones.alfa ?? 0.05;
  const tolerancia = opciones.tolerancia ?? 1e-7;
  const maxIteraciones = opciones.maxIteraciones ?? 1000;
  let punto = [...inicio];
  const historial = [];

  for (let iteracion = 0; iteracion < maxIteraciones; iteracion++) {
    const vector = gradiente(punto);
    const norma = Math.hypot(...vector);
    const valor = funcion(punto);
    historial.push({ iteracion, punto: [...punto], valor, norma });
    if (!Number.isFinite(valor) || !Number.isFinite(norma)) break;
    if (norma <= tolerancia) return { punto, historial, convergio: true };
    punto = punto.map((x, i) => x - alfa * vector[i]);
  }
  return { punto, historial, convergio: false };
}

const resultado = descensoGradiente(
  ([x, y]) => (x ** 2 + 2 * y ** 2) / 2,
  ([x, y]) => [x, 2 * y],
  [3, -2]
);
console.log(resultado.punto, resultado.convergio);

Gradiente por diferencias centrales

function gradienteNumerico(funcion, punto, paso = 1e-5) {
  return punto.map((_, i) => {
    const izquierda = [...punto];
    const derecha = [...punto];
    izquierda[i] -= paso;
    derecha[i] += paso;
    return (funcion(derecha) - funcion(izquierda)) / (2 * paso);
  });
}

const f = ([x, y]) => Math.sin(x) + x * y + y ** 2;
console.log(gradienteNumerico(f, [1, 2]));

Búsqueda de línea por retroceso

function pasoArmijo(funcion, punto, gradiente, inicial = 1) {
  let alfa = inicial;
  const pendiente = gradiente.reduce((suma, g) => suma + g * g, 0);
  while (alfa > 1e-12) {
    const candidato = punto.map((x, i) => x - alfa * gradiente[i]);
    if (funcion(candidato) <= funcion(punto) - 1e-4 * alfa * pendiente) {
      return alfa;
    }
    alfa *= 0.5;
  }
  return 0;
}

const funcion = ([x, y]) => x ** 2 + 10 * y ** 2;
console.log(pasoArmijo(funcion, [2, 1], [4, 20]));

En producción conviene evitar evaluaciones repetidas, registrar la causa de salida y copiar los vectores guardados en el historial para que actualizaciones posteriores no los modifiquen.

15 · Práctica guiada

Ejercicios de comprensión

Ejercicio 1: dos iteraciones

Aplicá dos pasos a f(x,y)=x²+y² desde (2,−1) con α=0,25.

Ver solución razonada

∇f=(2x,2y). El primer paso da (2,−1)−0,25(4,−2)=(1,−0,5). El segundo da (1,−0,5)−0,25(2,−1)=(0,5;−0,25). Cada coordenada se reduce a la mitad.

Ejercicio 2: estabilidad

¿Para qué valores de α converge el método en f(x)=3x²?

Ver solución razonada

f′=6x y xₖ₊₁=(1−6α)xₖ. Se necesita |1−6α|<1, es decir, 0<α<1/3.

Ejercicio 3: punto estacionario

El algoritmo llega a (0,0) para f=x²−y². ¿Puede afirmarse que encontró un mínimo?

Ver solución razonada

No. El origen es un punto silla: f aumenta sobre el eje x y disminuye sobre el eje y. Gradiente pequeño solo indica estacionariedad aproximada.

Ejercicio 4: escalado

Explicá por qué f=(x²+1000y²)/2 es difícil para una única tasa fija.

Ver solución razonada

La estabilidad en y exige aproximadamente α<0,002, pero ese paso hace muy lento el avance en x, cuya curvatura es 1. El número de condición es 1000; escalar y o precondicionar reduce la diferencia.

Ejercicio 5: actualización simultánea

¿Qué error aparece si se actualiza x y luego se usa ese x nuevo para calcular la actualización de y?

Ver solución razonada

Ya no se aplica el gradiente calculado en un único punto. Se obtiene otro método dependiente del orden de las coordenadas. Primero debe calcularse todo el vector gradiente y luego actualizar todas las componentes.

Ejercicio 6: criterio engañoso

El paso tiene norma 10⁻¹², pero ||∇f||=100. ¿Convergió el algoritmo?

Ver solución razonada

No necesariamente. Probablemente α es extremadamente pequeña. El paso pequeño por sí solo no certifica cercanía a un punto estacionario; debe combinarse con la norma del gradiente y el progreso del objetivo.

16 · Errores frecuentes y síntesis

Ideas para recordar

«El gradiente apunta hacia el mínimo»

Apunta hacia el crecimiento local más rápido. Para minimizar se usa su dirección opuesta.

«Una α mayor siempre converge más rápido»

Puede sobrepasar el valle, oscilar o divergir. La curvatura limita el paso estable.

«Si f disminuye, llegará al mínimo global»

En problemas no convexos puede converger a un mínimo local o estancarse cerca de una silla.

«Paso pequeño significa gradiente pequeño»

También puede deberse a una tasa diminuta. Ambos valores deben monitorearse.

«Las escalas de las variables no importan»

Determinan la geometría numérica y pueden volver muy lento al método.

«El último punto siempre es el mejor»

Con ruido u oscilaciones conviene conservar el menor valor factible observado.

  • El descenso por gradiente itera en la dirección opuesta a ∇f.
  • La tasa de aprendizaje equilibra velocidad y estabilidad.
  • La curvatura máxima limita el tamaño de paso seguro.
  • El mal condicionamiento causa zigzag y convergencia lenta.
  • La convexidad determina qué puede afirmarse sobre el óptimo alcanzado.
  • Los criterios de parada deben combinar gradiente, paso, objetivo y presupuesto.
  • Las derivadas pueden ser analíticas, numéricas o automáticas.
  • Historiales y comprobaciones de finitud convierten una fórmula en un algoritmo robusto.

Con esto cerramos el bloque de optimización. En el próximo tema comenzaremos a acumular cantidades sobre regiones mediante integrales dobles y sumas de Riemann.