Siirry sisältöön
3/30Luku 3/30

Alamäkeen: Gradient Descent ja kaksi askelta, jotka kaikki ohittavat

Laske oppimisnopeuden tarkka yläraja ja katso, miten 3 600 suunnan raakavoimahaku löytää gradientin ilman vihjettä.

Tällä sivulla

Edellinen luku päättyi laaksoon.

Ei vertauskuvalliseen: ihan oikeaan käyrään, jossa häviö oli piirretty yhden parametrin funktiona, painui alas ja nousi takaisin ylös. Eikä sen alla olevaa häviötä valittu siksi, että se oli siisti — se johdettiin mittausten kohinaa koskevasta väitteestä, ja neliövirhe tuli ulos seurauksena eikä konventiona.

Meillä on siis maisema, jolla on pohja, ja syy uskoa, että pohja on oikea paikka olla. Meiltä puuttuu tapa päästä sinne.

Tässä luvussa rakennetaan sellainen, ja kyseessä on algoritmi, joka kouluttaa jokaisen mallin tämän kurssin loppuosassa — aivan jokaisen, poikkeuksetta, aina satojen miljardien parametrien malleihin asti. Se mahtuu noin kahteenkymmeneen riviin. Kaksi vaikeaa kohtaa eivät ole noissa kahdessakymmenessä rivissä, ja ne ovat kaksi asiaa, jotka melkein jokainen selitys ohittaa:

  • Miksi miinusmerkki. Päivitys vähentää gradientin. Jokainen opas kirjoittaa sen; hyvin harva sanoo, miksi gradientti on suunta, joka menee ylös, mikä on ainoa fakta, joka tekee miinusmerkistä jotain muuta kuin uskonvaraisen teon.
  • Miten suuri askel. ”Liian suuri hajaantuu, liian pieni on hidas” on totta ja hyödytöntä. On olemassa tarkka luku, se voidaan laskea häviöstä, ja tämä luku laskee sen kahdesti — kerran leluesimerkin paraabelille ja kerran oikealle datalle.

Asetelma ja miksi et voi vain hakea

Linkki osioon: Asetelma ja miksi et voi vain hakea

Kerrataan niin, että tämä luku seisoo omillaan: luvun 1 liukuhihnan kahdeksan osaa, mutta kysytään eri kysymys. Ei hyväksy vai hylkää — se palaa myöhemmin — vaan ennusta osan paino sen leveyden perusteella.

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

Mittaukset on keskitetty, täsmälleen kuten luvussa 1 ja syystä, joka palaa korkojen kanssa ennen tämän luvun loppua. Malli on suora, y^=ax+b\hat{y} = a x + b, ja häviö on edellisessä luvussa johdettu mean squared error:

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

Kaksi parametria. Miksei vain kokeilla paljon arvoja? Tehdään se oikeasti — ruudukko väliltä a=0a = 055 ja b=5b = -555, askelin 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

Puoli miljoonaa arviointia kahden luvun paikantamiseen kahden desimaalin tarkkuudella — ja tuo sekunti on seinäkelloaikaa yhdellä koneella, joten uusi ajo osuu minne tahansa kolmen ja kuuden välille; arviointien määrä ja minimi ovat se osa, joka toistuu. Gradient descent saa tämän luvun lopussa neljä desimaalia kahdeksassa askeleessa ja koko float64-vastauksen kolmessakymmenessäkuudessa.

Mutta nopeus ei ole argumentti, ja juuri tämä kohta ratkaisee koko kurssin. Ruudukkohaku maksaa kPk^P arviointia, kun parametreja on PP ja arvoja kullakin kk. Tuhannella arvolla akselia kohti:

malliparametritruudukkoarvioinnit
tämä suora210610^{6}
luvun 5 XOR-verkko9102710^{27}
pieni monikerroksinen verkko20 0001060,00010^{60{,}000}

Kolmas rivi ei ole suuri luku, vaan merkityksetön — havaittavassa maailmankaikkeudessa on karkeasti 108010^{80} atomia. Haku ei hidastu mallien kasvaessa; se lakkaa olemasta. Kaikki seuraava on olemassa tuon taulukon takia.

Derivaatta on mittaus, jonka voit tehdä

Linkki osioon: Derivaatta on mittaus, jonka voit tehdä

Kiinnitä hetkeksi b=0b = 0, jotta jäljellä on yksi parametri ja yksi käyrä, eli juuri se kuva, johon edellinen luku jätti sinut. Ota siltä piste, a=1a = 1, ja kysy: jos tönäisen aa:tä pienellä määrällä hh, kuinka paljon häviö liikkuu tönäisyn yksikköä kohti?

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

