सामग्री पर जाएँ
3/30अध्याय 3 / 30

ढलान की ओर: Gradient Descent और वे दो कदम जिन्हें सब छोड़ देते हैं

learning rate की सटीक सीमा निकालें, फिर 3,600 दिशाओं की brute-force खोज को बिना बताए gradient फिर से खोजते देखें.

इस पेज पर

पिछला अध्याय एक घाटी पर खत्म हुआ था.

यह कोई रूपक वाली घाटी नहीं थी: एक असली curve था, loss को एक ही parameter के विरुद्ध plot किया गया था, जो नीचे झुकता था और फिर ऊपर लौट आता था। और उसके नीचे का loss इसलिए नहीं चुना गया था कि वह साफ-सुथरा था — वह measurements में noise के बारे में एक कथन से derive हुआ था, और squared error एक convention की जगह consequence के रूप में बाहर आया था.

तो हमारे पास एक bottom वाला landscape है, और यह मानने की वजह है कि bottom ही सही जगह है। जो हमारे पास नहीं है, वह वहाँ पहुँचने का तरीका है.

यह अध्याय वही बनाता है, और यह वही algorithm है जो इस course के बाकी हर model को train करता है — हर एक को, बिना अपवाद, उन models तक भी जिनमें सैकड़ों अरब parameters हैं। यह लगभग बीस lines में समा जाता है। कठिन दो हिस्से उन बीस lines में नहीं हैं, और वही दो चीज़ें हैं जिन्हें लगभग हर explanation छोड़ देती है:

  • minus sign क्यों। update gradient को subtract करता है। हर tutorial इसे लिखता है; बहुत कम बताते हैं कि gradient वह direction क्यों है जो ऊपर जाता है, और यही एकमात्र fact है जो minus sign को विश्वास की छलांग से कुछ अधिक बनाता है.
  • कदम कितना बड़ा। “बहुत बड़ा diverge करता है, बहुत छोटा slow है” सच है और बेकार है। एक exact number है, वह loss से compute किया जा सकता है, और यह chapter उसे दो बार compute करता है — एक बार toy parabola के लिए और एक बार actual data के लिए.

setup, और आप सिर्फ search क्यों नहीं कर सकते

सेक्शन का लिंक: setup, और आप सिर्फ search क्यों नहीं कर सकते

ताकि यह chapter अपने-आप खड़ा रहे, फिर से कहें: Chapter 1 की conveyor belt से वे आठ parts, लेकिन सवाल अलग। accept or reject नहीं — वह बाद में लौटेगा — बल्कि किसी part की width से उसका weight predict करना.

belt.pyPYTHON
import numpy as np

WIDTH  = np.array([18.0, 19.5, 20.2, 21.0, 24.0, 25.5, 23.0, 26.0])
WEIGHT = np.array([47.0, 52.0, 49.0, 55.0, 61.0, 66.0, 70.0, 58.0])

x = WIDTH  - WIDTH.mean()      # 22.15 mm
y = WEIGHT - WEIGHT.mean()     # 57.25 g

measurements centred हैं, ठीक Chapter 1 की तरह और उसी वजह से जो इस chapter के खत्म होने से पहले ब्याज सहित लौटेगी। model एक line है, y^=ax+b\hat{y} = a x + b, और loss वह mean squared error है जिसे पिछले chapter ने derive किया था:

L(a,b)=1ni=1n(axi+byi)2L(a, b) = \frac{1}{n} \sum_{i=1}^{n} \left(a x_i + b - y_i\right)^2

दो parameters। फिर बहुत सारी values try क्यों न करें? चलिए सच में करते हैं — a=0a = 0 से 55 और b=5b = -5 से 55 तक एक grid, 0.010.01 के steps में:

TEXT
grid 501 x 1001 = 501,501 evaluations in 3.67 s
  best found: a = 2.1000, b = -0.0000, L = 24.592450

दो numbers को दो decimal places तक pin down करने के लिए आधा million evaluations — और वह second एक machine पर wall clock है, इसलिए rerun तीन से छह के बीच कहीं भी land कर सकता है; evaluation count और minimum वे हिस्से हैं जो reproduce होते हैं। इस chapter के अंत में Gradient Descent आठ steps में चार decimal places और छत्तीस में पूरा float64 answer पा लेता है.

लेकिन speed argument नहीं है, और यही point पूरे course का फैसला करता है। Grid search की cost PP parameters के लिए, हर एक पर kk values होने पर, kPk^P evaluations है। हर axis पर एक thousand values के साथ:

modelparametersgrid evaluations
यह line210610^{6}
Chapter 5 का XOR network9102710^{27}
एक छोटा multilayer network20,0001060,00010^{60{,}000}

तीसरी row कोई बड़ा number नहीं है, यह meaningless number है — observable universe में लगभग 108010^{80} atoms हैं। models बढ़ने पर search धीमी नहीं होती; वह मौजूद रहना बंद कर देती है। आगे जो कुछ भी आता है, वह उस table की वजह से मौजूद है.

derivative एक measurement है जिसे आप ले सकते हैं

सेक्शन का लिंक: derivative एक measurement है जिसे आप ले सकते हैं

एक पल के लिए b=0b = 0 fix कर दें ताकि एक parameter और एक curve हो, वही picture जो पिछले chapter ने छोड़ी थी। उस पर एक point लें, a=1a = 1, और पूछें: अगर मैं aa को एक छोटे amount hh से nudge करूँ, तो loss per unit nudge कितना move करता है?

L(a+h)L(a)h\frac{L(a + h) - L(a)}{h}

