Mundarija (21)
- 1. Kirish va motivatsiya
- 2. Nazariya — chuqur tushuntirish
- 2.1. Gradient tushish
- 2.2. Batch, mini-batch, stoxastik
- 2.3. Moment
- 2.4. Adaptiv usullar
- 2.5. Bias tuzatish nima uchun
- 2.6. O'rganish tezligi jadvali
- 2.7. Tuzoqlar
- 3. Tez ma'lumotnoma
- 4. Batafsil misollar
- Misol 1 — O'rganish tezligi
- Misol 2 — Batch hajmi va shovqin
- Misol 3 — Optimizatorlarni taqqoslash
- Misol 4 — Jadval va amaliy taqqoslash
- 5. To'g'ri va noto'g'ri tushunishlar
- 6. Keng tarqalgan xatolar va yechimlari
- 7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 8. Eng yaxshi amaliyotlar
- 9. Amaliy topshiriq
- Xulosa
20.7-dars: Gradient tushish va optimizatorlar
20-QISM — NEYRON TARMOQLAR · 7-dars
1. Kirish va motivatsiya
Gradientni bilamiz. Endi savol: qancha qadam tashlash kerak?
Bu savol ko'ringanidan ancha chuqur. Gradient faqat yo'nalishni beradi — u ham cheksiz kichik masofada to'g'ri. Qadam kattaligini tanlash esa butun o'rgatishni belgilaydi: juda kichik bo'lsa asrlab o'rganadi, juda katta bo'lsa minimumdan sakrab o'tib, NaN ga ketadi.
Shuning uchun optimizator paydo bo'ldi: gradientdan qadamga o'tishning oqilona usuli. SGD dan Adam gacha bo'lgan yo'lda uchta g'oya qo'shildi — moment (inersiya), adaptiv qadam (har parametrga o'z tezligi) va bias tuzatish.
Bu darsda har bir g'oyani alohida ko'ramiz va ularni bir xil vazifada taqqoslaymiz. Shuningdek o'rganish tezligi jadvallarini (schedule) ko'rib chiqamiz — chunki amalda lr ni doimiy qoldirish deyarli hech qachon eng yaxshi tanlov emas.
Real vaziyat. Jamoa Adam bilan model qurdi va natija SGD dan yomon chiqdi. Sabab: Adam ning sukut lr = 0.001 ular uchun juda kichik edi, SGD da esa ular 0.1 ni tanlab olishgan. lr ni sozlagach Adam ustun chiqdi. Optimizatorni lr siz taqqoslash — bekor ish.
Bu darsda qadam tanlashni va optimizatorlarni o'rganamiz.
Bu darsda:
- Gradient tushish va o'rganish tezligi
- Mini-batch va shovqin
- Moment
- Adaptiv usullar: RMSProp, Adam
- Jadval (schedule)
- Tuzoqlar
- Amaliy: optimizator tanlash
ℹ Misollar real numpy/sklearn bilan (Python 3.14).
2. Nazariya — chuqur tushuntirish
2.1. Gradient tushish
QADAM: w <- w - lr * dL/dw
lr JUDA KICHIK:
har qadam arzimas, minimalgacha minglab davr
lr TO'G'RI:
loss barqaror kamayadi
lr JUDA KATTA:
minimumdan sakrab o'tadi, loss o'sadi yoki NaN
KVADRATIK FUNKSIYADA CHEGARA:
L(w) = 0.5 * a * w^2 uchun
lr < 2/a bo'lsa yaqinlashadi
lr > 2/a bo'lsa uzoqlashadi
TARMOQDA: a - Gessian matritsasining eng katta xos qiymati
uni hisoblash qimmat -> lr TAJRIBA bilan tanlanadi lr — eng muhim giperparametr; qolganlarining hammasidan ko'proq ta'sir qiladi.
2.2. Batch, mini-batch, stoxastik
TO'LIQ BATCH (batch = N):
gradient ANIQ, har qadam qimmat
tekis yo'l, lokal minimumda qolib ketishi mumkin
STOXASTIK (batch = 1):
gradient juda shovqinli, har qadam arzon
shovqin lokal minimumdan chiqishga yordam beradi
MINI-BATCH (batch = 32..512):
amaliyotdagi standart
matritsa amallaridan foydalanadi + foydali shovqin qoladi
GRADIENT SHOVQINI ~ 1/sqrt(batch)
batch 4x katta -> shovqin 2x kichik
EMPIRIK QOIDA: batch ni 2x oshirsangiz, lr ni ham ~2x oshiring
(yoki sqrt(2)x - manbalar kelishmaydi)Mini-batch shovqini — bepul regularizatsiya; juda katta batch ko'pincha umumlashtirishni yomonlashtiradi.
2.3. Moment
MUAMMO: uzun, tor "jarlik" da gradient tushish ZIG-ZAG qiladi
tik devorlar bo'ylab tebranadi, jarlik bo'ylab sekin siljiydi
MOMENT (Polyak 1964):
v <- beta * v + dL/dw
w <- w - lr * v
beta = 0.9 -> o'rtacha ~10 qadam "eslanadi"
TA'SIRI:
bir yo'nalishdagi gradientlar YIG'ILADI -> tezlashadi
tebranayotgan gradientlar BEKOR BO'LADI -> tinchlanadi
NESTEROV varianti: gradientni "oldinga qarab" hisoblaydi
amalda biroz yaxshiroqMoment — inersiya: bir xil yo'nalishda harakat tezlashadi, tebranish so'nadi.
2.4. Adaptiv usullar
MUAMMO: turli parametrlar turli masshtabda
ba'zilarida gradient 1e-1, ba'zilarida 1e-5
BITTA lr ikkalasiga ham mos kelmaydi
ADAGRAD: s <- s + g^2; w <- w - lr * g / (sqrt(s) + eps)
kamchilik: s o'sib boradi -> qadam nolga tushadi
RMSPROP: s <- rho*s + (1-rho)*g^2; w <- w - lr*g/(sqrt(s)+eps)
eksponensial o'rtacha -> s to'yinmaydi
ADAM (Kingma & Ba 2014) = MOMENT + RMSPROP + BIAS TUZATISH:
m <- b1*m + (1-b1)*g (birinchi moment)
s <- b2*s + (1-b2)*g^2 (ikkinchi moment)
m_hat = m / (1 - b1^t) (bias tuzatish)
s_hat = s / (1 - b2^t)
w <- w - lr * m_hat / (sqrt(s_hat) + eps)
sukut: b1=0.9, b2=0.999, eps=1e-8, lr=0.001Adam — uch g'oyaning birlashmasi; shuning uchun u sukut tanlov bo'lib qolgan.
2.5. Bias tuzatish nima uchun
m ni NOL bilan boshlaymiz. Birinchi qadamda:
m = 0.9*0 + 0.1*g = 0.1*g <- haqiqiy gradientning 10% i!
Bu boshida qadamlarni sun'iy kichik qiladi.
TUZATISH: m_hat = m / (1 - 0.9^t)
t=1: m / 0.1 = g <- to'g'ri
t=10: m / 0.651
t=100: m / 0.99997 ~ m <- ta'siri yo'qoladi
Bias tuzatish faqat BIRINCHI o'nlab qadamda muhim,
lekin o'sha qadamlar butun o'rgatishning yo'nalishini belgilaydiBias tuzatish — boshlanishdagi sekinlikni yo'q qiladi, keyin o'z-o'zidan so'nadi.
2.6. O'rganish tezligi jadvali
NIMA UCHUN: boshida katta qadam (tez harakat),
oxirida kichik qadam (aniq sozlash)
STEP: har K davrda lr ni gamma ga ko'paytirish
EXPONENTIAL: lr_t = lr_0 * gamma^t
COSINE: lr_t = lr_min + 0.5*(lr_0-lr_min)*(1+cos(pi*t/T))
WARMUP: birinchi bir necha davr lr ni 0 dan oshirish
(transformerlarda MAJBURIY - 26-qism)
ONE-CYCLE: warmup + cosine pasayish (juda samarali)
AMALIY: cosine + qisqa warmup - ko'p holatda eng yaxshi boshlanishJadval bepul yaxshilanish: bir necha qator kod, sezilarli natija.
2.7. Tuzoqlar
Asosiy tuzoqlar: optimizatorlarni bir xil lr bilan taqqoslash; Adam uchun SGD ning lr ini ishlatish; gradientni tozalashni unutish (torch da zero_grad); batch ni oshirib lr ni o'zgartirmaslik; lr ni umuman sozlamaslik; jadvalni validatsiya ballidan mustaqil tanlash; weight decay ni Adam ga to'g'ridan-to'g'ri qo'shish (AdamW kerak).
3. Tez ma'lumotnoma
import numpy as np
# SGD + moment
v = np.zeros_like(w)
v = beta * v + g
w -= lr * v
# RMSProp
s = rho * s + (1 - rho) * g ** 2
w -= lr * g / (np.sqrt(s) + 1e-8)
# Adam
m = b1 * m + (1 - b1) * g
s = b2 * s + (1 - b2) * g ** 2
w -= lr * (m / (1 - b1 ** t)) / (np.sqrt(s / (1 - b2 ** t)) + 1e-8)
# cosine jadval
lr_t = lr_min + 0.5 * (lr_0 - lr_min) * (1 + np.cos(np.pi * t / T))
# mini-batch
for boshi in range(0, len(X), batch):
idx = tartib[boshi:boshi + batch]Optimizator xulosasi
lr - eng muhim giperparametr
batch 32..512, shovqin ~ 1/sqrt(batch)
moment: inersiya, beta=0.9
Adam = moment + adaptiv + bias tuzatish
jadval: cosine + warmup4. Batafsil misollar
Misollar real numpy/sklearn bilan (Python 3.14).
Misol 1 — O'rganish tezligi
"""lr ning ta'siri: yaqinlashish, sekinlik, portlash (real numpy)."""
import numpy as np
def main() -> None:
print("=== 1. Kvadratik funksiyada nazariy chegara ===")
a = 2.0
print(f" L(w) = 0.5 * {a} * w^2, chegara lr < 2/a = {2 / a}")
print(f" {'lr':>7} {'50 qadamdan keyin w':>22} {'holat':>12}")
for lr in [0.05, 0.4, 0.9, 1.0, 1.05]:
w = 1.0
for _ in range(50):
w = w - lr * a * w
if not np.isfinite(w):
break
holat = "yaqinlashdi" if abs(w) < 1e-3 else (
"sekin" if np.isfinite(w) and abs(w) < 1 else "uzoqlashdi")
print(f" {lr:>7.2f} {w:>22.6e} {holat:>12}")
print("\n=== 2. Ikki o'lchovli 'jarlik' ===")
A = np.array([20.0, 1.0]) # bir o'q 20x tik
print(f" L(w) = 0.5*(20*w1^2 + 1*w2^2)")
print(f" chegara: lr < 2/20 = 0.1")
print(f" {'lr':>7} {'qadamlar':>10} {'|w|':>12} {'izoh'}")
for lr in [0.005, 0.05, 0.09, 0.11]:
w = np.array([1.0, 1.0])
qadam = 0
# lr chegaradan katta bo'lsa w ATAYLAB cheksizlikka ketadi
with np.errstate(over="ignore", invalid="ignore"):
for qadam in range(1, 2001):
w = w - lr * A * w
if not np.isfinite(w).all() or np.linalg.norm(w) < 1e-4:
break
with np.errstate(over="ignore", invalid="ignore"):
norma = float(np.linalg.norm(w))
izoh = ("yaqinlashdi" if norma < 1e-4
else "portladi" if not np.isfinite(w).all() else "sekin")
print(f" {lr:>7.3f} {qadam:>10} {norma:>12.3e} {izoh}")
print(" tik o'q lr ni CHEKLAYDI, yassi o'q sekin harakatlanadi")
print("\n=== 3. Real loss da lr izlash ===")
rng = np.random.default_rng(0)
n, d = 500, 10
X = rng.normal(0, 1, (n, d))
w_haqiqiy = rng.normal(0, 1, d)
y = X @ w_haqiqiy + rng.normal(0, 0.5, n)
print(f" {'lr':>8} {'100 qadamdan keyin loss':>26} {'holat':>12}")
for lr in [1e-4, 1e-3, 1e-2, 1e-1, 0.5, 1.0]:
w = np.zeros(d)
with np.errstate(over="ignore", invalid="ignore"):
for _ in range(100):
g = 2 * X.T @ (X @ w - y) / n
w = w - lr * g
if not np.isfinite(w).all():
break
loss = (float(np.mean((X @ w - y) ** 2))
if np.isfinite(w).all() else float("inf"))
holat = ("portladi" if not np.isfinite(loss)
else "yaxshi" if loss < 0.3 else "sekin")
print(f" {lr:>8.0e} {loss:>26.6f} {holat:>12}")
print("\n=== 4. lr izlash egri chizig'i ===")
print(" kichik lr dan boshlab asta oshiramiz (LR range test):")
print(f" {'lr':>9} {'loss (10 qadam)':>18}")
for lr in np.logspace(-4, 0.3, 9):
w = np.zeros(d)
for _ in range(10):
g = 2 * X.T @ (X @ w - y) / n
w = w - lr * g
loss = (np.mean((X @ w - y) ** 2)
if np.isfinite(w).all() else float("inf"))
print(f" {lr:>9.4f} {loss:>18.4f}")
print(" eng past nuqtadan 3-10x kichigini tanlash odat")
print("\n=== 5. Qadamlar traektoriyasi ===")
print(f" jarlikda lr = 0.09 bilan birinchi qadamlar:")
w = np.array([1.0, 1.0])
print(f" {'qadam':>6} {'w1':>12} {'w2':>12}")
for i in range(1, 9):
w = w - 0.09 * A * w
print(f" {i:>6} {w[0]:>12.6f} {w[1]:>12.6f}")
print(" ⭐ w1 tebranadi, w2 sekin siljiydi - moment shuni tuzatadi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Kvadratik funksiyada nazariy chegara ===
L(w) = 0.5 * 2.0 * w^2, chegara lr < 2/a = 1.0
lr 50 qadamdan keyin w holat
0.05 5.153775e-03 sekin
0.40 1.125900e-35 yaqinlashdi
0.90 1.427248e-05 yaqinlashdi
1.00 1.000000e+00 uzoqlashdi
1.05 1.173909e+02 uzoqlashdi
=== 2. Ikki o'lchovli 'jarlik' ===
L(w) = 0.5*(20*w1^2 + 1*w2^2)
chegara: lr < 2/20 = 0.1
lr qadamlar |w| izoh
0.005 1838 9.973e-05 yaqinlashdi
0.050 180 9.778e-05 yaqinlashdi
0.090 98 9.684e-05 yaqinlashdi
0.110 2000 inf sekin
tik o'q lr ni CHEKLAYDI, yassi o'q sekin harakatlanadi
=== 3. Real loss da lr izlash ===
lr 100 qadamdan keyin loss holat
1e-04 8.280343 sekin
1e-03 5.724921 sekin
1e-02 0.381762 sekin
1e-01 0.254561 yaxshi
5e-01 0.254561 yaxshi
1e+00 27495031550720895575691757889681096704.000000 sekin
=== 4. lr izlash egri chizig'i ===
kichik lr dan boshlab asta oshiramiz (LR range test):
lr loss (10 qadam)
0.0001 8.5945
0.0003 8.5078
0.0012 8.2156
0.0041 7.2825
0.0141 4.8073
0.0487 1.2208
0.1679 0.2569
0.5788 0.2546
1.9953 1865905289412.8137
eng past nuqtadan 3-10x kichigini tanlash odat
=== 5. Qadamlar traektoriyasi ===
jarlikda lr = 0.09 bilan birinchi qadamlar:
qadam w1 w2
1 -0.800000 0.910000
2 0.640000 0.828100
3 -0.512000 0.753571
4 0.409600 0.685750
5 -0.327680 0.624032
6 0.262144 0.567869
7 -0.209715 0.516761
8 0.167772 0.470253
⭐ w1 tebranadi, w2 sekin siljiydi - moment shuni tuzatadiNima ko'rsatdi: 2.1-bo'lim.
Misol 2 — Batch hajmi va shovqin
"""Mini-batch gradienti aniq gradientdan qancha farq qiladi."""
import numpy as np
def main() -> None:
rng = np.random.default_rng(0)
n, d = 4000, 8
X = rng.normal(0, 1, (n, d))
w_haqiqiy = rng.normal(0, 1, d)
y = X @ w_haqiqiy + rng.normal(0, 1.0, n)
w = rng.normal(0, 0.5, d)
def gradient(idx):
Xb, yb = X[idx], y[idx]
return 2 * Xb.T @ (Xb @ w - yb) / len(idx)
aniq = gradient(np.arange(n))
print("=== 1. Batch hajmi va gradient shovqini ===")
print(f" {'batch':>7} {'o_rtacha burchak':>18} "
f"{'nisbiy xato':>13} {'1/sqrt(b)':>11}")
for b in [1, 4, 16, 64, 256, 1024]:
burchaklar, xatolar = [], []
for _ in range(60):
idx = rng.choice(n, b, replace=False)
g = gradient(idx)
kos = (g @ aniq
/ (np.linalg.norm(g) * np.linalg.norm(aniq)))
burchaklar.append(np.degrees(np.arccos(np.clip(kos, -1, 1))))
xatolar.append(np.linalg.norm(g - aniq)
/ np.linalg.norm(aniq))
print(f" {b:>7} {np.mean(burchaklar):>17.2f}° "
f"{np.mean(xatolar):>13.4f} {1 / np.sqrt(b):>11.4f}")
print(" nisbiy xato ~ 1/sqrt(batch) ga mutanosib")
print("\n=== 2. Bir davrda necha qadam ===")
print(f" {'batch':>7} {'qadamlar/davr':>15} "
f"{'gradient hisoblari':>20}")
for b in [1, 32, 256, 4000]:
print(f" {b:>7} {int(np.ceil(n / b)):>15} {n:>20}")
print(" hisob hajmi BIR XIL, qadamlar soni boshqa")
print("\n=== 3. Bir xil davrda natija ===")
rng2 = np.random.default_rng(1)
print(f" {'batch':>7} {'lr':>8} {'5 davrdan keyin loss':>22}")
for b, lr in [(1, 0.002), (32, 0.01), (256, 0.05), (4000, 0.05)]:
ww = np.zeros(d)
for _ in range(5):
tartib = rng2.permutation(n)
for boshi in range(0, n, b):
idx = tartib[boshi:boshi + b]
g = 2 * X[idx].T @ (X[idx] @ ww - y[idx]) / len(idx)
ww = ww - lr * g
print(f" {b:>7} {lr:>8.3f} "
f"{np.mean((X @ ww - y) ** 2):>22.6f}")
print(" kichik batch ko'p qadam tashlaydi - tezroq yaqinlashadi")
print("\n=== 4. Batch va lr birga o'zgaradi ===")
print(f" {'batch':>7} {'lr = 0.01':>12} {'lr ~ batch':>12}")
for b in [32, 64, 128, 256]:
natijalar = []
for lr in [0.01, 0.01 * b / 32]:
ww = np.zeros(d)
r = np.random.default_rng(2)
for _ in range(5):
tartib = r.permutation(n)
for boshi in range(0, n, b):
idx = tartib[boshi:boshi + b]
g = (2 * X[idx].T @ (X[idx] @ ww - y[idx])
/ len(idx))
ww = ww - lr * g
natijalar.append(np.mean((X @ ww - y) ** 2))
print(f" {b:>7} {natijalar[0]:>12.6f} {natijalar[1]:>12.6f}")
print(" batch oshganda lr ni ham oshirish kerak")
print("\n=== 5. Shovqin foydali bo'lgan holat ===")
def egri(w):
return float(w ** 2 + 3 * np.sin(4 * w) ** 2)
def egri_grad(w):
return float(2 * w + 24 * np.sin(4 * w) * np.cos(4 * w))
print(" L(w) = w^2 + 3*sin(4w)^2 - ko'p lokal minimum")
print(f" {'shovqin':>9} {'yakuniy w':>12} {'L(w)':>10}")
for shovqin in [0.0, 0.5, 2.0, 6.0]:
r = np.random.default_rng(3)
w = 2.5
for _ in range(400):
g = egri_grad(w) + shovqin * r.normal()
w = w - 0.01 * g
print(f" {shovqin:>9.1f} {w:>12.4f} {egri(w):>10.4f}")
print(" ⭐ O'rtacha shovqin lokal minimumdan chiqishga yordam beradi")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Batch hajmi va gradient shovqini ===
batch o_rtacha burchak nisbiy xato 1/sqrt(b)
1 69.29° 3.1063 1.0000
4 55.07° 1.4687 0.5000
16 33.41° 0.7641 0.2500
64 18.91° 0.3885 0.1250
256 9.40° 0.1890 0.0625
1024 4.10° 0.0813 0.0312
nisbiy xato ~ 1/sqrt(batch) ga mutanosib
=== 2. Bir davrda necha qadam ===
batch qadamlar/davr gradient hisoblari
1 4000 4000
32 125 4000
256 16 4000
4000 1 4000
hisob hajmi BIR XIL, qadamlar soni boshqa
=== 3. Bir xil davrda natija ===
batch lr 5 davrdan keyin loss
1 0.002 1.047664
32 0.010 1.035608
256 0.050 1.035195
4000 0.050 2.560870
kichik batch ko'p qadam tashlaydi - tezroq yaqinlashadi
=== 4. Batch va lr birga o'zgaradi ===
batch lr = 0.01 lr ~ batch
32 1.035626 1.035626
64 1.035226 1.035995
128 1.043110 1.037284
256 1.208736 1.036383
batch oshganda lr ni ham oshirish kerak
=== 5. Shovqin foydali bo'lgan holat ===
L(w) = w^2 + 3*sin(4w)^2 - ko'p lokal minimum
shovqin yakuniy w L(w)
0.0 2.3069 5.4369
0.5 2.3092 5.4372
2.0 2.3160 5.4407
6.0 2.3319 5.4660
⭐ O'rtacha shovqin lokal minimumdan chiqishga yordam beradiNima ko'rsatdi: 2.2-bo'lim.
Misol 3 — Optimizatorlarni taqqoslash
"""SGD, moment, RMSProp, Adam bitta vazifada (real numpy)."""
import numpy as np
def optimizatorlar(nom, d):
"""Holat lug'atini qaytaradi."""
return {"v": np.zeros(d), "s": np.zeros(d), "m": np.zeros(d),
"t": 0}
def qadam(nom, w, g, h, lr):
h["t"] += 1
if nom == "SGD":
return w - lr * g
if nom == "Moment":
h["v"] = 0.9 * h["v"] + g
return w - lr * h["v"]
if nom == "RMSProp":
h["s"] = 0.9 * h["s"] + 0.1 * g ** 2
return w - lr * g / (np.sqrt(h["s"]) + 1e-8)
if nom == "Adam":
h["m"] = 0.9 * h["m"] + 0.1 * g
h["s"] = 0.999 * h["s"] + 0.001 * g ** 2
m_hat = h["m"] / (1 - 0.9 ** h["t"])
s_hat = h["s"] / (1 - 0.999 ** h["t"])
return w - lr * m_hat / (np.sqrt(s_hat) + 1e-8)
raise ValueError(nom)
def main() -> None:
print("=== 1. 'Jarlik' funksiyasida ===")
A = np.array([20.0, 1.0])
print(" L(w) = 0.5*(20*w1^2 + w2^2), boshlanish (1, 1)")
print(f" {'optimizator':<12} {'lr':>7} {'200 qadamdan keyin |w|':>25}")
for nom, lr in [("SGD", 0.05), ("Moment", 0.01),
("RMSProp", 0.05), ("Adam", 0.05)]:
w = np.array([1.0, 1.0])
h = optimizatorlar(nom, 2)
for _ in range(200):
w = qadam(nom, w, A * w, h, lr)
print(f" {nom:<12} {lr:>7.3f} {np.linalg.norm(w):>25.4e}")
print("\n=== 2. Har parametr uchun masshtab farqli ===")
masshtab = np.array([1e-3, 1e-1, 1.0, 1e1])
print(f" gradient masshtablari: {masshtab}")
print(f" {'optimizator':<12} {'300 qadamdan keyin har |w|':>32}")
for nom in ["SGD", "Moment", "RMSProp", "Adam"]:
w = np.ones(4)
h = optimizatorlar(nom, 4)
for _ in range(300):
w = qadam(nom, w, masshtab * w, h, 0.01)
print(f" {nom:<12} {str(np.abs(w).round(6)):>32}")
print(" adaptiv usullar hamma o'qni BIR XIL tezlikda olib boradi")
print("\n=== 3. Bias tuzatishning ta'siri ===")
g = np.array([1.0])
print(f" doimiy gradient g = 1.0")
print(f" {'qadam':>6} {'m':>10} {'m_hat':>10} {'nisbat':>9}")
m = np.zeros(1)
for t in range(1, 9):
m = 0.9 * m + 0.1 * g
m_hat = m / (1 - 0.9 ** t)
print(f" {t:>6} {m[0]:>10.6f} {m_hat[0]:>10.6f} "
f"{m_hat[0] / m[0]:>9.3f}")
print(" tuzatishsiz birinchi qadam 10 barobar kichik bo'lardi")
print("\n=== 4. Real regressiya vazifasida ===")
rng = np.random.default_rng(0)
n, d = 2000, 20
X = rng.normal(0, 1, (n, d)) * np.logspace(-1, 1, d)
w_haqiqiy = rng.normal(0, 1, d)
y = X @ w_haqiqiy + rng.normal(0, 0.5, n)
print(" belgilar masshtabi 0.1 dan 10 gacha (ataylab)")
print(f" {'optimizator':<12} {'lr':>7}", end="")
for davr in [5, 20, 100]:
print(f" {f'{davr} davr':>12}", end="")
print()
for nom, lr in [("SGD", 0.002), ("Moment", 0.0005),
("RMSProp", 0.05), ("Adam", 0.05)]:
w = np.zeros(d)
h = optimizatorlar(nom, d)
chiqish = []
for davr in range(1, 101):
g = 2 * X.T @ (X @ w - y) / n
w = qadam(nom, w, g, h, lr)
if davr in (5, 20, 100):
chiqish.append(float(np.mean((X @ w - y) ** 2)))
print(f" {nom:<12} {lr:>7.4f}", end="")
for c in chiqish:
print(f" {c:>12.4f}", end="")
print()
print("\n=== 5. lr ga sezgirlik ===")
print(f" {'optimizator':<12}", end="")
lrlar = [1e-4, 1e-3, 1e-2, 1e-1]
for lr in lrlar:
print(f" {lr:>11.0e}", end="")
print()
for nom in ["SGD", "Moment", "RMSProp", "Adam"]:
print(f" {nom:<12}", end="")
for lr in lrlar:
w = np.zeros(d)
h = optimizatorlar(nom, d)
for _ in range(50):
g = 2 * X.T @ (X @ w - y) / n
w = qadam(nom, w, g, h, lr)
if not np.isfinite(w).all():
break
loss = (float(np.mean((X @ w - y) ** 2))
if np.isfinite(w).all() else float("inf"))
print(f" {loss:>11.3g}", end="")
print()
print(" ⭐ Har optimizatorning O'Z lr oralig'i bor")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. 'Jarlik' funksiyasida ===
L(w) = 0.5*(20*w1^2 + w2^2), boshlanish (1, 1)
optimizator lr 200 qadamdan keyin |w|
SGD 0.050 3.5053e-05
Moment 0.010 1.4095e-05
RMSProp 0.050 3.4882e-02
Adam 0.050 4.0236e-05
=== 2. Har parametr uchun masshtab farqli ===
gradient masshtablari: [1.e-03 1.e-01 1.e+00 1.e+01]
optimizator 300 qadamdan keyin har |w|
SGD [0.997004 0.740707 0.049041 0. ]
Moment [0.971294 0.03933 0. 0. ]
RMSProp [0.004959 0.004961 0.00496 0.00496 ]
Adam [0.000183 0.000183 0.000183 0.000183]
adaptiv usullar hamma o'qni BIR XIL tezlikda olib boradi
=== 3. Bias tuzatishning ta'siri ===
doimiy gradient g = 1.0
qadam m m_hat nisbat
1 0.100000 1.000000 10.000
2 0.190000 1.000000 5.263
3 0.271000 1.000000 3.690
4 0.343900 1.000000 2.908
5 0.409510 1.000000 2.442
6 0.468559 1.000000 2.134
7 0.521703 1.000000 1.917
8 0.569533 1.000000 1.756
tuzatishsiz birinchi qadam 10 barobar kichik bo'lardi
=== 4. Real regressiya vazifasida ===
belgilar masshtabi 0.1 dan 10 gacha (ataylab)
optimizator lr 5 davr 20 davr 100 davr
SGD 0.0020 52.4173 11.0975 2.4965
Moment 0.0005 65.1189 42.4313 1.4509
RMSProp 0.0500 184.1141 20.7563 0.3278
Adam 0.0500 298.8404 51.4681 0.2554
=== 5. lr ga sezgirlik ===
optimizator 1e-04 1e-03 1e-02 1e-01
SGD 124 8.55 3.01e+05 8.59e+131
Moment 9.9 1.94 2.24 6.89e+129
RMSProp 446 412 159 0.245
Adam 447 417 191 1.77
⭐ Har optimizatorning O'Z lr oralig'i borNima ko'rsatdi: 2.3, 2.4, 2.5-bo'limlar.
Misol 4 — Jadval va amaliy taqqoslash
"""Learning rate schedule va sklearn bilan tekshiruv."""
import warnings
import numpy as np
from sklearn.datasets import make_classification
from sklearn.exceptions import ConvergenceWarning
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import StandardScaler
def jadval(nom, t, T, lr0=0.1, lr_min=0.001):
if nom == "doimiy":
return lr0
if nom == "step":
return lr0 * (0.1 ** (t // (T // 3)))
if nom == "exponential":
return lr0 * (0.01 ** (t / T))
if nom == "cosine":
return lr_min + 0.5 * (lr0 - lr_min) * (1 + np.cos(np.pi * t / T))
if nom == "warmup+cosine":
w = max(1, T // 10)
if t < w:
return lr0 * (t + 1) / w
u = (t - w) / max(1, T - w)
return lr_min + 0.5 * (lr0 - lr_min) * (1 + np.cos(np.pi * u))
raise ValueError(nom)
def main() -> None:
T = 40
nomlar = ["doimiy", "step", "exponential", "cosine",
"warmup+cosine"]
print("=== 1. Jadvallar shakli ===")
print(f" {'davr':>6}", end="")
for nom in nomlar:
print(f" {nom:>14}", end="")
print()
for t in [0, 3, 10, 20, 30, 39]:
print(f" {t:>6}", end="")
for nom in nomlar:
print(f" {jadval(nom, t, T):>14.5f}", end="")
print()
print("\n=== 2. O'rtacha lr ===")
print(f" {'jadval':<16} {'o_rtacha lr':>13} {'oxirgi lr':>11}")
for nom in nomlar:
qiymatlar = [jadval(nom, t, T) for t in range(T)]
print(f" {nom:<16} {np.mean(qiymatlar):>13.5f} "
f"{qiymatlar[-1]:>11.5f}")
print("\n=== 3. Regressiyada jadval ta'siri ===")
rng = np.random.default_rng(0)
n, d = 1500, 15
X = rng.normal(0, 1, (n, d)) * np.logspace(-0.5, 0.5, d)
w_haq = rng.normal(0, 1, d)
y = X @ w_haq + rng.normal(0, 0.4, n)
print(f" {'jadval':<16} {'yakuniy loss':>14} "
f"{'eng yaxshi loss':>17}")
for nom in nomlar:
w = np.zeros(d)
eng = float("inf")
for t in range(T * 8):
lr = jadval(nom, t, T * 8, lr0=0.05)
g = 2 * X.T @ (X @ w - y) / n
w = w - lr * g
eng = min(eng, float(np.mean((X @ w - y) ** 2)))
print(f" {nom:<16} {np.mean((X @ w - y) ** 2):>14.6f} "
f"{eng:>17.6f}")
print("\n=== 4. sklearn optimizatorlari ===")
Xc, yc = make_classification(n_samples=3000, n_features=20,
n_informative=10, n_redundant=4,
n_classes=3, flip_y=0.1,
class_sep=0.9, random_state=0)
Xtr, Xte, ytr, yte = train_test_split(Xc, yc, test_size=0.3,
random_state=0, stratify=yc)
sc = StandardScaler().fit(Xtr)
Xtr, Xte = sc.transform(Xtr), sc.transform(Xte)
print(f" {'solver':<8} {'lr':>8} {'davrlar':>9} {'loss':>9} "
f"{'test':>8}")
for solver, lr in [("sgd", 0.001), ("sgd", 0.01), ("sgd", 0.1),
("adam", 0.001), ("adam", 0.01), ("adam", 0.1)]:
with warnings.catch_warnings():
warnings.simplefilter("ignore", ConvergenceWarning)
m = MLPClassifier(hidden_layer_sizes=(64, 32),
solver=solver, learning_rate_init=lr,
max_iter=150, random_state=0,
early_stopping=False).fit(Xtr, ytr)
print(f" {solver:<8} {lr:>8.3f} {m.n_iter_:>9} "
f"{m.loss_:>9.4f} "
f"{accuracy_score(yte, m.predict(Xte)):>8.4f}")
print(" ⭐ Optimizatorni BIR XIL lr bilan taqqoslash noto'g'ri")
print("\n=== 5. sklearn ning o'z jadvallari ===")
print(f" {'learning_rate':<12} {'davrlar':>9} {'loss':>9} "
f"{'test':>8}")
for rejim in ["constant", "invscaling", "adaptive"]:
with warnings.catch_warnings():
warnings.simplefilter("ignore", ConvergenceWarning)
m = MLPClassifier(hidden_layer_sizes=(64, 32), solver="sgd",
learning_rate=rejim,
learning_rate_init=0.05, max_iter=150,
random_state=0,
early_stopping=False).fit(Xtr, ytr)
print(f" {rejim:<12} {m.n_iter_:>9} {m.loss_:>9.4f} "
f"{accuracy_score(yte, m.predict(Xte)):>8.4f}")
if __name__ == "__main__":
main()Natijaning muhim qismi:
=== 1. Jadvallar shakli ===
davr doimiy step exponential cosine warmup+cosine
0 0.10000 0.10000 0.10000 0.10000 0.02500
3 0.10000 0.10000 0.07079 0.09863 0.10000
10 0.10000 0.10000 0.03162 0.08550 0.09337
20 0.10000 0.01000 0.01000 0.05050 0.05910
30 0.10000 0.00100 0.00316 0.01550 0.01868
39 0.10000 0.00010 0.00112 0.00115 0.00119
=== 2. O'rtacha lr ===
jadval o_rtacha lr oxirgi lr
doimiy 0.10000 0.10000
step 0.03608 0.00010
exponential 0.02276 0.00112
cosine 0.05174 0.00115
warmup+cosine 0.05294 0.00119
=== 3. Regressiyada jadval ta'siri ===
jadval yakuniy loss eng yaxshi loss
doimiy 0.149416 0.149416
step 0.157593 0.157593
exponential 0.197353 0.197353
cosine 0.151485 0.151485
warmup+cosine 0.151475 0.151475
=== 4. sklearn optimizatorlari ===
solver lr davrlar loss test
sgd 0.001 150 0.5118 0.7644
sgd 0.010 150 0.1671 0.7933
sgd 0.100 98 0.0023 0.7989
adam 0.001 150 0.1194 0.8089
adam 0.010 87 0.0016 0.7944
adam 0.100 53 0.2637 0.8089
⭐ Optimizatorni BIR XIL lr bilan taqqoslash noto'g'ri
=== 5. sklearn ning o'z jadvallari ===
learning_rate davrlar loss test
constant 150 0.0037 0.7856
invscaling 150 0.6469 0.7289
adaptive 150 0.0037 0.7856Nima ko'rsatdi: 2.6-bo'lim.
5. To'g'ri va noto'g'ri tushunishlar
| Noto'g'ri fikr | To'g'risi |
|---|---|
| "Adam har doim yaxshi" | lr sozlanmasa SGD dan yomon bo'lishi mumkin |
"Bitta lr hamma optimizatorga mos" |
Har birida o'z oralig'i |
| "Katta batch — yaxshi" | Umumlashtirishni yomonlashtirishi mumkin |
| "Shovqin — zarar" | Lokal minimumdan chiqishga yordam beradi |
| "Moment — kichik yaxshilanish" | Jarlikda hal qiluvchi |
| "Bias tuzatish keraksiz" | Birinchi o'nlab qadamda muhim |
| "Jadval murakkab" | Bir necha qator, katta foyda |
"lr ni bir marta tanlash yetarli" |
Batch o'zgarsa qayta sozlang |
6. Keng tarqalgan xatolar va yechimlari
1. Bir xil lr bilan taqqoslash
# SGD(lr=0.001) va Adam(lr=0.001) # ⚠️
# har biriga o'z lr izlanadi # ✅2. Gradientni tozalamaslik
loss.backward(); opt.step() # ⚠️ torch da yig'iladi
opt.zero_grad(); loss.backward(); opt.step() # ✅3. Batch oshirib lr ni qoldirish
batch = 512 # lr o'zgarmadi # ⚠️
lr = lr * (512 / 64) # ✅4. Adam ga weight_decay
Adam(params, weight_decay=0.01) # ⚠️ L2 adaptiv bilan buziladi
AdamW(params, weight_decay=0.01) # ✅5. lr ni umuman sozlamaslik
# sukut qiymat bilan qoldirish # ⚠️
# LR range test bilan izlash # ✅6. eps ni nolga yaqin qilish
w -= lr * g / np.sqrt(s) # ⚠️ 0 ga bo'lish
w -= lr * g / (np.sqrt(s) + 1e-8) # ✅7. Jadvalni validatsiyasiz tanlash
# cosine har doim yaxshi deb o'ylash # ⚠️
# validatsiya balli bilan tekshirish # ✅7. Integratsiya — bu bilim qayerda kerak bo'ladi
- 20.6-dars (o'tilgan): Gradientlar
- 20.8-dars: Boshlang'ich qiymatlar
- 20.10-dars: Regularizatsiya
- 21-qism:
torch.optim - 26-qism: Warmup va transformerlar
8. Eng yaxshi amaliyotlar
lrni birinchi sozlang.LR range test o'tkazing.
Adamdan boshlang.Batch bilan
lrni birga o'zgartiring.Jadval qo'shing.
Gradient normasini kuzating.
AdamWishlating.Loss egri chizig'ini chizing.
9. Amaliy topshiriq
Vazifa 1: Bashorat qiling
1. # gradient tushish qadami?
2. # kvadratikda lr chegarasi?
3. # shovqin batch bilan qanday bog'liq?
4. # moment nima qiladi?
5. # beta = 0.9 necha qadam eslaydi?
6. # RMSProp nimani hal qiladi?
7. # Adam necha g'oyadan iborat?
8. # bias tuzatish nima uchun?
9. # Adam sukut lr?
10. # cosine jadval formulasi?
11. # warmup nima uchun?
12. # AdamW farqi?Javoblar
w -= lr * glr < 2/a~1/sqrt(batch)- Inersiya beradi
- ~10
- Har parametrga o'z qadami
- Uch
- Boshlanishdagi sekinlik
- 0.001
lr_min + 0.5*(lr0-lr_min)*(1+cos(pi*t/T))- Boshida barqarorlik
weight_decayalohida qo'llanadi
Vazifa 2: Xatolarni tuzating
1. # SGD(lr=0.001) va Adam(lr=0.001) ni taqqoslash
2. loss.backward(); opt.step()
3. batch = 512 # lr o'zgarmadi
4. Adam(params, weight_decay=0.01)
5. w -= lr * g / np.sqrt(s)Javoblar
1. # har biriga o'z lr izlanadi
2. opt.zero_grad(); loss.backward(); opt.step()
3. lr = lr * (512 / 64)
4. AdamW(params, weight_decay=0.01)
5. w -= lr * g / (np.sqrt(s) + 1e-8)Vazifa 3: lr
Modellang:
- Chegara
- Jarlik
- Izlash
- Traektoriya
Vazifa 4: Batch
Modellang:
- Shovqin
- Qadamlar
- Natija
- Foydali shovqin
Vazifa 5: Optimizatorlar
Modellang:
- Jarlik
- Masshtab
- Bias
- Sezgirlik
Vazifa 6: Jadval
Modellang:
- Shakllar
- O'rtacha
- Ta'sir
- sklearn
Vazifa 7: O'ylash
Loss egri chizig'i tekis pastga tushib, so'ng birdan NaN ga aylandi. Nima bo'lgan va qanday tuzatasiz?
Javob
Nima bo'lgan: gradient portlagan. Biror qadamda gradient juda katta bo'lgan, og'irliklar juda uzoqqa sakragan, keyingi oldinga o'tishda inf paydo bo'lgan va u NaN ga aylangan.
NaN tarqalishining zanjiri:
katta gradient -> katta og'irlik -> exp(katta) = inf
-> inf - inf = NaN -> BARCHA og'irlik NaNNaN bir marta paydo bo'lsa, u qaytmaydi — o'rgatishni qaytadan boshlash kerak.
Sababni topish:
for qadam in range(qadamlar):
g = gradient(...)
norma = np.linalg.norm(g)
if norma > 100 or not np.isfinite(norma):
print(f"qadam {qadam}: gradient normasi {norma:.3e}")
breakNaN dan oldingi qadamlarda norma qanday o'sganini ko'rish muhim.
Uch asosiy sabab:
| Sabab | Belgi | Yechim |
|---|---|---|
lr juda katta |
Loss oldin sakrab o'sgan | lr ni 10x kamaytiring |
| Gradient portlashi | Norma birdan 1e6 |
Gradient clipping |
| Raqamli beqarorlik | log(0), exp(800) |
clip, log_softmax |
Gradient clipping — eng ishonchli himoya:
max_norma = 1.0
norma = np.linalg.norm(g)
if norma > max_norma:
g = g * (max_norma / norma)Bu yo'nalishni saqlaydi, faqat uzunlikni cheklaydi. RNN va transformerlarda deyarli har doim qo'llanadi.
Tekshirish ro'yxati:
lrni 10 barobar kamaytiring —NaNyo'qolsa sabab shu- Gradient clipping qo'shing (
max_norm = 1.0) - Kirishni masshtablang (
X.std()~1 bo'lsin) - Loss ichida
clipbor-yo'qligini tekshiring - Boshlang'ich og'irliklarni tekshiring (
He/Xavier) - Warmup qo'shing — birinchi davrlarda
lrni asta oshiring
Profilaktika:
# har qadamda tekshiruv (o'rgatish boshida)
assert np.isfinite(loss), f"qadam {t}: loss = {loss}"Bu bir qator NaN paydo bo'lgan aniq qadamni ko'rsatadi va tashxisni bir necha daqiqaga qisqartiradi.
Eng ko'p uchraydigan yechim: lr ni kamaytirish + clipping. Bu ikkisi birga holatlarning katta qismini yopadi.
Nimani mustahkamlaydi: 2.1-bo'lim.
Xulosa
Bu darsda optimizatorlarni ko'rdik.
Eng muhim uch fikr:
lr— eng muhim giperparametr, va uning chegarasi bor. Kvadratik funksiyadalr < 2/a— bundan kattasi uzoqlashadi. "Jarlik" da eng tik o'qlrni cheklaydi va yassi o'q shu sababli sekin harakatlanadi. Shuning uchunlrni tanlashdan oldin LR range test o'tkazish arzon va foydali odat.Adam — uchta g'oyaning birlashmasi. Moment inersiya beradi,
RMSPropqismi har parametrga o'z qadamini beradi, bias tuzatish esa boshlanishdagi sun'iy sekinlikni yo'q qiladi. 3-misolda gradient masshtabi1e-3dan10gacha farq qilgandaSGDbir o'qni deyarli qimirlatmadi, adaptiv usullar esa hammasini bir vaqtda olib bordi.Optimizatorni
lrsiz taqqoslash — bekor ish. 4-misoldasgdvaadambir xillrda butunlay boshqa natija berdi, lekin har biriga o'z oralig'i berilganda farq ancha kichraydi. Jadval (cosine,warmup) esa bir necha qator kod evaziga barqaror yaxshilanish beradi.
Keyingi darsda boshlang'ich qiymatlar va normalizatsiya: nima uchun nol bilan boshlash ishlamaydi, Xavier va He qayerdan kelgan, BatchNorm va LayerNorm nimani hal qiladi.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!