Spring til indhold
3/30Kapitel 3 af 30

Nedad: gradient descent og de to trin alle springer over

Beregn det præcise loft for en læringsrate, og se brute-force over 3.600 retninger genfinde gradienten uden hjælp.

På denne side

Forrige kapitel sluttede med en dal.

Ikke en metaforisk én: en faktisk kurve, tabet plottet mod en enkelt parameter, som dykker ned og kommer op igen. Og tabet under den blev ikke valgt, fordi det var pænt — det blev udledt fra en påstand om støjen i målingerne, og den kvadrerede fejl kom ud i den anden ende som en konsekvens snarere end en konvention.

Så vi har et landskab med en bund og en grund til at tro, at bunden er det rigtige sted at være. Det, vi ikke har, er en måde at komme derhen på.

Dette kapitel bygger en, og det er algoritmen, der træner alle modeller i resten af dette kursus — hver eneste, uden undtagelse, helt op til og med dem med hundreder af milliarder parametre. Den kan være på cirka tyve linjer. De to svære dele står ikke i de tyve linjer, og de er de to ting, næsten alle forklaringer springer over:

  • Hvorfor minustegnet. Opdateringen trækker gradienten fra. Alle tutorials skriver det; meget få forklarer, hvorfor gradienten er retningen, der går op, hvilket er det eneste faktum, der gør minustegnet til andet end en trosakt.
  • Hvor stort et skridt. „For stort divergerer, for lille er langsomt” er sandt og ubrugeligt. Der findes et præcist tal, det kan beregnes fra tabet, og dette kapitel beregner det to gange — én gang for en legetøjsparabel og én gang for de faktiske data.

Opsætningen, og hvorfor du ikke bare kan søge

Link til afsnittet: Opsætningen, og hvorfor du ikke bare kan søge

Gentaget, så dette kapitel kan stå alene: de otte dele fra transportbåndet i kapitel 1, men med et andet spørgsmål. Ikke acceptér eller afvis — det vender tilbage senere — men forudsig en dels vægt ud fra dens bredde.

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

Målingerne er centreret, præcis som i kapitel 1 og af en grund, der kommer stærkt tilbage, før dette kapitel er slut. Modellen er en linje, y^=ax+b\hat{y} = a x + b, og tabet er den gennemsnitlige kvadrerede fejl, som forrige kapitel udledte:

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

To parametre. Hvorfor ikke bare prøve mange værdier? Lad os faktisk gøre det — et gitter fra a=0a = 0 til 55 og b=5b = -5 til 55, i skridt på 0.010.01:

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

En halv million evalueringer for at fastholde to tal med to decimalers præcision — og den sekund er vægur på én maskine, så en gentagelse lander hvor som helst fra tre til seks; antallet af evalueringer og minimummet er den del, der reproducerer. Gradient descent får, ved slutningen af dette kapitel, fire decimaler på otte skridt og det fulde float64-svar på seksogtredive.

Men hastighed er ikke argumentet, og det er denne pointe, der afgør hele kurset. Gittersøgning koster kPk^P evalueringer for PP parametre ved kk værdier hver. Med tusind værdier pr. akse:

modelparametregitterevalueringer
denne linje210610^{6}
XOR-netværket fra kapitel 59102710^{27}
et lille flerlaget netværk20.0001060,00010^{60{,}000}

Den tredje række er ikke et stort tal, det er et meningsløst tal — der er omtrent 108010^{80} atomer i det observerbare univers. Søgning bliver ikke bare langsommere, når modeller vokser; den ophører med at eksistere. Alt, der følger, findes på grund af den tabel.

Fastlås b=0b = 0 et øjeblik, så der er én parameter og én kurve, hvilket er billedet, sidste kapitel efterlod dig med. Tag et punkt på den, a=1a = 1, og spørg: hvis jeg skubber aa en lille smule hh, hvor meget flytter tabet sig pr. enhed skub?

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