वह ratio rise over run है — curve पर दो points से गुजरती straight line की slope। जैसे-जैसे hh shrink होता है, दोनों points साथ खिसकते हैं और line tangent बन जाती है। उसकी slope derivative L(a)L'(a) है: aa में change के per unit loss जिस rate से बदलता है। यह किसी चीज़ का approximation नहीं है, और न ही कोई infinitely small quantity। यह ordinary ratios की limit है.

इसे run करना worthwhile है, क्योंकि numbers ऐसी बात कहते हैं जो definition नहीं कहती:

slope.pyPYTHON
def loss1(a):
    return np.mean((a * x - y) ** 2)

for h in [1.0, 1e-2, 1e-4, 1e-6, 1e-8, 1e-10, 1e-12, 1e-14]:
    q = (loss1(1.0 + h) - loss1(1.0)) / h
    print(f"h = {h:<8.0e}   slope estimate = {q:.10f}   error = {abs(q + 16.385):.3e}")
TEXT
h = 1e+00      slope estimate = -8.9400000000    error = 7.445e+00
h = 1e-02      slope estimate = -16.3105500000   error = 7.445e-02
h = 1e-04      slope estimate = -16.3842555001   error = 7.445e-04
h = 1e-06      slope estimate = -16.3849925556   error = 7.444e-06
h = 1e-08      slope estimate = -16.3850003787   error = 3.787e-07
h = 1e-10      slope estimate = -16.3850444324   error = 4.443e-05
h = 1e-12      slope estimate = -16.3851154866   error = 1.155e-04
h = 1e-14      slope estimate = -17.0530256582   error = 6.680e-01

यहाँ दो चीज़ें होती हैं और दोनों load-bearing हैं.

error बस vaguely hh के proportional नहीं है — यह exactly 7.445h7.445\,h है। hh को सौ से divide करें, error हर बार four significant figures तक सौ से divide होता है। वह constant decoration नहीं है: यह loss के second derivative का half है, और उस idea का पहला appearance है जो अब से दो sections बाद आएगा — कि किसी point के पास curve, line plus h2h^2 के proportional correction जैसा दिखता है.

और फिर pattern टूट जाता है। h=108h = 10^{-8} से नीचे estimate खराब हो जाता है, और 101410^{-14} पर यह second digit में गलत है। कुछ mathematical नहीं हुआ; पिछले chapter का floating-point box हुआ। L(a+h)L(a+h) और L(a)L(a) अपने पहले ten digits में agree करते हैं, उन्हें subtract करने से वे digits destroy हो जाते हैं, और wreckage को tiny number से divide करने पर जो बचता है वह amplify हो जाता है। एक best hh है — यहाँ 10810^{-8} के आसपास, लगभग machine epsilon का square root — और उससे छोटा जाना more careful नहीं, less careful है। इसे याद रखें; इस chapter के अंत में एक function इस पर depend करता है.

calculus से exact slope, measurement के बजाय, 16.385-16.385 है। इसलिए हम measuring रोककर deriving शुरू कर सकते हैं.

यह वह idea है जिस पर course का बाकी हिस्सा बना है, एक बार साफ-साफ stated.

दो functions को compose करना यानी एक को दूसरे में feed करना: (fg)(x)=f(g(x))(f \circ g)(x) = f(g(x))। बस.

deep network composition जैसा नहीं है। वह है composition। एक layer एक function है; layers stack करना उन्हें compose करना है; “depth” chain में functions की संख्या है। जब Chapter 5 एक network बनाता है, वह f4f3f2f1f_4 \circ f_3 \circ f_2 \circ f_1 बना रहा होता है और कुछ नहीं। इसका मतलब है कि हमारे purposes के लिए calculus का single most important rule वही है जो composition को differentiate करता है:

ddxf(g(x))=f(g(x))g(x)\frac{d}{dx} f(g(x)) = f'(g(x)) \cdot g'(x)

rates multiply करते हैं। अगर gg, xx से तीन गुना तेजी से बदलता है, और ff, gg से दुगुना तेजी से बदलता है, तो ff, xx से छह गुना तेजी से बदलता है। यही पूरा content है, और इसी वजह से ten layers से पीछे pass होता signal ten numbers से multiplied होता है — इसलिए Chapter 6 एक section इस पर खर्च करता है कि क्या होता है जब वे numbers सभी one से थोड़ा कम होते हैं.

इसे अपने loss पर use करें। residual ri=axi+byir_i = a x_i + b - y_i लिखें, ताकि L=1nri2L = \frac{1}{n}\sum r_i^2। हर rir_i, inner function axia x_i के through aa पर depend करता है, जिसका derivative xix_i है। Chain rule, term by term:

La=1ni2rixi,Lb=1ni2ri1\frac{\partial L}{\partial a} = \frac{1}{n}\sum_i 2 r_i \cdot x_i, \qquad \frac{\partial L}{\partial b} = \frac{1}{n}\sum_i 2 r_i \cdot 1

ये curly \partial symbols एक partial derivative mark करते हैं: एक variable के respect में differentiate करें और बाकी सबको constant मानें। कुछ नया नहीं होता — यह वही limit है जो पहले थी, बस एक axis के along ली गई। partials को vector में collect करें और आपके पास gradient है:

L=(La, Lb)\nabla L = \left( \frac{\partial L}{\partial a},\ \frac{\partial L}{\partial b} \right)

point (a,b)=(1,4)(a, b) = (1, 4) पर वह vector (16.385, 8.0)(-16.385,\ 8.0) है। दो numbers। सवाल यह है कि उनका मतलब क्या है, और यही पहला step है जिसे सब छोड़ देते हैं.