Tuo suhde on nousu jaettuna etenemällä — käyrän kahden pisteen kautta kulkevan suoran kulmakerroin. Kun hh kutistuu, pisteet liukuvat yhteen ja suorasta tulee tangentti. Sen kulmakerroin on derivaatta L(a)L'(a): nopeus, jolla häviö muuttuu, kun aa muuttuu yhden yksikön. Ei minkään approksimaatio eikä äärettömän pieni suure. Tavallisten suhteiden raja-arvo.

Tämä kannattaa ajaa, koska luvut kertovat jotain, mitä määritelmä ei kerro:

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

Tässä tapahtuu kaksi asiaa, ja molemmat kantavat rakennetta.

Virhe ei ole epämääräisesti verrannollinen hh:ään — se on täsmälleen 7.445h7.445\,h. Jaa hh sadalla, virhe jakautuu sadalla, neljän merkitsevän numeron tarkkuudella joka kerta. Tuo vakio ei ole koriste: se on puolet häviön toisesta derivaatasta, ja se on ensiesiintyminen ajatukselle, johon tullaan kahden osion päästä — että käyrä pisteen lähellä näyttää suoralta plus korjaukselta, joka on verrannollinen h2h^2:ään.

Ja sitten kuvio rikkoutuu. Alle h=108h = 10^{-8} arvionti muuttuu huonommaksi, ja kohdassa 101410^{-14} se on väärin jo toisessa numerossa. Matematiikassa ei tapahtunut mitään; edellisen luvun liukulukulaatikko tapahtui. L(a+h)L(a+h) ja L(a)L(a) ovat samaa mieltä ensimmäisistä kymmenestä numerostaan, niiden vähentäminen tuhoaa nuo numerot, ja raunioiden jakaminen pienellä luvulla vahvistaa sen, mitä jäi jäljelle. On olemassa paras hh — tässä noin 10810^{-8}, suunnilleen kone-epsilonin neliöjuuri — ja pienemmäksi meneminen ei ole huolellisempaa vaan vähemmän huolellista. Muista tämä; tämän luvun lopussa oleva funktio riippuu siitä.

Tarkka kulmakerroin, laskennasta mittauksen sijaan, on 16.385-16.385. Voimme siis lopettaa mittaamisen ja aloittaa johtamisen.

Tässä on ajatus, jonka varaan loppukurssi rakentuu, kerran ja selvästi sanottuna.

Kahden funktion kompositio tarkoittaa, että syötät toisen toiseen: (fg)(x)=f(g(x))(f \circ g)(x) = f(g(x)). Ei muuta.

Syvä verkko ei ole kuin kompositio. Se on sellainen. Kerros on funktio; kerrosten pinoaminen on niiden komponointia; ”syvyys” on funktioiden määrä ketjussa. Kun luvussa 5 rakennetaan verkko, rakennetaan f4f3f2f1f_4 \circ f_3 \circ f_2 \circ f_1 eikä mitään muuta. Tämä tarkoittaa, että meidän tarkoituksiimme laskennan tärkein yksittäinen sääntö on se, joka derivoi komposition:

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

Nopeudet kertautuvat. Jos gg muuttuu kolme kertaa niin nopeasti kuin xx, ja ff muuttuu kaksi kertaa niin nopeasti kuin gg, silloin ff muuttuu kuusi kertaa niin nopeasti kuin xx. Siinä on koko sisältö, ja siksi kymmenen kerroksen läpi takaisin kulkeva signaali kerrotaan kymmenellä luvulla — minkä vuoksi luku 6 käyttää yhden osion siihen, mitä tapahtuu, kun nuo luvut ovat kaikki hieman alle yhden.

Käytä sitä häviöömme. Kirjoita residuaali ri=axi+byir_i = a x_i + b - y_i, jolloin L=1nri2L = \frac{1}{n}\sum r_i^2. Jokainen rir_i riippuu aa:sta sisäfunktion axia x_i kautta, jonka derivaatta on xix_i. Ketjusääntö termi termiltä:

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

Nuo kaarevat \partial-symbolit merkitsevät osittaisderivaattaa: derivoi yhden muuttujan suhteen ja käsittele kaikkia muita vakioina. Mitään uutta ei tapahdu — se on sama raja-arvo kuin aiemmin, otettuna yhtä akselia pitkin. Kerää osittaisderivaatat vektoriksi ja sinulla on gradientti:

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