Det forhold er en stigning over løb — hældningen på den rette linje gennem to punkter på kurven. Når hh krymper, glider de to punkter sammen, og linjen bliver tangenten. Dens hældning er den afledte L(a)L'(a): raten, hvormed tabet ændrer sig pr. enheds ændring i aa. Ikke en approximation af noget og ikke en uendeligt lille størrelse. En grænseværdi af almindelige forhold.

Det er værd at køre, fordi tallene siger noget, definitionen ikke gør:

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

To ting sker her, og begge er bærende.

Fejlen er ikke vagt proportional med hh — den er præcis 7.445h7.445\,h. Del hh med hundrede, så deles fejlen med hundrede, med fire betydende cifre hver gang. Den konstant er ikke pynt: den er halvdelen af den anden afledte af tabet, og den er den første optræden af en idé om to afsnit — at en kurve nær et punkt ligner en linje plus en korrektion proportional med h2h^2.

Og så bryder mønsteret. Under h=108h = 10^{-8} bliver estimatet værre, og ved 101410^{-14} er det forkert i andet ciffer. Der skete intet matematisk; sidste kapitels floating-point-boks gjorde det. L(a+h)L(a+h) og L(a)L(a) er enige i deres første ti cifre, at trække dem fra hinanden ødelægger de cifre, og at dividere vraget med et lille tal forstærker det, der er tilbage. Der er et bedste hh — her omkring 10810^{-8}, omtrent kvadratroden af maskin-epsilon — og at gå mindre er ikke mere omhyggeligt, det er mindre. Husk det; en funktion sidst i dette kapitel afhænger af det.

Den præcise hældning, fra calculus snarere end måling, er 16.385-16.385. Så vi kan stoppe med at måle og begynde at udlede.

Her er idéen, resten af kurset er bygget på, sagt én gang, ligeud.

At komponere to funktioner er at føre den ene ind i den anden: (fg)(x)=f(g(x))(f \circ g)(x) = f(g(x)). Ikke mere.

Et dybt netværk er ikke som en komposition. Det er en. Et lag er en funktion; at stable lag er at komponere dem; „dybde” er antallet af funktioner i kæden. Når kapitel 5 bygger et netværk, bygger det f4f3f2f1f_4 \circ f_3 \circ f_2 \circ f_1 og intet andet. Det betyder, at den vigtigste regel i calculus, til vores formål, er den, der differentierer en komposition:

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

Rater multipliceres. Hvis gg ændrer sig tre gange så hurtigt som xx, og ff ændrer sig dobbelt så hurtigt som gg, så ændrer ff sig seks gange så hurtigt som xx. Det er hele indholdet, og det er derfor, et signal, der passerer tilbage gennem ti lag, bliver multipliceret med ti tal — og derfor bruger kapitel 6 et afsnit på, hvad der sker, når de tal alle er lidt mindre end én.

Brug den på vores tab. Skriv residualen ri=axi+byir_i = a x_i + b - y_i, så L=1nri2L = \frac{1}{n}\sum r_i^2. Hver rir_i afhænger af aa gennem den indre funktion axia x_i, hvis afledte er xix_i. Kædereglen, led for led:

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

De krøllede \partial-symboler markerer en partiel afledt: differentier med hensyn til én variabel, og behandl alle andre som konstanter. Der sker ikke noget nyt — det er samme grænseværdi som før, taget langs én akse. Saml de partielle afledte i en vektor, og du har gradienten:

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

I punktet (a,b)=(1,4)(a, b) = (1, 4) er den vektor (16.385, 8.0)(-16.385,\ 8.0). To tal. Spørgsmålet er, hvad de betyder, og dette er det første trin, alle springer over.

Gradienten er en vektor af hældninger langs akserne. Det er alt, vi har bevist. Det er ikke oplagt — det bør ikke være oplagt — at det at samle dem i en vektor producerer noget, der peger et bestemt sted hen.

Så definér det, vi faktisk vil have. Vælg en enhedsvektor u\mathbf{u}, en retning. Den retningsafledte er raten, hvormed tabet ændrer sig, når du går den vej:

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

Kædereglen gør dette beregneligt. At gå langs u\mathbf{u} ændrer aa med raten u1u_1 og bb med raten u2u_2, og bidragene lægges sammen:

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}