gradient axes के along slopes का vector है। हमने बस इतना ही prove किया है। यह obvious नहीं है — और obvious होना भी नहीं चाहिए — कि उन्हें vector में assemble करने से कोई चीज़ किसी particular direction में point करेगी.

तो वह चीज़ define करें जो हम सच में चाहते हैं। एक unit vector u\mathbf{u} चुनें, एक direction। directional derivative वह rate है जिससे उस direction में चलते हुए loss बदलता है:

DuL=limh0L(θ+hu)L(θ)hD_{\mathbf{u}} L = \lim_{h \to 0} \frac{L(\boldsymbol{\theta} + h\mathbf{u}) - L(\boldsymbol{\theta})}{h}

Chain rule इसे computable बना देता है। u\mathbf{u} के along चलना, aa को u1u_1 rate पर और bb को u2u_2 rate पर बदलता है, और contributions add होते हैं:

DuL=Lau1+Lbu2=LuD_{\mathbf{u}} L = \frac{\partial L}{\partial a} u_1 + \frac{\partial L}{\partial b} u_2 = \nabla L \cdot \mathbf{u}

किसी भी direction में change का rate gradient और उस direction का dot product है। और अब punchline, जो geometry की one line है। vectors के बीच angle ϕ\phi के साथ dot product लिखते हुए,

Lu=Lucosϕ=Lcosϕ\nabla L \cdot \mathbf{u} = \lVert \nabla L \rVert \, \lVert \mathbf{u} \rVert \cos\phi = \lVert \nabla L \rVert \cos\phi

क्योंकि u\mathbf{u} की length 1 है। जिस एक चीज़ को आप control करते हैं वह cosϕ\cos\phi है, जो ϕ=0\phi = 0 पर largest और half turn, ϕ=180\phi = 180 degrees पर smallest है। इसलिए:

  • steepest ascent खुद L\nabla L के along है, और वहाँ slope exactly L\lVert \nabla L \rVert है.
  • steepest descent L-\nabla L के along है, और वहाँ slope L-\lVert \nabla L \rVert है.
  • gradient के perpendicular, loss बिल्कुल नहीं बदलता। इसलिए contour map की lines gradient को right angles पर cross करती हैं.

यही minus sign है। कोई convention नहीं, कोई sign flip नहीं जिसे किसी ने चुना: fastest decrease की direction negative gradient है क्योंकि cosϕ\cos\phi half turn पर minimised होता है, और किसी अन्य कारण से नहीं.

क्योंकि यह claim सभी directions के बारे में है, इसे सभी directions के against test करें। उनमें से 3,600 sample करें, हर tenth of a degree पर एक, और हर एक को nudging से measure करें:

directions.pyPYTHON
theta = np.array([1.0, 4.0])
g = grad(theta)
print("gradient      ", g)
print("its length    ", np.linalg.norm(g))
print("its angle     ", np.degrees(np.arctan2(g[1], g[0])) % 360, "degrees")

best = max(
    ((loss(theta + 1e-6 * u) - loss(theta - 1e-6 * u)) / 2e-6, np.degrees(ang))
    for ang, u in (
        (a, np.array([np.cos(a), np.sin(a)])) for a in np.arange(3600) * 2 * np.pi / 3600
    )
)
print("steepest slope", best[0], "at", best[1], "degrees")
TEXT
gradient       [-16.385   8.   ]
its length     18.23371122399386
its angle      153.97598928042032 degrees
steepest slope 18.233709624837502 at 154.0 degrees

एक search जिसे gradients के बारे में कुछ नहीं पता, 3,600 directions में, अपनी steepest climb 154.0 degrees पर पाती है — gradient की अपनी direction, search की 0.1-degree resolution के भीतर। और जो slope उसे वहाँ मिलती है, 18.2337, वह six figures तक gradient की length है। theorem gradients के meaning की story नहीं है; यह measurable fact है, और यही measurement है.

downhill एक छोटा step सच में मदद क्यों करता है

सेक्शन का लिंक: downhill एक छोटा step सच में मदद क्यों करता है

अब दूसरा skipped step। हमें पता है कि down कौन-सी direction है। इससे यह follow नहीं होता कि उस तरफ चलने से loss कम होगा, क्योंकि “down” infinitesimal nudge के बारे में statement है और step infinitesimal नहीं है.

bridge है linearisation। किसी point के पास, smooth function अपनी tangent plus correction होता है:

L(θ+δ)=L(θ)+Lδ+O(δ2)L(\boldsymbol{\theta} + \boldsymbol{\delta}) = L(\boldsymbol{\theta}) + \nabla L \cdot \boldsymbol{\delta} + O(\lVert\boldsymbol{\delta}\rVert^2)

यह first-order Taylor expansion है। discarded O(δ2)O(\lVert\boldsymbol{\delta}\rVert^2) curvature है — वही term जिसने slope table के estimate को exactly 7.445h7.445\,h से गलत बनाया था। उस step को डालें जो हम लेना चाहते हैं, δ=ηL\boldsymbol{\delta} = -\eta \nabla L:

L(θηL)L(θ)ηL2L(\boldsymbol{\theta} - \eta \nabla L) \approx L(\boldsymbol{\theta}) - \eta \lVert \nabla L \rVert^2

loss ηL2\eta \lVert \nabla L \rVert^2 से drop करता है। इसका हर हिस्सा non-negative है, इसलिए promise real है — काफी small η\eta के लिए, क्योंकि neglected term η2\eta^2 की तरह grow करता है और eventually उसे खा जाता है। यही पूरी theory है। यहाँ promise निभता है, और फिर टूटता है:

TEXT
eta = 0.2       promised    66.49364500   delivered   -16.01619240   ratio -0.240868
eta = 0.1       promised    33.24682250   delivered    12.61936315   ratio  0.379566
eta = 0.01      promised     3.32468225   delivered     3.11840766   ratio  0.937957
eta = 0.001     promised     0.33246822   delivered     0.33040548   ratio  0.993796
eta = 0.0001    promised     0.03324682   delivered     0.03322620   ratio  0.999380
eta = 1e-05     promised     0.00332468   delivered     0.00332448   ratio  0.999938

इसे bottom से पढ़ें। जैसे η\eta shrink होता है, delivered drop promised one पर converge करता है — ratio 0.99938, फिर 0.99994 — यानी Taylor का theorem correct है। top से पढ़ें और η=0.2\eta = 0.2 पर delivered “drop” negative sixteen है। step downhill गया और loss ऊपर गया.

तो update rule है

θθηL(θ)\boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \nabla L(\boldsymbol{\theta})

और इसके साथ एक condition आती है जिसे कोई state नहीं करता, कि η\eta काफी small हो। Exactly किसके compared to small, यह अगला section है.

सबसे simple valley से शुरू करें, f(x)=x2f(x) = x^2, जहाँ f(x)=2xf'(x) = 2x। Gradient Descent का एक step है

xxη2x=x(12η)x \leftarrow x - \eta \cdot 2x = x\,(1 - 2\eta)

position हर step पर (12η)(1 - 2\eta) से multiplied है। यह geometric sequence है, और geometric sequences का exactly one rule है: multiplier absolute value में 1 से smaller हो तो वे shrink करते हैं और otherwise grow करते हैं। इसलिए 12η<1\lvert 1 - 2\eta \rvert < 1, जो 0<η<10 < \eta < 1 है.

boundary exactly η=1\eta = 1 पर है। “लगभग 1” नहीं, “1 usually too big है” नहीं। η=1\eta = 1 पर multiplier 1-1 है और point हमेशा xx और x-x के बीच bounce करता है, न approach करता है न escape। इसके नीचे, converge; इसके ऊपर, diverge। interval η=0.5\eta = 0.5 पर फिर split होता है, जहाँ multiplier sign बदलता है: उससे नीचे approach monotone है, उससे ऊपर point overshoot करता है और sides alternate करता है, और exactly 0.50.5 पर multiplier 0 है और one single step minimum पर land करता है.

algebra की four lines से four regimes। जाइए और boundaries खुद cross कीजिए:

14 चरण, x = -0.0836 पर समाप्त।

डेटा को तालिका में देखें
चरणxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨-1.5200⁩⁨2.3104⁩
2⁨-1.2160⁩⁨1.4787⁩
3⁨-0.9728⁩⁨0.9463⁩
4⁨-0.7782⁩⁨0.6057⁩
5⁨-0.6226⁩⁨0.3876⁩
6⁨-0.4981⁩⁨0.2481⁩
7⁨-0.3985⁩⁨0.1588⁩
8⁨-0.3188⁩⁨0.1016⁩
9⁨-0.2550⁩⁨0.0650⁩
10⁨-0.2040⁩⁨0.0416⁩
11⁨-0.1632⁩⁨0.0266⁩
12⁨-0.1306⁩⁨0.0170⁩
13⁨-0.1045⁩⁨0.0109⁩
14⁨-0.0836⁩⁨0.0070⁩
ग्रेडिएंट डिसेंट, इंटरैक्टिव

x=1.9x = -1.9 से, 0.1 rate पर fourteen steps, 0.0836-0.0836 पर ending। rate को 0.5 पर push करें और पहला ही step bottom पर land करता है। इसे 0.9 पर push करें और यह same 0.0836-0.0836 पर end करता है जहाँ 0.1 ने किया था — same distance, opposite style, क्योंकि 12η\lvert 1 - 2\eta \rvert दोनों के लिए 0.8 है — लेकिन वह valley के एक side से नीचे चलने की बजाय उसके across zig-zag करते हुए वहाँ पहुँचता है.

और अब interesting one:

14 चरण, x = -1.9000 पर समाप्त।

डेटा को तालिका में देखें
चरणxf(x)
0⁨-1.9000⁩⁨3.6100⁩
1⁨1.9000⁩⁨3.6100⁩
2⁨-1.9000⁩⁨3.6100⁩
3⁨1.9000⁩⁨3.6100⁩
4⁨-1.9000⁩⁨3.6100⁩
5⁨1.9000⁩⁨3.6100⁩
6⁨-1.9000⁩⁨3.6100⁩
7⁨1.9000⁩⁨3.6100⁩
8⁨-1.9000⁩⁨3.6100⁩
9⁨1.9000⁩⁨3.6100⁩
10⁨-1.9000⁩⁨3.6100⁩
11⁨1.9000⁩⁨3.6100⁩
12⁨-1.9000⁩⁨3.6100⁩
13⁨1.9000⁩⁨3.6100⁩
14⁨-1.9000⁩⁨3.6100⁩
ग्रेडिएंट डिसेंट, इंटरैक्टिव

ठीक boundary पर। rate 1 पर fourteen steps, और यह 1.9-1.9 पर finish करता है: बिल्कुल जहाँ से शुरू हुआ था, bounce करने के अलावा कुछ नहीं करते हुए। एक nudge ज्यादा और bouncing hold होने की बजाय grow करती है; 1.2 पर यह four steps में chart से बाहर है। बहुत large rate slowly converge नहीं करता। वह converge नहीं करता.

