Adam ও AdamW
এই পাঠে যা শিখবেন
- Adam-এর তিন component — momentum, adaptive lr, bias correction
- RMSprop ও AdaGrad — Adam-এর parents
- Bias correction-এর গণিত
- L2 vs weight decay — AdamW-এর fix
- PyTorch-এ
torch.optim.Adam,AdamW
১ · Adam-এর তিন idea একসাথে
Adam ২০১৪-এর paper তিনটি পূর্ব-existing idea একসাথে combine করেছে:
- Momentum: gradient-এর exponential moving average।
- RMSprop: gradient-এর squared moving average — adaptive per-parameter scale।
- Bias correction: early-step underestimation fix।
২ · AdaGrad — adaptive lr-এর জন্ম
Duchi et al. (২০১১) AdaGrad propose করেছিলেন:
$$G_t = G_{t-1} + g_t^2, \quad w_t = w_{t-1} - \frac{\alpha}{\sqrt{G_t} + \epsilon} g_t$$
প্রতিটি parameter-এর জন্য আলাদা effective learning rate। Frequent gradient → bigger $G$ → smaller step। Rare gradient → bigger step। Sparse data-এ অসাধারণ।
সমস্যা: $G$ monotonically increases → learning rate eventually zero। Long training-এ stalled।
৩ · RMSprop — exponential decay
Hinton-এর Coursera lecture-এ propose (unpublished, ২০১২):
$$v_t = \beta v_{t-1} + (1-\beta) g_t^2, \quad w_t = w_{t-1} - \frac{\alpha}{\sqrt{v_t} + \epsilon} g_t$$
AdaGrad-এর running sum-এর জায়গায় exponential moving average — তাই learning rate vanish করে না। Modern adaptive optimizer-এর foundation।
৪ · Adam — full recipe
প্রতিটি step $t$-এ:
$m_t = \beta_1 m_{t-1} + (1-\beta_1) g_t$
$v_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2$
$\hat{m}_t = m_t / (1 - \beta_1^t)$
$\hat{v}_t = v_t / (1 - \beta_2^t)$
$w_t = w_{t-1} - \alpha \dfrac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}$
- $m$: momentum — past gradient-এর moving average।
- $v$: RMSprop component — past gradient²-এর moving average।
- $\hat{m}, \hat{v}$: bias correction — initial steps-এ underestimate fix।
- $\alpha / \sqrt{\hat{v}}$: per-parameter adaptive learning rate।
৫ · Bias correction — কেন দরকার
Initial $m_0 = v_0 = 0$। Step ১-এ:
$m_1 = (1-\beta_1) g_1 \approx 0.1 g_1$ — actual gradient-এর ১/১০!
Without correction: early steps tiny effective gradient। Correction $/(1-\beta_1^t)$ — step ১-এ ÷০.১ = ×১০ — full gradient ফিরে।
$t \to \infty$-তে $\beta_1^t \to 0$, correction $\to 1$ — vanish। Early-step issue specific।
৬ · Adam — PyTorch
import torch
import torch.nn as nn
torch.manual_seed(0)
model = nn.Sequential(
nn.Linear(10, 64),
nn.ReLU(),
nn.Linear(64, 1),
)
opt = torch.optim.Adam(
model.parameters(),
lr=1e-3,
betas=(0.9, 0.999),
eps=1e-8,
weight_decay=0, # default — pure Adam
)
# Training pattern
x = torch.randn(32, 10)
y = torch.randn(32, 1)
for step in range(5):
pred = model(x)
loss = ((pred - y) ** 2).mean()
opt.zero_grad()
loss.backward()
opt.step()
print(f"step {step}: loss = {loss.item():.4f}")
৭ · Scratch Adam — NumPy
import numpy as np
class Adam:
def __init__(self, lr=1e-3, b1=0.9, b2=0.999, eps=1e-8):
self.lr = lr
self.b1, self.b2 = b1, b2
self.eps = eps
self.m = None
self.v = None
self.t = 0
def step(self, w, g):
if self.m is None:
self.m = np.zeros_like(w)
self.v = np.zeros_like(w)
self.t += 1
self.m = self.b1 * self.m + (1 - self.b1) * g
self.v = self.b2 * self.v + (1 - self.b2) * g * g
m_hat = self.m / (1 - self.b1 ** self.t)
v_hat = self.v / (1 - self.b2 ** self.t)
return w - self.lr * m_hat / (np.sqrt(v_hat) + self.eps)
# Test on quadratic
opt = Adam(lr=0.1)
w = np.array([5.0, 1.0])
for i in range(50):
g = np.array([2 * w[0], 200 * w[1]]) # ravine grad
w = opt.step(w, g)
print(f"Final w: {w}, loss: {w[0]**2 + 100*w[1]**2:.6f}")
৮ · L2 regularization vs weight decay — AdamW
Classical SGD-এ "L2 regularization" = "weight decay" — equivalent। কিন্তু Adam-এ এই দু'টো ভিন্ন!
L2 regularization: loss-এ $\lambda \|w\|^2$ যোগ। Gradient-এ $\lambda w$ যোগ হয়। Adam-এ এই extra gradient-ও $v$-এর সাথে scale হয় — weight কম update পায়।
Weight decay (proper): update-এর শেষে $w \leftarrow w - \alpha \lambda w$ — adaptive scaling-এর বাইরে। AdamW (Loshchilov-Hutter ২০১৭) এই fix।
import torch.nn as nn
import torch.optim as optim
model = nn.Linear(10, 1)
# Buggy Adam — weight_decay actually adds to gradient (L2)
opt_bad = optim.Adam(model.parameters(), lr=1e-3, weight_decay=0.01)
# Correct: AdamW — decoupled weight decay
opt_good = optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)
# Modern Hugging Face, BERT, GPT — সবই AdamW
print("Use AdamW for modern DL training")
৯ · Hyperparameter cheatsheet
- $\alpha$: 1e-3 default; 3e-4 large model; 5e-5 fine-tuning।
- $\beta_1$: 0.9 default; 0.95 for some Transformer।
- $\beta_2$: 0.999 default; 0.95 — large model (gradient noisier — quicker forget)।
- $\epsilon$: 1e-8 default; 1e-6 mixed-precision-এ।
- weight_decay: 0.01-0.1 modern transformer; 1e-4 vision।
১০ · Adam-এর critique
- Generalization gap: SGD-এর চেয়ে কখনো test accuracy কম (Wilson ২০১৭)।
- Convergence proof flaw: Reddi et al. (২০১৮) "On the convergence of Adam" — counterexample। AMSGrad fix।
- Memory overhead: $m$ ও $v$ — 2x parameter memory।
- Tuning illusion: "default works"-এর মিথ্যা সান্ত্বনা — domain-specific tune still needed।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ Adam-এর "convergence proof flaw" কী? AMSGrad কীভাবে fix করে — তবু কেন AMSGrad widely adopted হয়নি?
ML history-র সবচেয়ে famous "embarrassing fix"। ICLR ২০১৮ best paper Reddi-Kale-Kumar এর "On the convergence of Adam and beyond"।
The flaw:
- Adam-এর convergence proof (২০১৪) assumed $\hat{v}_t$ monotone increasing।
- Counterexample: $\hat{v}_t$ can decrease since EMA of $g^2$।
- Result — Adam-এর effective lr non-monotone।
- Specific cases-এ converge না বা wrong direction।
Toy counterexample:
- Synthetic problem: $f_t(w) = C w$ যদি $t \mod 3 = 1$, else $-w$।
- Optimum: $w = -1$।
- Adam — $w = +1$-এ converge!
- Vanilla SGD ঠিকভাবে converge।
AMSGrad fix:
- $\hat{v}_t = \max(\hat{v}_{t-1}, v_t)$ — monotone enforce।
- Convergence proof now valid।
- Theoretical guarantee restored।
Why AMSGrad didn't take over:
- Empirical performance: sometimes worse than Adam।
- Practical issue rare: real DL training-এ counterexample-like dynamic uncommon।
- Memory overhead: additional $\hat{v}_{\max}$ store।
- Adam habit: ecosystem already established।
- Other fixes: RAdam, AdaBound — alternatives।
Recent perspective:
- Bock et al. (২০১৯) — flaw গুরুত্বপূর্ণ but practical impact small।
- Modern variants (AdamW, AMSGrad) acceptable।
- Theoretical hygiene matters for research, less for production।
Lessons:
- "Most cited paper" → most scrutinized → flaws found।
- Theoretical proof বিবরণ critical — assumption check।
- Empirical success ≠ theoretical correctness।
- Fix-করা paper নিজেই influential।
Other Adam variants:
- RAdam: rectified Adam — early-step variance issue address।
- AdaBelief: $v$ uses $(g - m)^2$ instead of $g^2$।
- NovoGrad: NVIDIA's normalize-first optimizer।
- Lion (২০২৩): sign of momentum — memory ÷2।
- Sophia (২০২৩): diagonal Hessian estimate।
মূল উপলব্ধি: Adam flawed-but-works। AMSGrad correct-but-rarely-better। Practical DL "good enough" theoretical engineering-এর চেয়ে important। Research-এ correct theory, production-এ tested practice — দু'টোই value।
প্র ০২ L2 regularization আর weight decay — SGD-এ identical, Adam-এ ভিন্ন। Math-এ exactly কেন? AdamW কীভাবে fix করে?
সাত বছর ধরে DL community-তে hidden bug। Loshchilov-Hutter ২০১৭-এ explicitly identify।
SGD case — equivalent:
- L2 reg: loss = base + $\frac{\lambda}{2}\|w\|^2$।
- Gradient: $g + \lambda w$।
- SGD update: $w \leftarrow w - \eta(g + \lambda w) = (1 - \eta\lambda) w - \eta g$।
- Direct decay: $w \leftarrow w - \eta g - \eta \lambda w$ — exactly same।
Adam case — different:
- L2 reg: gradient $g + \lambda w$ → fed into $m, v$।
- $m = \beta_1 m + (1-\beta_1)(g + \lambda w)$।
- $v = \beta_2 v + (1-\beta_2)(g + \lambda w)^2$।
- Update: $\hat{m}/\sqrt{\hat{v}}$ — weight decay scaled by $1/\sqrt{v}$।
- Large gradient parameter — small effective decay।
- Small gradient parameter — large effective decay।
AdamW fix:
- Decay applied directly: $w \leftarrow w - \eta(\hat{m}/\sqrt{\hat{v}}) - \eta\lambda w$।
- Decay decoupled from adaptive scaling।
- Each parameter decays uniformly।
Why this matters:
- Adam + L2 — large weight grow disproportionately।
- AdamW — proper regularization।
- Generalization-এ measurable improvement।
Empirical evidence:
- Loshchilov-Hutter — CIFAR-100, ImageNet improvement।
- BERT (Devlin ২০১৮) — explicitly AdamW।
- Hugging Face default AdamW।
- Modern Transformer training — AdamW universal।
PyTorch implementation difference:
# Adam with weight_decay (BUGGY for adaptive)
optim.Adam(params, weight_decay=0.01)
# AdamW (correct)
optim.AdamW(params, weight_decay=0.01)
# Math difference:
# Adam: g_eff = g + λw, then adaptive
# AdamW: w -= adaptive(g) + ηλw
Hyperparameter difference:
- Adam-এর effective weight decay-অনিয়মিত — λ harder to tune।
- AdamW-এর λ direct interpretation — easy to tune।
- AdamW-এ typical λ = 0.01-0.1, Adam-এ ভিন্ন scale।
Why hidden so long:
- Default
weight_decay=0Adam-এ — issue invisible। - Vision-এ SGD dominant — Adam-এর regularization rarely tested।
- Empirical tuning hide subtle issues।
Ecosystem migration:
- PyTorch 1.0 — separate AdamW class।
- TF 2.x —
AdamWin addons। - JAX/Flax — Optax library।
Modern recommendation:
- Always use AdamW (not Adam) when weight_decay > 0।
- Vision: AdamW, weight_decay=1e-4।
- Transformer: AdamW, weight_decay=0.1।
- Fine-tune: AdamW, weight_decay=0.01।
মূল উপলব্ধি: Subtle math, big practical impact। DL field-এ এমন hidden bug research-এ দেখা যায়। Loshchilov-Hutter-এর insight — careful theoretical analysis production-এ pay off। আজকের সব major LLM (GPT, LLaMA, Claude) — AdamW-এ trained।
প্র ০৩ "3e-4 is the best learning rate for Adam, hands down" — Karpathy-এর famous tweet। এই specific number-এর behind কী intuition? কখন এটি change করতে হবে?
DL community-র সবচেয়ে famous one-liner। ২০১৬-এ Karpathy এই tweet করেছিলেন — joke ছিল কিছুটা, কিন্তু empirically ভাল default।
Why 3e-4 (≈ 0.0003):
- Empirical sweet spot: CV, NLP, RL — most cases-এ converge।
- Default-এর জন্য balance: too small slow, too large divergence।
- Adam-এর adaptive scaling: per-parameter normalization-এ scale-invariant।
Math behind 3e-4:
- Adam-এ effective per-step update: $\eta / \sqrt{\hat{v}}$।
- $\hat{v} \approx g^2$ — typical gradient ~0.1, $\sqrt{\hat{v}} \approx 0.1$।
- Effective: $0.0003 / 0.1 = 0.003$ — reasonable parameter step।
- Vanilla SGD-এ same effect পেতে $\eta \approx 0.01$।
When 3e-4 works:
- Standard architectures (CNN, RNN, Transformer)।
- Standard initialization।
- Mid-size models (10M-1B parameters)।
- Standard datasets (CIFAR, ImageNet, GLUE)।
- From-scratch training।
When to use lower lr:
- Fine-tuning pre-trained: 1e-5 to 5e-5।
- BERT fine-tune: 2e-5।
- GPT fine-tune: 1e-5।
- Vision fine-tune: 1e-4।
- Very large model: 1e-4 (LLaMA 70B)।
- Sensitive layers: embeddings often need lower lr।
- Late-stage training: cosine decay → 0।
When to use higher lr:
- Small model + small data: 1e-3 to 3e-3।
- Linear probing: last layer only — 1e-2।
- RNN-এর recurrent weight: sometimes 1e-3।
Layer-wise lr (sometimes):
- Pre-trained backbone — low lr।
- New head — high lr।
- "discriminative fine-tuning" — Howard-Ruder (২০১৮)।
LR scheduling:
- Cosine decay: $\eta_t = \eta_0 (1 + \cos(t\pi/T))/2$ — Transformer-এ universal।
- Warmup: first 1-10% steps — linear ramp।
- Step decay: /10 at fixed epochs — old-school CV।
- OneCycle: Smith ২০১৭ — start small, peak, decay।
LR finder (Smith ২০১৭):
- 1e-7 থেকে 10 পর্যন্ত exponential sweep।
- Loss curve plot।
- Steepest descent-এর just before peak — optimal।
Modern LLM training:
- GPT-3 175B: 6e-5।
- LLaMA-2 70B: 1.5e-4।
- BERT base: 1e-4।
- Vision Transformer: 1e-3।
Practical wisdom:
- Start with 3e-4, scan 1e-4 to 1e-3 if time।
- Plot loss vs lr — pick steepest stable region।
- Always add warmup for stability।
- Always add decay for final convergence।
মূল উপলব্ধি: 3e-4 — empirical Schelling point, math-এ explainable। Standard scenario-এ default ভাল। Domain ও model size-এ adjust করতে হবে। Karpathy joke serious truth — most experimentation 3e-4 থেকে শুরু করা wise।
প্র ০৪ আপনি একটি 7B parameter LLaMA fine-tune করছেন। Adam memory overhead 2x parameter — out of memory। কী options আছে?
Modern LLM fine-tuning-এর কেন্দ্রীয় challenge। Multiple memory-efficient techniques।
The memory math:
- 7B parameters × FP32 (4 bytes) = 28 GB weights।
- Adam optimizer states (m, v): 2 × 28 = 56 GB।
- Gradients: 28 GB।
- Activations: variable (10-50 GB)।
- Total: 122-172 GB — A100 80GB এ অসম্ভব।
Solution category 1: Quantize optimizer states
- 8-bit Adam (Dettmers ২০২২): $m, v$ in INT8 → 4x save।
bitsandbytes.optim.AdamW8bit।- Quality near-identical to FP32 Adam।
- 32 → 8 bit accumulator → trick।
Solution category 2: Mixed precision
- Weight FP32 master copy, computation FP16/BF16।
- Memory ÷ 2 for activations।
torch.cuda.ampautomatic।- BF16 over FP16 (better range)।
Solution category 3: Quantization
- QLoRA (Dettmers ২০২৩):
- Base model 4-bit (NF4)।
- LoRA adapter 16-bit।
- 7B fits in 6 GB।
Solution category 4: Parameter-efficient fine-tuning
- LoRA (Hu ২০২১):
- $W = W_0 + BA$ (B, A small rank)।
- Only $B, A$ train — original frozen।
- ~0.1% parameters trainable।
- Adam state on these only।
- Prefix tuning, P-tuning: only soft prompts।
- Adapters: small inserted modules।
Solution category 5: ZeRO / FSDP
- Optimizer states sharded across GPUs।
- ZeRO-1: optimizer state shard।
- ZeRO-2: + gradient shard।
- ZeRO-3: + parameter shard।
- DeepSpeed, PyTorch FSDP।
Solution category 6: Gradient accumulation
- Small per-step batch।
- Multiple steps accumulate before update।
- Memory friendly, longer training।
Solution category 7: Activation checkpointing
- Discussed in L10।
- Activation memory ÷ 2-4।
- 30% extra compute।
Solution category 8: Lighter optimizer
- SGD + momentum: only 1x parameter overhead।
- Lion: only momentum, no second moment — half Adam memory।
- Sophia: diagonal Hessian — different trade-off।
Practical recipe for 7B on consumer GPU (24 GB):
- QLoRA + 4-bit base model।
- BF16 mixed precision।
- Gradient accumulation 8x।
- Activation checkpointing।
- LoRA rank 16-64।
- Hugging Face PEFT library।
Code example:
from peft import LoraConfig, get_peft_model
from transformers import BitsAndBytesConfig
bnb = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4")
model = AutoModelForCausalLM.from_pretrained("llama2-7b", quantization_config=bnb)
lora = LoraConfig(r=16, target_modules=["q_proj", "v_proj"])
model = get_peft_model(model, lora)
# 7B model — only ~80M params trainable
optim = bnb.optim.AdamW8bit(model.parameters(), lr=1e-4)
Bangladesh perspective:
- Consumer GPU (RTX 3090/4090) — QLoRA enables 13B fine-tune।
- Free Colab — LoRA on Llama 7B।
- Bangla LLM fine-tune very accessible now।
মূল উপলব্ধি: Memory hierarchy DL training-এ central। 7B model accessible — পাঁচ বছর আগে impossible। Quantization + parameter-efficient + sharding combination revolutionary। Bangladesh-এ Bangla LLM build করা — এই tools-এ democratized। যথাযথ প্রয়োগ-এ — modest hardware-এ frontier capability।
অনুশীলন
-
Math: $\beta_1 = 0.9$, step ১০-এ bias correction factor কত?
$1 - 0.9^{10} = 1 - 0.3487 = 0.6513$। Correction = $\hat{m}_{10} = m_{10}/0.6513$।
-
Code: AdamW optimizer setup করুন — lr=3e-4, betas=(0.9, 0.95), weight_decay=0.1।
opt = torch.optim.AdamW( model.parameters(), lr=3e-4, betas=(0.9, 0.95), weight_decay=0.1, eps=1e-8, ) -
Compare: একটি toy regression-এ Adam vs SGD compare করুন — কে দ্রুত converge?
import torch, torch.nn as nn torch.manual_seed(0) X = torch.randn(200, 5) y = (X * torch.tensor([1.,2.,3.,-1.,-2.])).sum(1, keepdim=True) for optname in ['SGD', 'Adam']: m = nn.Linear(5, 1) opt = torch.optim.SGD(m.parameters(), lr=0.01) if optname=='SGD' \ else torch.optim.Adam(m.parameters(), lr=0.01) for i in range(50): loss = ((m(X) - y) ** 2).mean() opt.zero_grad(); loss.backward(); opt.step() print(f"{optname} final loss: {loss.item():.4f}")সাধারণত Adam দ্রুত converge করে এই toy setup-এ।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ১৪ · Vanishing/Exploding gradient পরবর্তী পাঠ Adam কেন এই সমস্যা mitigate করে।
- পাঠ ১২ · Momentum ও Nesterov আগের পাঠ Adam-এর momentum component।
- পাঠ ১৫ · Batch Normalization এই পাঠের সাথে সম্পর্কিত Optimizer-এর সাথে দলবেঁধে কাজ করে।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।