Momentum (Optimization)
La optimización por impulso utiliza gradientes anteriores para acelerar el entrenamiento del modelo, suavizar las actualizaciones ruidosas y mejorar la convergencia, al tiempo que equilibra la tasa de aprendizaje.
El impulso es una técnica de optimización que dota al entrenamiento basado en gradientes de memoria de las actualizaciones anteriores. Al combinar el gradiente actual con un historial decreciente de gradientes anteriores, gana velocidad en las direcciones constantes y reduce los movimientos de ida y vuelta. Esto ayuda a los modelos de aprendizaje automático a minimizar el objetivo de entrenamiento de forma más eficiente. La optimización para motores de búsqueda tiene que ver con la visibilidad de los sitios web; el impulso, con las actualizaciones numéricas de los parámetros del modelo.
Cómo funciona el impulso#
Durante el descenso del gradiente, un modelo desplaza sus pesos en sentido contrario al gradiente, es decir, a la dirección en la que su función de pérdida aumenta más rápidamente. El impulso clásico, también llamado impulso de Polyak o método de la bola pesada, añade inercia a este movimiento. Boris Polyak lo presentó en su trabajo de 1964 sobre la aceleración de métodos iterativos.
El optimizador mantiene un búfer de velocidad, con un valor acumulado por parámetro. En cada actualización, multiplica el búfer anterior por un coeficiente de impulso, suma el gradiente actual y resta de los pesos el búfer resultante multiplicado por la tasa de aprendizaje. En las redes neuronales, la retropropagación proporciona esos gradientes; el optimizador conserva el búfer entre actualizaciones.
El impulso resulta especialmente útil en superficies de pérdida alargadas, donde la curvatura es pronunciada a través de un valle y suave a lo largo de su fondo. Los gradientes que apuntan repetidamente a lo largo del valle se acumulan, mientras que los componentes alternos que lo atraviesan se cancelan parcialmente. Con el descenso estocástico del gradiente, esta memoria también suaviza las fluctuaciones entre minilotes. La dinámica de la pérdida cuadrática con impulso explica tanto su aceleración como las oscilaciones que puede introducir cerca de un mínimo.
El impulso, la tasa de aprendizaje y métodos relacionados#
El coeficiente de impulso, que suele representarse con beta o mu, normalmente está entre cero y uno. Con cero se obtiene el descenso del gradiente ordinario; los valores más cercanos a uno conservan durante más tiempo los gradientes anteriores. 0.9 es un valor inicial habitual. Con un búfer de velocidad no normalizado y un gradiente constante, la velocidad acumulada se aproxima a diez veces ese gradiente con 0.9, frente a cien veces con 0.99. Por tanto, el impulso y la tasa de aprendizaje interactúan estrechamente durante el ajuste de hiperparámetros.
Una combinación demasiado agresiva provoca un sobreimpulso: las actualizaciones atraviesan repetidamente un mínimo y causan oscilaciones en la pérdida o divergencia. Esto ocurre incluso con objetivos cuadráticos suaves. Un programa de tasa de aprendizaje modifica la magnitud de las actualizaciones durante el entrenamiento, mientras que el impulso determina cuánto persiste el historial direccional.
Dos algoritmos de optimización estrechamente relacionados utilizan este historial de forma distinta:
- El impulso de Nesterov evalúa el gradiente en una posición anticipada obtenida mediante la velocidad conservada, lo que permite que el gradiente corrija el movimiento previsto.
- Adam combina una media de gradientes ponderada exponencialmente con una media de gradientes al cuadrado que escala las actualizaciones por separado para cada parámetro. Su
beta1controla la memoria de gradientes.
Un ejemplo mínimo con PyTorch#
Este ejemplo de PyTorch compara puntos de partida y tasas de aprendizaje idénticos en un objetivo cuadrático alargado. La implementación de SGD oficial gestiona automáticamente el búfer de impulso.
import torch
# Curvature is 50 times greater along the second coordinate.
scale = torch.tensor([1.0, 50.0])
for momentum in (0.0, 0.9):
weights = torch.tensor([5.0, 1.0], requires_grad=True)
optimizer = torch.optim.SGD([weights], lr=0.015, momentum=momentum)
for step in range(100):
optimizer.zero_grad()
loss = (scale * weights.square()).sum()
loss.backward()
optimizer.step()
final_loss = (scale * weights.square()).sum().item()
print(f"Momentum {momentum}: loss = {final_loss:.6f}")Tras 100 actualizaciones, la pérdida es de aproximadamente 0.056531 sin impulso y 0.000216 con impulso. El historial direccional acumulado acelera el avance a lo largo de la coordenada más suave.
Usos en el entrenamiento de visión artificial#
El impulso contribuye al entrenamiento de redes neuronales convolucionales para la clasificación de imágenes y la detección de objetos. El entrenamiento de Ultralytics YOLO habilita el impulso de Nesterov cuando se selecciona optimizer="SGD", y el ajuste momentum controla el historial de actualizaciones conservado. La implementación del entrenador pasa ese coeficiente al optimizador con nesterov=True.
Una aplicación destacada es el procedimiento de entrenamiento original de ResNet para ImageNet. Esos modelos utilizaban SGD con un impulso de 0.9, un tamaño de lote de 256, una disminución de pesos de 0.0001 y una tasa de aprendizaje inicial de 0.1, que se dividía entre diez cuando el error se estancaba.