अब general rule, जो same argument से निकलता है। multiplier 12η1 - 2\eta वास्तव में 1ηf1 - \eta f'' था, और किसी minimum के पास multi-parameter loss में हर direction के लिए ऐसा one number होता है — second derivatives की matrix के eigenvalues। हर direction को एक साथ stable होना पड़ता है, इसलिए ceiling largest से set होती है:

η<2λmax\eta < \frac{2}{\lambda_{\max}}

f(x)=x2f(x) = x^2 के लिए, f=2f'' = 2, ceiling 1, जो हमने अभी derive किया। हमारी belt के लिए, second-derivative matrix 2nAA\frac{2}{n} A^{\top} A है जिसमें AA inputs की two-column matrix है, और उसके eigenvalues 2 और 14.89 हैं, इसलिए ceiling 2/14.89=0.134322 / 14.89 = 0.13432 है। यह पाँच significant figures वाली prediction है। इसे test करें:

TEXT
lr=0.1343    -> L =      24.5924
lr=0.13431   -> L =      24.5924
lr=0.13432   -> L =       4707.8       BLEW UP
lr=0.13433   -> L =  4.00452e+16       BLEW UP
lr=0.1344    -> L = 1.18229e+107       BLEW UP

linear algebra की एक line और for loop की hundred thousand iterations के बीच five decimal places की agreement.

और यहीं Chapter 1 वापस आता है। ऊपर सबने centred measurements use किए। raw millimetres और grams पर identical code run करें और eigenvalues 2 और 14.89 के बजाय 0.0298 और 998.1 हैं। ceiling 0.134 से 0.002004 पर collapse हो जाती है — उतनी ही exact तरह, lr=0.002003 पर converging और lr=0.002004 पर blowing up.

ceiling से भी bad eigenvalues के बीच का ratio है। condition number measure करता है कि valley round होने से कितनी दूर है: एक long thin trench rate को steep walls के लिए काफी small होने को force करता है, और फिर trench का floor उसी crawl पर walked होता है। हमारा centred में 7.44 से raw में 33,452 हो जाता है। हर version जिस best rate को ले सकता है, उसके साथ:

featurescondition numberbest rateoptimum के 1% के भीतर steps
centred7.440.118410
raw millimetres and grams33,4520.002003779,513

same data, same code, अंत में same answer — और आठ हजार गुना काम, क्योंकि किसी ने mean subtract नहीं किया। Chapter 1 में इसी omission ने perceptron को epochs में छह हजार का factor cost किया था, और वहाँ diagnosis geometric था: data origin से दूर float कर रहा था। यहाँ optimisation costume में वही geometry है, और यही वजह है कि input normalisation hygiene advice नहीं बल्कि arithmetic है.1

ऊपर कुछ भी library नहीं चाहता था। पूरा optimiser यहाँ है.

descent.pyPYTHON
def loss(theta):
    a, b = theta
    return np.mean((a * x + b - y) ** 2)


def grad(theta):
    a, b = theta
    residual = a * x + b - y
    return np.array([np.mean(2 * residual * x), np.mean(2 * residual)])


def descend(theta, lr, steps):
    theta = np.array(theta, dtype=float)
    for _ in range(steps):
        theta = theta - lr * grad(theta)   
    return theta


theta = descend([0.0, 0.0], lr=0.05, steps=60)
print(theta, loss(theta))
TEXT
[ 2.10040296e+00 -2.76445533e-15] 24.592448791134984

इन आठ points के लिए closed-form least-squares answer a=2.100403a = 2.100403, b=0b = 0 है, 24.59244924.592449 के loss के साथ। loop ने इसे eight significant figures तक ढूँढ लिया, बिना यह जाने कि closed form exist करता है — जो matter करता है, क्योंकि Chapter 5 से आगे ऐसा कोई नहीं होगा.

trajectory, क्योंकि इसे देखना ही point है:

TEXT
   0 a=0.000000 b=0.000000 L=57.437500
   1 a=1.563750 b=0.000000 L=26.736582
   2 a=1.963288 b=-0.000000 L=24.732418
   5 a=2.098116 b=-0.000000 L=24.592488
  10 a=2.100400 b=-0.000000 L=24.592449
  60 a=2.100403 b=-0.000000 L=24.592449

distance का अधिकांश first two steps में cover हो जाता है, क्योंकि gradient तब largest होता है जब आप bottom से सबसे दूर होते हैं और approach करने पर shrink होता है। Gradient Descent minimum के पास automatically slow down करता है। यह feature है और Chapter 6 में, problem भी.

अब तक के argument में एक hole है। step तब रुकता है जब L=0\nabla L = \mathbf{0}, और हम इसे “the minimum” कहते आए हैं। zero gradient वाला point critical point है, और minimum होना उसका केवल एक तरीका है:

  • एक local minimum: हर direction में uphill, लेकिन संभव है कि कहीं भी lowest ऐसा point न हो;
  • एक local maximum: हर direction में downhill;
  • एक saddle point: कुछ directions में uphill और कुछ में downhill। surface f(x,y)=x2y2f(x,y) = x^2 - y^2 में f=(2x,2y)\nabla f = (2x, -2y) है, जो origin पर zero है, जहाँ function same time पर xx-axis के along minimum और yy-axis के along maximum है.

Gradient Descent इन्हें अलग नहीं बता सकता, क्योंकि वह हमेशा सिर्फ gradient देखता है, और gradient तीनों पर zero है.

हमारी line का एक critical point है और वही answer है — linear model पर squared-error loss convex है, एक single bowl, और उस पर descent global minimum ढूँढने में fail नहीं हो सकता। यह property इस course से contact में survive नहीं करती। neural network का loss convex नहीं होता, और Chapter 5 से आगे “the minimum” कोई ऐसी चीज़ नहीं है जो exist करती हो: कई minima होते हैं, अलग-अलग depths के, और आपको कौन-सा मिलता है यह इस पर depend करता है कि आप कहाँ से शुरू हुए। यह one sentence है और one sentence ही रहेगा, क्योंकि theory बड़ी है और practical consequence छोटा.

