Optimization Algorithm
Un algoritmo de optimización actualiza los pesos de un modelo para minimizar su pérdida durante el entrenamiento. Incluye descenso del gradiente, momento, Adam, AdamW, Muon y código.
Un algoritmo de optimización, u optimizador, es la regla que utiliza un proceso de entrenamiento para modificar los parámetros de un modelo y reducir su función de pérdida. En aprendizaje profundo, el optimizador recibe, mediante retropropagación, el gradiente de la pérdida con respecto a cada peso del modelo y decide cuánto y en qué dirección moverlo. Junto con su tasa de aprendizaje, el optimizador determina la velocidad de convergencia del entrenamiento, su estabilidad, la memoria que necesita y, a menudo, la capacidad de generalización del modelo final.
Cómo funcionan los optimizadores#
Casi todos los optimizadores de aprendizaje profundo son variantes del descenso del gradiente: calculan el gradiente g de la pérdida en un minilote y después desplazan los pesos un pequeño paso en dirección contraria, w ← w − η·g. Los optimizadores se diferencian en lo que hacen con g antes de dar ese paso. Los métodos de momento promedian los gradientes a lo largo del tiempo para ganar velocidad en direcciones que se mantienen constantes. Los métodos adaptativos dividen el paso de cada parámetro por una estimación acumulada del tamaño de su gradiente. Muon ortogonaliza la actualización de cada matriz de pesos en su conjunto. Los métodos de segundo orden también utilizan la curvatura, lo que permite tomar decisiones más fundamentadas en cada paso, pero con un coste de cálculo mucho mayor. Los métodos que no necesitan gradiente, como los algoritmos evolutivos y la búsqueda aleatoria, optimizan probando candidatos y conservando el mejor:
La regla de actualización es más importante cuando la superficie de pérdida está mal condicionada y se curva con mucha pendiente en unas direcciones y suavemente en otras. Ejecutar tres optimizadores desde el mismo punto inicial en un valle estrecho muestra la diferencia:
import torch
# A long, narrow valley: f(w) = w1^2 + 50 * w2^2, with its minimum at (0, 0)
scale = torch.tensor([1.0, 50.0])
optimizers = {
"SGD": lambda p: torch.optim.SGD(p, lr=0.015),
"SGD + momentum": lambda p: torch.optim.SGD(p, lr=0.015, momentum=0.9),
"Adam": lambda p: torch.optim.Adam(p, lr=0.1),
}
for name, make_optimizer in optimizers.items():
w = torch.tensor([5.0, 1.0], requires_grad=True)
optimizer = make_optimizer([w])
# Same loss and starting point for every optimizer; only the update rule differs
for step in range(100):
loss = (scale * w**2).sum()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"{name:15s} f(w) after 100 steps: {(scale * w**2).sum().item():.6f}")El SGD simple se detiene en 0.056531 porque la dirección pronunciada w2 limita su tasa de aprendizaje: cualquier tasa superior a 0.02 hace que w2 se pase más en cada paso, y con 0.021 la pérdida sube hasta unos 9500 millones en 100 pasos. Con ese límite, el avance en la dirección más suave w1 es lento. El momento llega a 0.000216 al ganar velocidad en w1, y Adam llega a 0.001953 al asignar a cada coordenada un tamaño de paso propio.
Algoritmos de optimización habituales#
- Descenso del gradiente estocástico (SGD): Da pasos en dirección contraria al gradiente del minilote. Con un momento de 0.9, se entrenaron con él la mayoría de las redes convolucionales de referencia y almacena un valor adicional por parámetro.
- AdaGrad y RMSProp: Ajustan el paso de cada parámetro según el historial de sus gradientes al cuadrado. AdaGrad divide por la raíz de la suma acumulada de estos gradientes, que solo aumenta, por lo que sus pasos se reducen durante todo el entrenamiento. RMSProp utiliza, en cambio, una media con decaimiento exponencial, que mantiene los tamaños de paso adaptables.
- Adam: Combina el momento con un escalado al estilo de RMSProp y corrige ambas medias acumuladas para compensar su valor inicial cero. Sus valores predeterminados —una tasa de aprendizaje de 0.001, β1 = 0.9 y β2 = 0.999— funcionan en muchos problemas.
- AdamW: Adam con decaimiento de pesos desacoplado, que reduce los pesos directamente en lugar de hacerlo mediante el escalado adaptativo del gradiente. Es el optimizador estándar para Transformers y modelos de lenguaje grandes (LLM).
- Muon: Ortogonaliza la actualización del momento de cada matriz de pesos 2D mediante iteraciones de Newton-Schulz y mantiene un único búfer de estado por parámetro. Moonshot AI lo escaló para el preentrenamiento de LLM.
- L-BFGS: Un método cuasi-Newton que construye una estimación de la curvatura a partir de gradientes recientes. Converge en pocos pasos en problemas suaves con lotes completos, y los gradientes ruidosos de los minilotes no lo hacen adecuado para redes grandes.
El paquete de optimizadores de PyTorch implementa todos estos métodos, incluido torch.optim.Muon, además de planificadores de tasa de aprendizaje compatibles con cualquiera de ellos.
Optimizador y términos relacionados#
- Función de pérdida: El objetivo que minimiza el optimizador, como la entropía cruzada para clasificación o el error cuadrático medio para regresión.
- Planificador de tasa de aprendizaje: Ajusta el tamaño del paso η durante el entrenamiento, con calentamiento, decaimiento escalonado o enfriamiento coseno, además de cualquier optimizador.
- Ajuste de hiperparámetros: Búsqueda externa de configuraciones como el optimizador, la tasa de aprendizaje y el tamaño del lote; cada candidato requiere un entrenamiento completo o parcial. Los métodos sin gradiente, como la optimización bayesiana y la búsqueda evolutiva, realizan esta tarea porque no se puede calcular el gradiente de una puntuación de validación con respecto a opciones como el optimizador.
Cómo elegir un optimizador#
El optimizador y la tasa de aprendizaje se eligen conjuntamente, ya que cada optimizador funciona en su propio intervalo: el SGD con momento suele empezar entre 0.01 y 0.1, y los optimizadores de la familia Adam, en torno a 0.001. El entrenamiento de Ultralytics YOLO elige automáticamente: el valor predeterminado optimizer="auto" ignora lr0 y selecciona AdamW con una tasa de aprendizaje ajustada al número de clases para entrenamientos de hasta 10.000 iteraciones, o MuSGD, la combinación de SGD y Muon utilizada para entrenar los pesos publicados de YOLO26, para calendarios más largos; si indicas un optimizador, lr0 se aplica:
from ultralytics import YOLO
# Carga un modelo YOLO26n preentrenado
model = YOLO("yolo26n.pt")
# # Elige SGD explícitamente; lr0 solo se aplica cuando el optimizador no es "auto"
results = model.train(data="coco8.yaml", epochs=5, optimizer="SGD", lr0=0.01)Con optimizer="SGD", el entrenador también activa el momento de Nesterov y utiliza el argumento momentum, cuyo valor predeterminado es 0.937, como coeficiente.