Ændringsraten i enhver retning er prikproduktet af gradienten med den retning. Og nu punchlinen, som er én linje geometri. Skriv prikproduktet med vinklen ϕ\phi mellem vektorerne,

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

da u\mathbf{u} har længde 1. Det eneste, du kontrollerer, er cosϕ\cos\phi, som er størst ved ϕ=0\phi = 0 og mindst ved en halv omgang, ϕ=180\phi = 180 grader. Så:

  • Den stejleste stigning er langs L\nabla L selv, og hældningen dér er præcis L\lVert \nabla L \rVert.
  • Det stejleste fald er langs L-\nabla L, og hældningen dér er L-\lVert \nabla L \rVert.
  • Vinkelret på gradienten ændrer tabet sig slet ikke. Det er derfor, linjerne på et konturkort krydser gradienten i rette vinkler.

Det er minustegnet. Ikke en konvention, ikke et fortegnsskift, nogen valgte: retningen for hurtigste fald er den negative gradient, fordi cosϕ\cos\phi minimeres ved en halv omgang, og af ingen anden grund.

Da dette er en påstand om alle retninger, så test den mod alle retninger. Sample 3.600 af dem, én pr. tiendedel grad, og mål hver enkelt ved at skubbe:

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

En søgning, der intet ved om gradienter, over 3.600 retninger, finder sin stejleste opstigning ved 154,0 grader — gradientens egen retning, inden for søgningens opløsning på 0,1 grad. Og hældningen, den finder dér, 18,2337, er gradientens længde med seks cifres præcision. Sætningen er ikke en historie om, hvad gradienter betyder; den er et målbart faktum, og dette er målingen.

Hvorfor et lille skridt nedad faktisk hjælper

Link til afsnittet: Hvorfor et lille skridt nedad faktisk hjælper

Nu det andet oversprungne trin. Vi ved, hvilken vej der er ned. Det følger ikke, at det sænker tabet at gå den vej, fordi „ned” er en påstand om et infinitesimalt skub, og et skridt er ikke infinitesimalt.

Broen er linearisering. Nær et punkt er en glat funktion sin tangent plus en korrektion:

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

Det er førsteordens Taylor-udvikling. Det kasserede O(δ2)O(\lVert\boldsymbol{\delta}\rVert^2) er krumningen — det samme led, der gjorde hældningstabellens estimat forkert med præcis 7.445h7.445\,h. Sæt det skridt ind, vi agter at tage, δ=η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

Tabet falder med ηL2\eta \lVert \nabla L \rVert^2. Hver del af det er ikke-negativ, så løftet er ægte — for et tilstrækkeligt lille η\eta, fordi det forsømte led vokser som η2\eta^2 og til sidst æder det. Det er hele teorien. Her bliver løftet holdt og derefter brudt:

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

Læs den nedefra. Når η\eta krymper, konvergerer det leverede fald mod det lovede — forhold 0,99938, derefter 0,99994 — hvilket er Taylors sætning, der har ret. Læs den oppefra, og ved η=0.2\eta = 0.2 er det leverede „fald” minus seksten. Skridtet gik nedad, og tabet gik op.

Så opdateringsreglen er

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

og den kommer med en betingelse, ingen nævner, nemlig at η\eta er lille nok. Lille nok i forhold til hvad, præcis, er næste afsnit.

Learning rate har et loft, og det kan beregnes

Link til afsnittet: Learning rate har et loft, og det kan beregnes

Start med den simpleste dal, der findes, f(x)=x2f(x) = x^2, hvor f(x)=2xf'(x) = 2x. Ét skridt med gradient descent er

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

Positionen multipliceres med (12η)(1 - 2\eta) hvert skridt. Det er en geometrisk følge, og geometriske følger har præcis én regel: de krymper, når multiplikatoren er mindre end 1 i absolut værdi, og vokser ellers. Så 12η<1\lvert 1 - 2\eta \rvert < 1, hvilket er 0<η<10 < \eta < 1.