आप पूरा consequence एक curve पर देख सकते हैं। f(x)=x44x22+x10f(x) = \tfrac{x^4}{4} - \tfrac{x^2}{2} + \tfrac{x}{10} लें, जिसमें अलग depths की दो valleys हैं:

TEXT
   x =  -1.046681   f(x) =  -0.352386   minimum
   x =   0.101031   f(x) =   0.005026   maximum
   x =   0.945649   f(x) =  -0.152639   minimum

40 चरण, x = 0.9456 पर समाप्त।

डेटा को तालिका में देखें
चरणxf(x)
0⁨0.1100⁩⁨0.0050⁩
1⁨0.1122⁩⁨0.0050⁩
2⁨0.1149⁩⁨0.0049⁩
3⁨0.1182⁩⁨0.0049⁩
4⁨0.1223⁩⁨0.0048⁩
5⁨0.1275⁩⁨0.0047⁩
6⁨0.1338⁩⁨0.0045⁩
7⁨0.1416⁩⁨0.0042⁩
8⁨0.1513⁩⁨0.0038⁩
9⁨0.1633⁩⁨0.0032⁩
10⁨0.1781⁩⁨0.0022⁩
11⁨0.1962⁩⁨0.0007⁩
12⁨0.2183⁩⁨-0.0014⁩
13⁨0.2453⁩⁨-0.0046⁩
14⁨0.2779⁩⁨-0.0093⁩
15⁨0.3170⁩⁨-0.0160⁩
16⁨0.3633⁩⁨-0.0253⁩
17⁨0.4172⁩⁨-0.0377⁩
18⁨0.4783⁩⁨-0.0535⁩
19⁨0.5455⁩⁨-0.0721⁩
20⁨0.6163⁩⁨-0.0922⁩
21⁨0.6869⁩⁨-0.1116⁩
22⁨0.7526⁩⁨-0.1277⁩
23⁨0.8092⁩⁨-0.1393⁩
24⁨0.8540⁩⁨-0.1463⁩
25⁨0.8868⁩⁨-0.1499⁩
26⁨0.9091⁩⁨-0.1516⁩
27⁨0.9236⁩⁨-0.1522⁩
28⁨0.9325⁩⁨-0.1525⁩
29⁨0.9379⁩⁨-0.1526⁩
30⁨0.9411⁩⁨-0.1526⁩
31⁨0.9430⁩⁨-0.1526⁩
32⁨0.9441⁩⁨-0.1526⁩
33⁨0.9448⁩⁨-0.1526⁩
34⁨0.9451⁩⁨-0.1526⁩
35⁨0.9454⁩⁨-0.1526⁩
36⁨0.9455⁩⁨-0.1526⁩
37⁨0.9455⁩⁨-0.1526⁩
38⁨0.9456⁩⁨-0.1526⁩
39⁨0.9456⁩⁨-0.1526⁩
40⁨0.9456⁩⁨-0.1526⁩
ग्रेडिएंट डिसेंट, इंटरैक्टिव

x=0.11x = 0.11 से forty steps, 0.94560.9456 पर settling — दो valleys में shallower वाली। अब starting point को one notch left, 0.100.10 पर move करें। same rate, same forty steps, और यह इसके बजाय 1.0461-1.0461 पर settle करता है, जहाँ loss 0.199747 lower है। watershed 0.1010310.101031 पर hump है, और दोनों answers के बीच पूरा difference बस यह है कि आप उसके किस side पर start हुए.

shallow valley में land करना loss में 56.7% worse है, और algorithm के पास जानने का कोई तरीका नहीं, क्योंकि valley के अंदर से हर direction uphill है। Gradient Descent में इसका कोई repair नहीं है और कोई आने वाला भी नहीं। practice में जो है, वह यह finding है कि यह picture जितना suggest करती है उससे बहुत कम matter करता है — real network की बहुत high dimensions में most critical points traps के बजाय saddles निकलते हैं,2 और Chapter 5 measure करता है कि एक small network सच में कितनी बार stuck होता है.

ऊपर grad के बारे में एक बात आपको bother करनी चाहिए: यह हर step के लिए entire dataset पर sum करता है। आठ parts कुछ नहीं। एक million का मतलब parameters को एक बार move करने के लिए एक million gradient computations है.

escape यह है कि gradient एक average है, और average को sample से estimate किया जा सकता है। random handful — एक minibatch — पर इसे compute करें, और उस पर step लें। estimate noisy है; वह unbiased भी है, और hundreds of cheap noisy steps एक expensive exact one को beat करते हैं। hundred thousand synthetic parts पर, steps के बजाय per-example gradients गिनते हुए:

methodoptimum के 0.1% के भीतर stepsper-example gradients
full batch7700,000
minibatch of 321003,200
one example at a time17,58017,580

same जगह पहुँचने के लिए two hundred and nineteen times less arithmetic। और extreme — one example at a time, Robbins और Monro3 की original stochastic approximation — winner नहीं है: यह 32 के batches से five times worse है, क्योंकि matrices multiply करने वाले hardware पर 32 examples की cost one से लगभग अधिक नहीं होती, जबकि noise batch size के square root के साथ गिरता है। यही trade-off वजह है कि आप जो भी training script पढ़ेंगे उसमें batch_size होगा.

