Comparaison SGD vs Momentum vs Adam Optimizer
Exécutez les trois optimiseurs sur la même fonction de perte « vallée longue et étroite » pour visualiser les chemins de convergence et les différences de vitesse.
À la fin de ce tutoriel, vous comprendrez :SGD oscille, Momentum s'appuie sur l'inertie pour lisser, Adam ajuste de manière adaptative la taille du pas—les principes mathématiques et les effets intuitifs des trois stratégies.
Analogie de la vie quotidienne
Descendre une route sinueuse—trois stratégies
Stratégie SGD : ne regardez que vos pieds, allez toujours dans la direction la plus raide. Face à un ravin étroit, elle rebondit d'un côté à l'autre.
Stratégie Momentum : comme faire rouler une boule de neige—souvenez-vous de la direction de la vitesse précédente, et l'inertie lui permet de franchir rapidement les petits nids-de-poule.
Stratégie Adam : non seulement elle a de l'inertie, mais elle ajuste aussi la foulée selon l'état de chaque portion de route—faites de petits pas dans les pentes raides, et de grandes enjambées sur terrain plat.
Compréhension intuitive
theta -= lr * v
v = beta2*v + (1-beta2)*g^2
theta -= lr * m_hat/(sqrt(v_hat)+eps)
Fonction de test : \(f(x, y) = 0.5x^2 + 5y^2\) — une longue vallée étroite où la direction x est douce et la direction y est raide.
Exercices pratiques Python
Exemple
def f(pos):
x, y = pos
return 0.5 * x**2 + 5 * y**2
def grad(pos):
x, y = pos
return np.array([x, 10 * y])
def sgd(start, lr=0.1, steps=60):
pos = np.array(start, dtype=float)
history = [pos.copy()]
for _ in range(steps):
pos = pos - lr * grad(pos)
history.append(pos.copy())
return np.array(history)
def momentum(start, lr=0.1, beta=0.9, steps=60):
pos = np.array(start, dtype=float)
v = np.zeros_like(pos)
history = [pos.copy()]
for _ in range(steps):
g = grad(pos)
v = beta * v + (1 - beta) * g
pos = pos - lr * v
history.append(pos.copy())
return np.array(history)
def adam(start, lr=0.3, beta1=0.9, beta2=0.999, eps=1e-8, steps=60):
pos = np.array(start, dtype=float)
m = np.zeros_like(pos)
v = np.zeros_like(pos)
history = [pos.copy()]
for t in range(1, steps + 1):
g = grad(pos)
m = beta1 * m + (1 - beta1) * g
v = beta2 * v + (1 - beta2) * (g ** 2)
m_hat = m / (1 - beta1 ** t)
v_hat = v / (1 - beta2 ** t)
pos = pos - lr * m_hat / (np.sqrt(v_hat) + eps)
history.append(pos.copy())
return np.array(history)
start = [4.0, 4.0]
results = {
"SGD": sgd(start, lr=0.1),
"Momentum": momentum(start, lr=0.1),
"Adam": adam(start, lr=0.3),
}
print("EXEMPLE comparaison de trois optimiseurs (point de départ [4,4]):\n")
for name, hist in results.items():
dists = np.linalg.norm(hist, axis=1)
mask = dists < 0.05
conv = (np.argmax(mask) if mask.any() else "non convergé")
n_osc = np.sum(np.diff(np.sign(hist[:, 1])) != 0)
print(f" {name:10s}: {str(conv):>6s} étapes pour converger, oscillation de y {n_osc} fois, perte={f(hist[-1]):.6f}")
EXAMPLE 三种优化器对比 (起点 [4,4]): SGD : 未收敛 步收敛, y震荡36次, 损失=0.000035 Momentum : 21 步收敛, y震荡6次, 损失=0.000000 Adam : 16 步收敛, y震荡0次, 损失=0.000000
Scénarios d'application en IA
| Scénario | Optimiseur recommandé | Raison |
|---|---|---|
| La plupart des tâches | Adam/AdamW | Adaptatif, convergence rapide, peu de paramètres à régler |
| Entraînement de Transformer | AdamW | GPT/BERT l'utilisent tous les deux |
| Lorsqu'une précision extrême est nécessaire | SGD+Momentum | La capacité de généralisation est parfois meilleure |