Grænsen ligger præcis ved η=1\eta = 1. Ikke „omkring 1”, ikke „1 er som regel for stort”. Ved η=1\eta = 1 er multiplikatoren 1-1, og punktet hopper mellem xx og x-x for evigt, uden hverken at nærme sig eller slippe væk. Under den, konvergér; over den, divergér. Intervallet deles igen ved η=0.5\eta = 0.5, hvor multiplikatoren skifter fortegn: under den er tilnærmelsen monoton, over den skyder punktet forbi og skifter side, og ved præcis 0.50.5 er multiplikatoren 0, og ét enkelt skridt lander på minimum.

Fire regimer, fra fire linjer algebra. Gå selv ud og kryds grænserne:

14 trin, slutter ved x = -0.0836.

Se dataene som en tabel
Trinxf(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⁩
Gradientnedstigning, interaktiv

Fjorten skridt med en rate på 0,1, fra x=1.9x = -1.9, slutter ved 0.0836-0.0836. Skub raten til 0,5, og det allerførste skridt lander på bunden. Skub den til 0,9, og den slutter ved samme 0.0836-0.0836, som 0,1 gjorde — samme afstand, modsat stil, fordi 12η\lvert 1 - 2\eta \rvert er 0,8 for begge — men den kommer dertil ved at zigzagge over dalen i stedet for at gå ned ad den ene side.

Og nu den interessante:

14 trin, slutter ved x = -1.9000.

Se dataene som en tabel
Trinxf(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⁩
Gradientnedstigning, interaktiv

Præcis på grænsen. Fjorten skridt med en rate på 1, og den slutter ved 1.9-1.9: præcis hvor den startede, efter intet andet end at hoppe frem og tilbage. Ét skub højere, og hoppene vokser i stedet for at holde sig; ved 1,2 er den ude af grafen på fire skridt. En rate, der er for stor, konvergerer ikke langsomt. Den konvergerer ikke.

Nu den generelle regel, som falder ud af samme argument. Multiplikatoren 12η1 - 2\eta var egentlig 1ηf1 - \eta f'', og nær et minimum har et tab med flere parametre ét sådant tal pr. retning — egenværdierne for matricen af andenafledte. Hver retning skal være stabil på én gang, så loftet sættes af den største:

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

For f(x)=x2f(x) = x^2, f=2f'' = 2, loft 1, hvilket er det, vi lige udledte. For vores bånd er andenafledt-matricen 2nAA\frac{2}{n} A^{\top} A med AA som inputmatricen med to kolonner, og dens egenværdier er 2 og 14,89, så loftet er 2/14.89=0.134322 / 14.89 = 0.13432. Det er en forudsigelse med fem betydende cifre i sig. Test den:

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

Fem decimalers overensstemmelse mellem én linje lineær algebra og hundrede tusind iterationer af en for-løkke.

Og her vender kapitel 1 tilbage. Alt ovenfor brugte de centrerede målinger. Kør den identiske kode på rå millimeter og gram, og egenværdierne er 0,0298 og 998,1 i stedet for 2 og 14,89. Loftet kollapser fra 0,134 til 0,002004 — lige så præcist, konvergerende ved lr=0.002003 og eksploderende ved lr=0.002004.

Værre end loftet er forholdet mellem egenværdierne. Konditionstallet måler, hvor langt fra rund dalen er: en lang, tynd rende tvinger en rate, der er lille nok til de stejle vægge, og så må rendens gulv gås med samme sneglefart. Vores går fra 7,44 centreret til 33.452 rå. Med den bedste rate, hver version kan tage:

featureskonditionstalbedste rateskridt til inden for 1% af optimum
centreret7,440,118410
rå millimeter og gram33.4520,002003779.513

Samme data, samme kode, samme svar til sidst — og otte tusind gange arbejdet, fordi ingen trak et gennemsnit fra. I kapitel 1 kostede den samme udeladelse perceptronen en faktor seks tusind i epoker, og diagnosen dér var geometrisk: data svævede langt fra origo. Det er den samme geometri her i optimeringskostume, og det er derfor, inputnormalisering ikke er hygiejneråd, men aritmetik.1

Intet ovenfor krævede et bibliotek. Her er hele optimizeren.

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

Det lukkede least-squares-svar for disse otte punkter er a=2.100403a = 2.100403, b=0b = 0, med et tab på 24.59244924.592449. Løkken fandt det med otte betydende cifre uden at vide, at en lukket form findes — hvilket betyder noget, for fra kapitel 5 og frem findes der ikke en.

Trajektorien, eftersom pointen er at se den:

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

Det meste af afstanden dækkes i de første to skridt, fordi gradienten er størst, når du er længst fra bunden, og krymper, når du nærmer dig. Gradient descent sænker automatisk farten nær et minimum. Det er en feature, og det er også, i kapitel 6, et problem.

Argumentet indtil nu har et hul. Skridtet stopper, når L=0\nabla L = \mathbf{0}, og vi har kaldt det „minimum”. Et punkt med nul gradient er et kritisk punkt, og at være et minimum er kun én af måderne at være det på:

  • et lokalt minimum: opad i alle retninger, men muligvis ikke det laveste sådanne punkt nogen steder;
  • et lokalt maksimum: nedad i alle retninger;
  • et saddelpunkt: opad i nogle retninger og nedad i andre. Fladen f(x,y)=x2y2f(x,y) = x^2 - y^2 har f=(2x,2y)\nabla f = (2x, -2y), som er nul i origo, hvor funktionen er et minimum langs xx-aksen og et maksimum langs yy-aksen på samme tid.

Gradient descent kan ikke skelne mellem dem, fordi den kun nogensinde ser på gradienten, og gradienten er nul ved alle tre.

Vores linje har ét kritisk punkt, og det er svaret — et kvadreret-fejl-tab over en lineær model er konvekst, en enkelt skål, og descent på det kan ikke undgå at finde det globale minimum. Den egenskab overlever ikke mødet med dette kursus. Tabet for et neuralt netværk er ikke konvekst, og fra kapitel 5 og frem er „minimum” ikke en ting, der findes: der er mange, med forskellige dybder, og hvilken en du får, afhænger af, hvor du startede. Det er én sætning og forbliver én sætning, fordi teorien er stor og den praktiske konsekvens lille.

Du kan se hele konsekvensen på én kurve. Tag f(x)=x44x22+x10f(x) = \tfrac{x^4}{4} - \tfrac{x^2}{2} + \tfrac{x}{10}, som har to dale med forskellige dybder:

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 trin, slutter ved x = 0.9456.

Se dataene som en tabel
Trinxf(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⁩
Gradientnedstigning, interaktiv

Fyrre skridt fra x=0.11x = 0.11, landende ved 0.94560.9456 — den grundere af de to dale. Flyt nu startpunktet ét hak til venstre, til 0.100.10. Samme rate, samme fyrre skridt, og den lander ved 1.0461-1.0461 i stedet, hvor tabet er 0,199747 lavere. Vandskellet er puklen ved 0.1010310.101031, og hele forskellen mellem de to svar er, hvilken side af den du tilfældigvis startede på.

At lande i den lave dal er 56,7% værre i tab, og algoritmen har ingen måde at vide det på, fordi fra inde i en dal går alle retninger opad. Der findes ingen reparation for dette i gradient descent, og der kommer ingen. Det, der findes i praksis, er konstateringen af, at det betyder langt mindre, end dette billede antyder — i de meget høje dimensioner af et rigtigt netværk viser de fleste kritiske punkter sig at være saddelpunkter snarere end fælder,2 og kapitel 5 måler, hvor ofte et lille netværk faktisk sidder fast.

Billigere skridt: stokastisk, minibatch, momentum

Link til afsnittet: Billigere skridt: stokastisk, minibatch, momentum

Én ting ved grad ovenfor bør genere dig: den summerer over hele datasættet for hvert skridt. Otte dele er ingenting. En million er en million gradientberegninger for at flytte parametrene én gang.

Udvejen er, at gradienten er et gennemsnit, og et gennemsnit kan estimeres fra en sample. Beregn den på en tilfældig håndfuld — en minibatch — og tag skridtet på den. Estimatet er støjende; det er også unbiased, og hundreder af billige, støjende skridt slår ét dyrt, præcist. På hundrede tusind syntetiske dele, talt som gradienter pr. eksempel snarere end skridt:

metodeskridt til inden for 0,1% af optimumgradienter pr. eksempel
full batch7700.000
minibatch på 321003.200
ét eksempel ad gangen17.58017.580

To hundrede og nitten gange mindre aritmetik for at nå samme sted. Og yderpunktet — ét eksempel ad gangen, den oprindelige stokastiske approximation fra Robbins og Monro3 — er ikke vinderen: den er fem gange værre end batches på 32, fordi 32 eksempler næsten ikke koster mere end ét på hardware, der multiplicerer matricer, mens støjen falder med kvadratroden af batchstørrelsen. Den afvejning er grunden til, at hvert træningsscript, du nogensinde læser, har en batch_size i sig.

Momentum er det andet billige fix, og det sigter direkte mod renden. I en dårligt konditioneret dal zigzagger skridtene over den smalle retning, mens de kryber langs den lange. Momentum holder et løbende gennemsnit af tidligere gradienter, så de oscillerende komponenter udligner hinanden, og den konsistente akkumuleres:4

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

To ekstra linjer. På det rå, ucentrerede bånd — konditionstal 33.452, det værste tilfælde vi har — ved den bedste rate, almindelig descent kan tage:

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%

En faktor 172 for to linjer kode. Kapitel 6 gør dette til Adam; mekanismen er allerede her.

Hver gradient i dette kapitel blev udledt i hånden og kunne derfor være forkert. Løsningen er hældningstabellen fra begyndelsen: mål den afledte numerisk og sammenlign. Brug den centrale differens, L(θ+h)L(θh)2h\frac{L(\theta+h) - L(\theta-h)}{2h}, som ophæver det ledende fejlled og er langt mere præcis for samme hh.

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)))