Momentum दूसरा cheap fix है, और उसका निशाना सीधे trench है। badly conditioned valley में steps narrow direction के across zig-zag करते हैं जबकि long one के along creep करते हैं। Momentum past gradients का running average रखता है, ताकि oscillating components cancel हों और consistent one accumulate हो:4

vβv+L(θ),θθηv\mathbf{v} \leftarrow \beta \mathbf{v} + \nabla L(\boldsymbol{\theta}), \qquad \boldsymbol{\theta} \leftarrow \boldsymbol{\theta} - \eta \mathbf{v}

दो extra lines। raw uncentred belt पर — condition number 33,452, हमारे पास worst case — best rate पर जो plain descent ले सकता है:

TEXT
momentum beta=0.0   ->    79,513 steps to 1%
momentum beta=0.9   ->     1,609 steps to 1%
momentum beta=0.99  ->       461 steps to 1%

दो lines of code के लिए 172 का factor। Chapter 6 इसे Adam में बदलता है; mechanism पहले से यहाँ है.

वह check जिसकी आपको Chapter 5 में ज़रूरत होगी

सेक्शन का लिंक: वह check जिसकी आपको Chapter 5 में ज़रूरत होगी

इस chapter में हर gradient hand-derived था और इसलिए wrong हो सकता था। fix शुरुआत की slope table है: derivative को numerically measure करें और compare करें। central difference, L(θ+h)L(θh)2h\frac{L(\theta+h) - L(\theta-h)}{2h}, use करें, जो leading error term cancel करता है और same hh के लिए बहुत अधिक accurate है.

gradcheck.pyPYTHON
def numeric_grad(f, theta, h=1e-5):
    theta = np.asarray(theta, dtype=float)
    out = np.zeros_like(theta)
    for i in range(theta.size):
        bump = np.zeros_like(theta)
        bump[i] = h
        out[i] = (f(theta + bump) - f(theta - bump)) / (2 * h)     
    return out


def gradcheck(f, df, theta, h=1e-5):
    analytic = np.asarray(df(theta), dtype=float)
    numeric = numeric_grad(f, theta, h)
    return np.max(np.abs(analytic - numeric) / np.maximum(1e-8, np.abs(analytic) + np.abs(numeric)))

comparison का relative form matter करता है: 10410^{-4} का absolute difference size 10310^{-3} के gradient पर disaster है और size 10610^{6} वाले पर irrelevant.

TEXT
relative error: 1.8929136036763527e-11
with 2 dropped: 0.33333333331650744

पहली line ऊपर का hand-derived gradient है। दूसरी वही function है जिसमें एक component से factor of 2 छूट गया है — single character का typo — और check उसे तुरंत पकड़ लेता है। लगभग 10710^{-7} से नीचे कुछ भी agreement है; 10410^{-4} से ऊपर कुछ भी bug है। इस function को रखें: Chapter 5 इसे automatic differentiation engine debug करने के लिए use करता है, और यही एकमात्र वजह है कि wrong gradient findable है.

इस chapter की हर चीज़ एक unstated assumption पर टिकी थी: कि आप L/θ\partial L / \partial \theta लिख सकते हैं.

दो parameters वाली line के लिए, वह algebra की one line थी। यह लगभग तुरंत one line होना बंद कर देता है। किसी symbolic algebra system से network के loss का derivative single first-layer weight के respect में, single example के लिए पूछें, और answer में arithmetic count करें:

networkone partial derivative में operations
four hidden units, one layer40
four hidden units, two layers301
four hidden units, three layers1,717

तीसरी row 57 parameters वाला network है — इतना छोटा network कि Chapter 6 में footnote होता — और उसका gradient हाथ से लिखने का मतलब one training example के लिए लगभग 97,869 operations है। कोई notation इसे rescue नहीं करता। जो rescue करता है वह observation है कि composition पर apply किया गया chain rule enormous structure रखता है, वही intermediate quantities बार-बार appear होती हैं, और उन्हें सही order में compute करने से all derivatives roughly one forward pass की price में मिल जाते हैं। वह Chapter 5 है.

लेकिन पहले एक छोटा problem है, और वह तुरंत इंतज़ार कर रहा है.

अब हमारे पास ऐसी machine है जो किसी भी differentiable loss पर downhill roll करेगी। इसे belt के original question — accept or reject, target जो 1 या 0 है — पर point करें, output पर sigmoid लगाएँ ताकि यह probability predict करे, और squared error minimise करें। यह run करेगा। यह तब भी मुश्किल से move करेगा जब यह सबसे अधिक wrong होगा, और gradient बताता है क्यों:

output zzpredictiontruthgradient with squared errorgradient with cross-entropy
000.500012.5×1012.5 \times 10^{-1}5.0×1015.0 \times 10^{-1}
2-20.119211.850×1011.850 \times 10^{-1}8.808×1018.808 \times 10^{-1}
6-60.002514.921×1034.921 \times 10^{-3}9.975×1019.975 \times 10^{-1}
10-104.54×1054.54 \times 10^{-5}19.079×1059.079 \times 10^{-5}1.0001.000

एक model जो confidently, catastrophically wrong है — answer 1 होने पर 0.0000454 predict कर रहा है — 9×1059 \times 10^{-5} का squared-error gradient produce करता है। उसे पता ही नहीं कि वह trouble में है। दूसरी column, एक ऐसे loss से जिसे हमने अभी derive नहीं किया है, 1.0 report करती है: maximum urgency, exactly जहाँ deserved है.

जिससे वह सवाल उठता है जिससे अगला chapter शुरू होता है। पिछले chapter ने कहा था कि loss noise के बारे में assumption है, और squared error Gaussian noise assume करता है। yes-or-no answer का कौन-सा noise model होता है — और जब आप उसी derivation को उस पर run करते हैं तो कौन-सा loss निकलता है?