Pisteessä (a,b)=(1,4)(a, b) = (1, 4) tuo vektori on (16.385, 8.0)(-16.385,\ 8.0). Kaksi lukua. Kysymys on, mitä ne tarkoittavat, ja tämä on ensimmäinen askel, jonka kaikki ohittavat.

Miksi gradientti osoittaa ylämäkeen

Linkki osioon: Miksi gradientti osoittaa ylämäkeen

Gradientti on akselien suuntaisten kulmakertoimien vektori. Siinä kaikki, mitä olemme todistaneet. Ei ole ilmeistä — eikä sen pidäkään olla ilmeistä — että niiden kokoaminen vektoriksi tuottaisi jotain, joka osoittaa mihinkään erityiseen.

Määritellään siis se, mitä oikeasti haluamme. Valitse yksikkövektori u\mathbf{u}, suunta. Suuntaderivaatta on nopeus, jolla häviö muuttuu, kun kävelet siihen suuntaan:

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

Ketjusääntö muuttaa tämän laskettavaksi. Käveleminen u\mathbf{u}:n suuntaan muuttaa aa:tä nopeudella u1u_1 ja bb:ta nopeudella u2u_2, ja vaikutukset lasketaan yhteen:

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}

Muutosnopeus missä tahansa suunnassa on gradientin ja tuon suunnan pistetulo. Ja nyt loppuhuipennus, joka on yksi rivi geometriaa. Kun pistetulo kirjoitetaan vektorien välisen kulman ϕ\phi avulla,

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

koska u\mathbf{u}:n pituus on 1. Ainoa asia, jota hallitset, on cosϕ\cos\phi, joka on suurin kohdassa ϕ=0\phi = 0 ja pienin puolen kierroksen päässä, ϕ=180\phi = 180 asteessa. Siis:

  • Jyrkin nousu on itse L\nabla L:n suuntainen, ja kulmakerroin siellä on täsmälleen L\lVert \nabla L \rVert.
  • Jyrkin lasku on L-\nabla L:n suuntainen, ja kulmakerroin siellä on L-\lVert \nabla L \rVert.
  • Gradienttiin nähden kohtisuorassa häviö ei muutu lainkaan. Siksi korkeuskäyrät leikkaavat gradientin suorassa kulmassa.

Siinä on miinusmerkki. Ei konventio, ei jonkun valitsema merkinvaihto: nopeimman pienenemisen suunta on negatiivinen gradientti, koska cosϕ\cos\phi minimoituu puolen kierroksen päässä, eikä mistään muusta syystä.

Koska tämä on väite kaikista suunnista, testataan sitä kaikilla suunnilla. Otetaan 3 600 näytettä, yksi joka kymmenenneltä asteelta, ja mitataan jokainen tönäisemällä:

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

Haku, joka ei tiedä gradienteista mitään, löytää 3 600 suunnan joukosta jyrkimmän nousunsa 154,0 asteesta — gradientin omasta suunnasta, haun 0,1 asteen resoluution rajoissa. Ja sen löytämä kulmakerroin, 18,2337, on gradientin pituus kuuden merkitsevän numeron tarkkuudella. Lause ei ole tarina siitä, mitä gradientit merkitsevät; se on mitattava fakta, ja tuo on mittaus.

Miksi pieni askel alamäkeen oikeasti auttaa

Linkki osioon: Miksi pieni askel alamäkeen oikeasti auttaa

Nyt toinen ohitettu askel. Tiedämme, mikä suunta on alas. Siitä ei seuraa, että siihen suuntaan käveleminen pienentää häviötä, koska ”alas” on väite infinitesimaalisesta tönäisystä, eikä askel ole infinitesimaalinen.

Silta on linearisointi. Pisteen lähellä sileä funktio on tangenttinsa plus korjaus:

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

Se on ensimmäisen kertaluvun Taylorin kehitelmä. Pois jätetty O(δ2)O(\lVert\boldsymbol{\delta}\rVert^2) on kaarevuus — sama termi, joka teki kulmakerrointaulukon arviosta väärän täsmälleen 7.445h7.445\,h:n verran. Sijoita siihen askel, jonka aiomme ottaa, δ=η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

Häviö putoaa ηL2\eta \lVert \nabla L \rVert^2. Jokainen osa siitä on epänegatiivinen, joten lupaus on todellinen — riittävän pienelle η\eta:lle, koska laiminlyöty termi kasvaa kuten η2\eta^2 ja syö sen lopulta. Siinä koko teoria. Tässä lupaus pidetään ja sitten rikotaan:

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