Den relative form af sammenligningen betyder noget: en absolut forskel på 10410^{-4} er en katastrofe på en gradient af størrelse 10310^{-3} og irrelevant på en af størrelse 10610^{6}.

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

Den første linje er den håndudledte gradient ovenfor. Den anden er den samme funktion med faktoren 2 udeladt i én komponent — en tastefejl på ét enkelt tegn — og tjekket fanger den med det samme. Alt under cirka 10710^{-7} er overensstemmelse; alt over 10410^{-4} er en bug. Behold denne funktion: kapitel 5 bruger den til at debugge en automatic differentiation-engine, og den er den eneste grund til, at en forkert gradient overhovedet kan findes.

Alt i dette kapitel hvilede på én antagelse, der aldrig blev sagt: at du kan skrive L/θ\partial L / \partial \theta ned.

For en linje med to parametre var det én linje algebra. Det holder næsten øjeblikkeligt op med at være det. Bed et symbolsk algebra-system om den afledte af et netværks tab med hensyn til en enkelt første-lags-vægt, for et enkelt eksempel, og tæl aritmetikken i svaret:

netværkoperationer i én partiel afledt
fire skjulte enheder, ét lag40
fire skjulte enheder, to lag301
fire skjulte enheder, tre lag1.717

Den tredje række er et netværk med 57 parametre — et netværk så lille, at det ville være en fodnote i kapitel 6 — og at skrive dets gradient ud i hånden betyder cirka 97.869 operationer for ét træningseksempel. Der er ingen notation, der redder dette. Det, der redder det, er observationen om, at kædereglen anvendt på en komposition har enorm struktur, at de samme mellemliggende størrelser dukker op igen og igen, og at beregning af dem i den rigtige rækkefølge giver alle de afledte til omtrent prisen for ét forward pass. Det er kapitel 5.