method इन सब से पुराना है: Cauchy ने 1847 में Académie des Sciences को एक note में इसे describe किया था, systems of equations solve करने के तरीके के रूप में, उनके squared residuals के sum पर downhill चलते हुए। इस chapter के साथ पढ़ने लायक और भी: Sebastian Ruder का An overview of gradient descent optimization algorithms (arXiv:1609.04747), जो fourteen readable pages में momentum से Adam तक cover करता है; Nocedal और Wright की Numerical Optimization (2nd ed., Springer, 2006) का chapter 3, जिसका theorem 3.3 condition number के terms में quadratic पर steepest descent की convergence rate देता है — यही theory है जिसके पीछे conditioning step count तय करती है, हालांकि वह line search treat करता है न कि ऊपर measured fixed-step 2/λmax2/\lambda_{\max} ceiling, या Deisenroth, Faisal और Ong की Mathematics for Machine Learning के §5.8 और §7.1 उसी ground के लिए less machinery के साथ; Prince की Understanding Deep Learning का §6.1 और Goodfellow, Bengio और Courville की Deep Learning का §4.3; Dive into Deep Learning §12.1–12.3, जिसमें minibatch analysis यहाँ की room से अधिक measurements के साथ है; और Géron की Hands-On Machine Learning (3rd ed.) का chapter 4, learning rate को derive करने की बजाय tune करने वाली चीज़ के रूप में सबसे practical treatment। MIT 6.390 notes classification से पहले Gradient Descent रखते हैं, जैसे यह course करता है और same reason से.

  1. LeCun, Y., Bottou, L., Orr, G. B. and Müller, K.-R. Efficient BackProp, in Neural Networks: Tricks of the Trade (Springer, 1998), pp. 9–50. Section 4.3 recommendation देता है और section 5.1 ऊपर detail box में use किया गया argument: inputs को centre और scale करने से second-derivative matrix के eigenvalues बदलते हैं, और इसलिए steps की संख्या, सिर्फ numerical comfort नहीं.

  2. Dauphin, Y. N., Pascanu, R., Gulcehre, C., Cho, K., Ganguli, S. and Bengio, Y. Identifying and attacking the saddle point problem in high-dimensional non-convex optimization, arXiv:1406.2572 (2014). यह argument कि high dimensions में critical points overwhelmingly local minima के बजाय saddles होते हैं, क्योंकि minimum के लिए हजारों directions में से हर एक का एक साथ upward curve करना आवश्यक है.

  3. Robbins, H. and Monro, S. A Stochastic Approximation Method. Annals of Mathematical Statistics 22(3), pp. 400–407 (1951). वह paper जिसने establish किया कि gradient का noisy estimate enough है, अगर step size सही तरह से shrink करे.

  4. Polyak, B. T. Some methods of speeding up the convergence of iteration methods. USSR Computational Mathematics and Mathematical Physics 4(5), pp. 1–17 (1964). heavy-ball method, जो ऊपर का momentum update है, backpropagation के इस field तक पहुँचने से twenty-two years पहले.


निर्माता

David Vicente Campos

NeuraLIA Labs के संस्थापक और MyRealFood के सह-संस्थापक

मैं लेओन विश्वविद्यालय से कंप्यूटर इंजीनियर हूँ। मैंने MyRealFood की सह-स्थापना की, जहाँ CTO के रूप में मैंने वह ऐप बनाया जिसे लाखों लोग बेहतर खान-पान के लिए इस्तेमाल कर चुके हैं, और मैंने NeuraLIA Labs की स्थापना की, जहाँ मैं AI प्रोडक्ट्स बनाता हूँ। यहाँ मैं उन बातों के बारे में लिखता हूँ जो इस सफ़र में मुझे समझनी पड़ीं, उस तरह जिस तरह काश किसी ने मुझे समझाई होतीं।

लेखक के बारे में और जानें

NeuraLIA Labs द्वारा प्रकाशित।

नए पोस्ट अपने इनबॉक्स में पाएं

AI समाचार, गाइड और प्रोडक्ट अपडेट — जब भी हम कुछ उपयोगी प्रकाशित करें, एक छोटा ईमेल।

कोर्स सूची

Abstract software decision engine with branching paths, probability nodes, and glowing gates.
jev13 मिनट पढ़ें

Jev AI मॉडल गद्य के लिए नहीं, निर्णयों के लिए बना है

TypeSafe AI का Jev ध्यान खींच रहा है क्योंकि यह सॉफ्टवेयर इंटेलिजेंस को संभावना की समस्या मानता है: सही शाखा चुनें, भरोसे का स्तर जोड़ें, और जब कोड को निर्णय चाहिए तो LLM से टेक्स्ट लिखवाने पर खर्च न करें।

Abstract agent runtime sorting documents, memory blocks and pointer nodes inside a bounded context frame.
context-engineering14 मिनट पढ़ें

लॉन्ग-होराइजन AI एजेंट्स के लिए कॉन्टेक्स्ट इंजीनियरिंग

लंबे समय तक चलने वाले एजेंट सिर्फ इसलिए असफल नहीं होते कि विंडो छोटी है। वे तब असफल होते हैं जब फ़ाइलें, टूल आउटपुट और पुराना इतिहास उस काम को ही पीछे धकेल देते हैं जिसे एजेंट को पूरा करना था।

मॉडल चुनने का काम LIA पर छोड़ने के लिए तैयार हैं?

हर AI मॉडल एक ही जगह — आज ही मुफ़्त शुरू करें।