Lue alhaalta. Kun η\eta kutistuu, toteutunut pudotus lähestyy luvattua — suhde 0,99938, sitten 0,99994 — eli Taylorin lause on oikeassa. Lue ylhäältä ja kohdassa η=0.2\eta = 0.2 toteutunut ”pudotus” on negatiivinen kuusitoista. Askel meni alamäkeen ja häviö nousi.

Päivityssääntö on siis

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

ja siihen liittyy ehto, jota kukaan ei sano ääneen: η\eta on riittävän pieni. Riittävän pieni verrattuna mihin, täsmälleen, on seuraavan osion aihe.

Oppimisnopeudella on yläraja, ja se voidaan laskea

Linkki osioon: Oppimisnopeudella on yläraja, ja se voidaan laskea

Aloita yksinkertaisimmasta mahdollisesta laaksosta, f(x)=x2f(x) = x^2, jossa f(x)=2xf'(x) = 2x. Yksi gradient descent -askel on

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

Sijainti kerrotaan luvulla (12η)(1 - 2\eta) joka askeleella. Se on geometrinen jono, ja geometrisilla jonoilla on tasan yksi sääntö: ne kutistuvat, kun kerroin on itseisarvoltaan pienempi kuin 1, ja kasvavat muuten. Siis 12η<1\lvert 1 - 2\eta \rvert < 1, eli 0<η<10 < \eta < 1.

Raja on täsmälleen kohdassa η=1\eta = 1. Ei ”noin 1”, ei ”1 on yleensä liian iso”. Kohdassa η=1\eta = 1 kerroin on 1-1 ja piste pomppii ikuisesti xx:n ja x-x:n välillä, ei lähestyen eikä paeten. Sen alapuolella konvergoi; sen yläpuolella hajaantuu. Väli jakautuu uudelleen kohdassa η=0.5\eta = 0.5, jossa kerroin vaihtaa merkkiä: sen alapuolella lähestyminen on monotonista, sen yläpuolella piste ylittää pohjan ja vuorottelee puolilla, ja täsmälleen kohdassa 0.50.5 kerroin on 0 ja yksi ainoa askel laskeutuu minimiin.

Neljä regiimiä neljästä algebrarivistä. Mene ja ylitä rajat itse:

Askelia 14, lopuksi x = -0.0836.