Men der er et mindre problem først, og det venter lige nu.

Vi har nu en maskine, der kan rulle nedad på ethvert differentiérbart tab. Peg den på båndets oprindelige spørgsmål — acceptér eller afvis, et target der er 1 eller 0 — sæt en sigmoid på outputtet, så den forudsiger en sandsynlighed, og minimér kvadreret fejl. Den vil køre. Den vil også knap nok bevæge sig, når den tager mest fejl, og gradienten siger hvorfor:

output zzforudsigelsesandhedgradient med kvadreret fejlgradient med 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

En model, der er selvsikkert, katastrofalt forkert — den forudsiger 0,0000454, når svaret er 1 — producerer en kvadreret-fejl-gradient på 9×1059 \times 10^{-5}. Den aner ikke, at den er i problemer. Den anden kolonne, fra et tab vi endnu ikke har udledt, rapporterer 1,0: maksimal hast, præcis hvor den er fortjent.

Hvilket rejser spørgsmålet, næste kapitel åbner med. Sidste kapitel sagde, at et tab er en antagelse om støjen, og kvadreret fejl antager Gaussisk støj. Hvilken støjmodel har et ja-eller-nej-svar — og hvilket tab kommer ud, når du kører den samme udledning på den?


Metoden er ældre end alle disse: Cauchy beskrev den i en note til Académie des Sciences i 1847, som en måde at løse ligningssystemer ved at gå nedad på summen af deres kvadrerede residualer. Det er også værd at læse sammen med dette kapitel: Sebastian Ruders An overview of gradient descent optimization algorithms (arXiv:1609.04747), som dækker momentum til Adam på fjorten læsevenlige sider; kapitel 3 i Nocedal og Wrights Numerical Optimization (2. udg., Springer, 2006), hvis sætning 3.3 giver konvergensraten for steepest descent på en kvadratisk funktion udtrykt ved konditionstallet — det er teorien bag, hvorfor konditionering afgør antallet af skridt, selvom den behandler line search snarere end det faste 2/λmax2/\lambda_{\max}-loft målt ovenfor, eller §5.8 og §7.1 i Deisenroth, Faisal og Ongs Mathematics for Machine Learning for samme stof med mindre maskineri; §6.1 i Princes Understanding Deep Learning og §4.3 i Goodfellow, Bengio og Courvilles Deep Learning; Dive into Deep Learning §12.1–12.3, som har minibatch-analysen med flere målinger, end der er plads til her; og kapitel 4 i Géron's Hands-On Machine Learning (3. udg.), den mest praktiske behandling af learning rate som noget, du tuner, snarere end udleder. MIT 6.390-noterne placerer gradient descent før klassifikation, som dette kursus gør og af samme grund.

  1. LeCun, Y., Bottou, L., Orr, G. B. og Müller, K.-R. Efficient BackProp, i Neural Networks: Tricks of the Trade (Springer, 1998), s. 9–50. Afsnit 4.3 giver anbefalingen og afsnit 5.1 argumentet brugt i detaljeboksen ovenfor: at centrere og skalere inputs ændrer egenværdierne for andenafledt-matricen og derfor antallet af skridt, ikke blot den numeriske komfort.

  2. Dauphin, Y. N., Pascanu, R., Gulcehre, C., Cho, K., Ganguli, S. og Bengio, Y. Identifying and attacking the saddle point problem in high-dimensional non-convex optimization, arXiv:1406.2572 (2014). Argumentet om, at kritiske punkter i høje dimensioner overvældende ofte er saddelpunkter snarere end lokale minima, eftersom et minimum kræver, at hver eneste af tusindvis af retninger krummer opad på én gang.

  3. Robbins, H. og Monro, S. A Stochastic Approximation Method. Annals of Mathematical Statistics 22(3), s. 400–407 (1951). Artiklen, der fastslog, at et støjende estimat af en gradient er nok, givet en skridtstørrelse, der krymper på den rigtige måde.

  4. Polyak, B. T. Some methods of speeding up the convergence of iteration methods. USSR Computational Mathematics and Mathematical Physics 4(5), s. 1–17 (1964). Heavy-ball-metoden, som er momentum-opdateringen ovenfor, toogtyve år før backpropagation nåede dette felt.

Klar til at lade LIA vælge for dig?

Byg med alle AI-modeller ét sted — kom gratis i gang i dag.