Näytä tiedot taulukkona
Askelxf(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⁩
Interaktiivinen gradienttilaskeutuminen

Neljätoista askelta nopeudella 0,1, alkaen kohdasta x=1.9x = -1.9 ja päättyen kohtaan 0.0836-0.0836. Nosta nopeus 0,5:een ja ensimmäinen askel laskeutuu pohjalle. Nosta se 0,9:ään ja se päätyy samaan 0.0836-0.0836:aan kuin 0,1 — sama etäisyys, eri tyyli, koska 12η\lvert 1 - 2\eta \rvert on 0,8 molemmille — mutta se pääsee sinne siksakkaamalla laakson yli sen sijaan, että kävelisi alas yhtä reunaa.

Ja nyt kiinnostava tapaus:

Askelia 14, lopuksi x = -1.9000.

Näytä tiedot taulukkona
Askelxf(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⁩
Interaktiivinen gradienttilaskeutuminen

Täsmälleen rajalla. Neljätoista askelta nopeudella 1, ja se päätyy kohtaan 1.9-1.9: täsmälleen sinne, mistä se aloitti, tekemättä muuta kuin pomppimista. Yksi tönäisy ylemmäs ja pomppiminen kasvaa paikallaan pysymisen sijaan; nopeudella 1,2 se on ulkona kaaviosta neljässä askeleessa. Liian suuri nopeus ei konvergoi hitaasti. Se ei konvergoi.

Nyt yleinen sääntö, joka putoaa ulos samasta argumentista. Kerroin 12η1 - 2\eta oli oikeasti 1ηf1 - \eta f'', ja minimin lähellä moniparametrisella häviöllä on yksi tällainen luku jokaista suuntaa kohti — toisten derivaattojen matriisin ominaisarvot. Jokaisen suunnan täytyy olla vakaa yhtä aikaa, joten ylärajan asettaa suurin:

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

Kun f(x)=x2f(x) = x^2, f=2f'' = 2, yläraja on 1, mikä on juuri se, minkä johdimme. Hihnallemme toisen derivaatan matriisi on 2nAA\frac{2}{n} A^{\top} A, jossa AA on syötteiden kaksisarakkeinen matriisi, ja sen ominaisarvot ovat 2 ja 14,89, joten yläraja on 2/14.89=0.134322 / 14.89 = 0.13432. Se on ennuste viiden merkitsevän numeron tarkkuudella. Testataan se:

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

Viisi desimaalia yhteensopivuutta yhden lineaarialgebrarivin ja for-silmukan sadantuhannen iteraation välillä.

Ja tässä luku 1 palaa. Kaikki edellä käytti keskitettyjä mittauksia. Aja identtinen koodi raaoilla millimetreillä ja grammoilla, ja ominaisarvot ovat 0,0298 ja 998,1 eivätkä 2 ja 14,89. Yläraja romahtaa 0,134:stä arvoon 0,002004 — yhtä täsmällisesti, konvergoiden kohdassa lr=0.002003 ja räjähtäen kohdassa lr=0.002004.

Ylärajaa pahempi on ominaisarvojen välinen suhde. Kuntoluku mittaa, kuinka kaukana pyöreästä laakso on: pitkä kapea uoma pakottaa nopeuden riittävän pieneksi jyrkille seinämille, ja sitten uoman pohjaa kävellään samalla matelevalla vauhdilla. Meillä se muuttuu keskitetyn datan 7,44:stä raa'an datan 33 452:een. Parhaalla nopeudella, jonka kumpikin versio voi ottaa:

piirteetkuntolukuparas nopeusaskeleet 1 %:n päähän optimista
keskitetty7,440,118410
raa'at millimetrit ja grammat33 4520,002003779 513

Sama data, sama koodi, sama vastaus lopussa — ja kahdeksantuhatta kertaa työ, koska kukaan ei vähentänyt keskiarvoa. Luvussa 1 sama poisjättö maksoi perceptronille kuudentuhannen kertoimen epookeissa, ja diagnoosi oli siellä geometrinen: data leijui kaukana origosta. Tässä se on sama geometria optimoinnin asussa, ja siksi syötteen normalisointi ei ole hygieniaohje vaan aritmetiikkaa.1

Mikään edellä ei tarvinnut kirjastoa. Tässä on koko optimoija.

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

Suljetun muodon least-squares-vastaus näille kahdeksalle pisteelle on a=2.100403a = 2.100403, b=0b = 0, häviöllä 24.59244924.592449. Silmukka löysi sen kahdeksan merkitsevän numeron tarkkuudella tietämättä, että suljettu muoto on olemassa — millä on väliä, koska luvusta 5 eteenpäin sellaista ei ole.

Trajektori, koska sen katsominen on asian ydin:

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

Suurin osa matkasta taittuu kahdessa ensimmäisessä askeleessa, koska gradientti on suurin silloin, kun olet kauimpana pohjasta, ja kutistuu lähestyessäsi. Gradient descent hidastuu automaattisesti minimin lähellä. Se on ominaisuus, ja luvussa 6 se on myös ongelma.

Missä muualla kulmakerroin on nolla

Linkki osioon: Missä muualla kulmakerroin on nolla

Tähänastisessa argumentissa on aukko. Askel pysähtyy, kun L=0\nabla L = \mathbf{0}, ja olemme kutsuneet sitä ”minimiksi”. Piste, jossa gradientti on nolla, on kriittinen piste, ja miniminä oleminen on vain yksi tapa olla sellainen:

  • paikallinen minimi: ylämäkeä joka suuntaan, mutta mahdollisesti ei matalin tällainen piste missään;
  • paikallinen maksimi: alamäkeä joka suuntaan;
  • satulapiste: ylämäkeä joihinkin suuntiin ja alamäkeä toisiin. Pinta f(x,y)=x2y2f(x,y) = x^2 - y^2 saa f=(2x,2y)\nabla f = (2x, -2y), joka on nolla origossa, jossa funktiolla on minimi xx-akselin suunnassa ja maksimi yy-akselin suunnassa samaan aikaan.

Gradient descent ei voi erottaa näitä toisistaan, koska se katsoo aina vain gradienttia, ja gradientti on kaikissa kolmessa nolla.

Suorallamme on yksi kriittinen piste ja se on vastaus — lineaarisen mallin squared-error-häviö on konveksi, yksi kulho, eikä descent voi epäonnistua löytämään sen globaalia minimiä. Tämä ominaisuus ei selviä kosketuksesta tähän kurssiin. Neuroverkon häviö ei ole konveksi, ja luvusta 5 eteenpäin ”minimi” ei ole asia, joka olisi olemassa: niitä on monta, eri syvyisiä, ja se, minkä saat, riippuu siitä, mistä aloitit. Tämä on yksi virke ja pysyy yhtenä virkkeenä, koska teoria on suuri ja käytännön seuraus pieni.

Näet koko seurauksen yhdellä käyrällä. Ota f(x)=x44x22+x10f(x) = \tfrac{x^4}{4} - \tfrac{x^2}{2} + \tfrac{x}{10}, jolla on kaksi eri syvyistä laaksoa:

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

Askelia 40, lopuksi x = 0.9456.

Näytä tiedot taulukkona
Askelxf(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⁩
Interaktiivinen gradienttilaskeutuminen

Neljäkymmentä askelta kohdasta x=0.11x = 0.11, asettuen arvoon 0.94560.9456 — kahdesta laaksosta matalampaan. Siirrä nyt aloituspistettä yhden pykälän vasemmalle, kohtaan 0.100.10. Sama nopeus, samat neljäkymmentä askelta, ja se asettuu sen sijaan kohtaan 1.0461-1.0461, jossa häviö on 0,199747 pienempi. Vedenjakaja on kumpu kohdassa 0.1010310.101031, ja koko ero kahden vastauksen välillä on se, kummalle puolelle sitä satuit aloittamaan.

Matalaan laaksoon laskeutuminen on häviössä 56,7 % huonompi, eikä algoritmilla ole tapaa tietää sitä, koska laakson sisältä jokainen suunta on ylämäkeä. Gradient descent ei tarjoa tähän korjausta, eikä sellaista ole tulossa. Käytännössä on sen sijaan havainto, että asialla on paljon vähemmän väliä kuin tämä kuva antaa ymmärtää — oikean verkon hyvin korkeissa dimensioissa useimmat kriittiset pisteet osoittautuvat satuloiksi eivätkä ansoiksi,2 ja luku 5 mittaa, kuinka usein pieni verkko oikeasti jää jumiin.

Halvemmat askeleet: stokastinen, minibatch, momentum

Linkki osioon: Halvemmat askeleet: stokastinen, minibatch, momentum

Yhden asian yllä olevassa grad:ssa pitäisi häiritä sinua: se summaa koko datasetin yli jokaista askelta varten. Kahdeksan osaa ei ole mitään. Miljoona on miljoona gradienttilaskua, jotta parametrit liikkuvat kerran.

Pakotie on se, että gradientti on keskiarvo, ja keskiarvo voidaan arvioida otoksesta. Laske se satunnaisella kourallisella — minibatch — ja astu sen mukaan. Arvio on kohinainen; se on myös harhaton, ja sadat halvat kohinaiset askeleet voittavat yhden kalliin tarkan. Sadallatuhannella synteettisellä osalla, laskien esimerkkikohtaisia gradientteja askelten sijaan:

menetelmäaskeleet 0,1 %:n päähän optimistaesimerkkikohtaiset gradientit
full batch7700 000
minibatch, 321003 200
yksi esimerkki kerrallaan17 58017 580

Kaksisataayhdeksäntoista kertaa vähemmän aritmetiikkaa samaan paikkaan pääsemiseksi. Ja ääripää — yksi esimerkki kerrallaan, Robbinsin ja Monron alkuperäinen stokastinen approksimaatio3 — ei ole voittaja: se on viisi kertaa huonompi kuin 32:n batchit, koska 32 esimerkkiä ei maksa juuri mitään enempää kuin yksi laitteistolla, joka kertoo matriiseja, samalla kun kohina pienenee batch-koon neliöjuuren mukaan. Tämä vaihtokauppa on syy, miksi jokaisessa koskaan lukemassasi koulutusskriptissä on batch_size.

Momentum on toinen halpa korjaus, ja se tähtää suoraan uomaan. Huonosti ehdollistetussa laaksossa askeleet siksakkaavat kapean suunnan yli samalla kun ne ryömivät pitkää suuntaa pitkin. Momentum pitää liukuvaa keskiarvoa menneistä gradienteista, jolloin värähtelevät komponentit kumoavat toisensa ja johdonmukainen komponentti kasautuu:4

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

Kaksi lisäriviä. Raa'alla keskittämättömällä hihnalla — kuntoluku 33 452, pahin tapauksemme — parhaalla nopeudella, jonka tavallinen descent kestää:

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%

Kerroin 172 kahdella koodirivillä. Luku 6 muuttaa tämän Adamiksi; mekanismi on jo tässä.

Tarkistus, jota tarvitset luvussa 5

Linkki osioon: Tarkistus, jota tarvitset luvussa 5

Jokainen tämän luvun gradientti johdettiin käsin ja voi siksi olla väärin. Korjaus on alun kulmakerrointaulukko: mittaa derivaatta numeerisesti ja vertaa. Käytä central difference -menetelmää, L(θ+h)L(θh)2h\frac{L(\theta+h) - L(\theta-h)}{2h}, joka kumoaa johtavan virhetermin ja on samalla hh:lla paljon tarkempi.

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

Vertailun suhteellisella muodolla on väliä: absoluuttinen ero 10410^{-4} on katastrofi gradientilla, jonka koko on 10310^{-3}, ja merkityksetön sellaisella, jonka koko on 10610^{6}.

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

Ensimmäinen rivi on yllä käsin johdettu gradientti. Toinen on sama funktio, josta yhden komponentin kerroin 2 on jätetty pois — yhden merkin kirjoitusvirhe — ja tarkistus nappaa sen heti. Kaikki alle noin 10710^{-7} on yhteensopivuutta; kaikki yli 10410^{-4} on bugi. Säilytä tämä funktio: luku 5 käyttää sitä automaattisen differentiointimoottorin debuggaukseen, ja se on ainoa syy, miksi väärä gradientti on ylipäätään löydettävissä.

Kaikki tässä luvussa nojasi yhteen oletukseen, jota ei koskaan sanottu ääneen: että voit kirjoittaa L/θ\partial L / \partial \theta ylös.

Suoralle, jolla on kaksi parametria, se oli yksi rivi algebraa. Se lakkaa olemasta sitä melkein heti. Pyydä symbolisen algebran järjestelmältä verkon häviön derivaattaa yhden ensimmäisen kerroksen painon suhteen, yhdelle esimerkille, ja laske vastauksen aritmeettiset operaatiot:

verkkooperaatiot yhdessä osittaisderivaatassa
neljä piiloyksikköä, yksi kerros40
neljä piiloyksikköä, kaksi kerrosta301
neljä piiloyksikköä, kolme kerrosta1 717

Kolmas rivi on verkko, jossa on 57 parametria — niin pieni verkko, että se olisi alaviite luvussa 6 — ja sen gradientin kirjoittaminen käsin tarkoittaa noin 97 869 operaatiota yhdelle koulutusesimerkille. Mikään notaatio ei pelasta tätä. Pelastuksen tuo havainto, että kompositioon sovelletussa ketjusäännössä on valtava rakenne, että samat välisuureet esiintyvät uudelleen ja uudelleen, ja että niiden laskeminen oikeassa järjestyksessä antaa kaikki derivaatat suunnilleen yhden forward passin hinnalla. Se on luku 5.

Mutta ensin on pienempi ongelma, ja se odottaa heti.

Meillä on nyt kone, joka vierii alamäkeen millä tahansa derivoituvalla häviöllä. Osoita se hihnan alkuperäiseen kysymykseen — hyväksy vai hylkää, tavoite joka on 1 tai 0 — laita ulostuloon sigmoid, jotta se ennustaa todennäköisyyttä, ja minimoi squared error. Se toimii. Se myös liikkuu tuskin lainkaan silloin, kun se on eniten väärässä, ja gradientti kertoo miksi:

ulostulo zzennustetotuusgradientti squared errorillagradientti cross-entropylla
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

Malli, joka on itsevarmasti, katastrofaalisesti väärässä — ennustaa 0,0000454, kun vastaus on 1 — tuottaa squared-error-gradientin 9×1059 \times 10^{-5}. Sillä ei ole aavistustakaan, että se on pulassa. Toinen sarake, häviöstä jota emme ole vielä johtaneet, ilmoittaa 1,0: maksimaalinen kiireellisyys täsmälleen siellä, missä se ansaitaan.

Tästä nousee kysymys, jolla seuraava luku avaa. Edellinen luku sanoi, että häviö on oletus kohinasta, ja squared error olettaa Gaussisen kohinan. Millainen kohinamalli kyllä-tai-ei-vastauksella on — ja mikä häviö tulee ulos, kun ajat saman johdon sille?


Menetelmä on näitä kaikkia vanhempi: Cauchy kuvasi sen Académie des Sciencesille lähettämässään muistiossa vuonna 1847 tapana ratkaista yhtälöryhmiä kävelemällä alamäkeen niiden neliöityjen residuaalien summalla. Tämän luvun rinnalla kannattaa lukea myös Sebastian Ruderin An overview of gradient descent optimization algorithms (arXiv:1609.04747), joka kattaa momentumin Adamista lähtien neljässätoista luettavassa sivussa; Nocedalin ja Wrightin Numerical Optimization -teoksen (2. painos, Springer, 2006) luku 3, jonka lause 3.3 antaa jyrkimmän descentin konvergenssinopeuden neliömuodolla kuntoluvun avulla — se on teoria sen takana, miksi ehdollisuus ratkaisee askelmäärän, vaikka se käsittelee line searchia eikä yllä mitattua kiinteän askeleen 2/λmax2/\lambda_{\max}-ylärajaa; tai Deisenrothin, Faisalin ja Ongin Mathematics for Machine Learning -teoksen §5.8 ja §7.1 samasta aiheesta vähemmällä koneistolla; Princen Understanding Deep Learning -teoksen §6.1 ja Goodfellow’n, Bengion ja Courvillen Deep Learning -teoksen §4.3; Dive into Deep Learning §12.1–12.3, jossa on minibatch-analyysiä useammilla mittauksilla kuin tänne mahtuu; sekä Géronin Hands-On Machine Learning -teoksen (3. painos) luku 4, käytännöllisin käsittely oppimisnopeudesta asiana, jota säädetään eikä johdeta. MIT 6.390 -muistiinpanot laittavat gradient descentin ennen luokittelua, kuten tämä kurssi tekee ja samasta syystä.

  1. LeCun, Y., Bottou, L., Orr, G. B. ja Müller, K.-R. Efficient BackProp, teoksessa Neural Networks: Tricks of the Trade (Springer, 1998), s. 9–50. Osio 4.3 antaa suosituksen ja osio 5.1 yllä olevan tietolaatikon argumentin: syötteiden keskittäminen ja skaalaaminen muuttaa toisen derivaatan matriisin ominaisarvoja ja siten askelten määrää, ei vain numeerista mukavuutta.

  2. Dauphin, Y. N., Pascanu, R., Gulcehre, C., Cho, K., Ganguli, S. ja Bengio, Y. Identifying and attacking the saddle point problem in high-dimensional non-convex optimization, arXiv:1406.2572 (2014). Argumentti siitä, että korkeissa dimensioissa kriittiset pisteet ovat ylivoimaisesti useammin satuloita kuin paikallisia minimejä, koska minimi vaatii jokaisen tuhansista suunnista kaartuvan ylöspäin yhtä aikaa.

  3. Robbins, H. ja Monro, S. A Stochastic Approximation Method. Annals of Mathematical Statistics 22(3), s. 400–407 (1951). Artikkeli, joka osoitti, että kohinainen gradientin arvio riittää, kun askelkoko pienenee oikealla tavalla.

  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-menetelmä, joka on yllä oleva momentum-päivitys, kaksikymmentäkaksi vuotta ennen kuin backpropagation saavutti tämän alan.


Tekijä

David Vicente Campos

NeuraLIA Labsin perustaja ja MyRealFoodin toinen perustaja

Olen valmistunut tietotekniikan insinööriksi Leónin yliopistosta. Olin mukana perustamassa MyRealFoodia, jossa teknologiajohtajana rakensin sovelluksen, jota miljoonat ihmiset ovat käyttäneet syödäkseen paremmin, ja perustin NeuraLIA Labsin, jossa rakennan tekoälytuotteita. Täällä kirjoitan siitä, mitä minun on pitänyt ymmärtää matkan varrella, niin kuin olisin toivonut jonkun selittävän asiat minulle.

Lisää kirjoittajasta

Julkaisija: NeuraLIA Labs.

Uudet julkaisut suoraan sähköpostiisi

AI-uutisia, oppaita ja tuoteuutisia — lyhyt sähköposti, kun julkaisemme jotain aikasi arvoista.

Kurssin hakemisto

Abstract software decision engine with branching paths, probability nodes, and glowing gates.
jev9 min lukuaikaa

Jev AI -malli on rakennettu päätöksiä, ei proosaa varten

TypeSafe AI:n Jev herättää huomiota, koska se käsittelee ohjelmistojen älykkyyttä todennäköisyysongelmana: valitse oikea haara, liitä mukaan varmuus ja vältä maksamasta LLM:lle tekstin kirjoittamisesta, kun koodi tarvitsee päätöksen.

Abstract agent runtime sorting documents, memory blocks and pointer nodes inside a bounded context frame.
context-engineering9 min lukuaikaa

Kontekstisuunnittelu pitkän aikavälin AI-agenteille

Pitkäkestoiset agentit eivät epäonnistu vain siksi, että ikkuna on pieni. Ne epäonnistuvat, kun tiedostot, työkalujen tulosteet ja vanhentunut historia syrjäyttävät tehtävän, joka agentin piti saada valmiiksi.

Valmis antamaan LIA:n valita puolestasi?

Rakenna kaikilla tekoälymalleilla yhdessä paikassa — aloita ilmaiseksi jo tänään.