11.2 Parciális derivált és gradiens

A Meredekség és numerikus derivált alfejezet egyetlen bemeneti koordináta mentén értelmezte a deriváltat. A predikciós modellek azonban általában több paraméterrel dolgoznak: egy lineáris modell súlyvektora pp dimenziós, és a veszteségfüggvény minden paraméter együttesétől függ. Itt két paraméter felületén dolgozunk, hogy megkülönböztessük az egyirányú változást a teljes gradiensvektortól.

Konkrét helyzet. Bemenet: a w1,w2w_1,w_2 paraméterpárból álló 𝐰∈ℝ2\mathbf w\in\mathbb R^2 vektor; megfigyelési egység: egy paraméterpont; kimenet: a skalár veszteség

L(w1,w2)=w12+4w22.L(w_1,w_2)=w_1^2+4w_2^2.

Cél: kiszámítani a parciális deriváltakat és a gradienst, megrajzolni a szintvonalakat (contour), majd három gradienslépés irányát megjelölni. Ellenőrzési feltétel: a parciális deriváltak numerikus centrális közelítése a (2,1.5)(2, 1.5) pontban 10−510^{-5}-ön belül egyezzen a képletből kapott értékkel, és mindhárom gradienslépés csökkentse a veszteséget. Induló becslés: a (2,1.5)(2, 1.5) pontban L=22+4⋅1.52=13L=2^2+4\cdot 1.5^2=13; várt gradiens (2w1,8w2)=(4,12)(2w_1, 8w_2)=(4,12); az η=0.1\eta=0.1 tanulási rátával tett három lépés után a veszteség 1313-ról körülbelül 1.051.05-re csökken.

11.2.1 Parciális derivált és gradiens

Egy f:ℝp→ℝf:\mathbb R^p\to\mathbb R függvény jj-edik koordinátája szerinti parciális deriváltja (partial derivative) azt méri, hogyan változik a kimenet, ha csak a wjw_j bemenetet mozdítjuk, a többi koordinátát pedig rögzítjük:

∂L∂wj=limh→0L(w1,…,wj+h,…,wp)−L(w1,…,wj,…,wp)h.\frac{\partial L}{\partial w_j}=\lim_{h\to 0}\frac{L(w_1,\dots,w_j+h,\dots,w_p)-L(w_1,\dots,w_j,\dots,w_p)}{h}.

Jelölések: j=1,…,pj=1,\dots,p a koordináta indexe; h∈ℝh\in\mathbb R a kis lépés; LL a skalár kimenet. A megszokott egyenes dd helyett a görbített ∂\partial jel különbözteti meg a többváltozós esetet. A mértékegység ugyanaz a logika, mint az egyváltozós deriváltnál: a veszteség egysége osztva a jj-edik paraméter egységével.

A példánkban a w2w_2 rögzítésével w1w_1 egyváltozós függvényként viselkedik, ezért a Meredekség és numerikus derivált alfejezetben tanult szabállyal

∂L∂w1=2w1,∂L∂w2=8w2.\frac{\partial L}{\partial w_1}=2w_1,\qquad \frac{\partial L}{\partial w_2}=8w_2.

A gradiens (gradient) a parciális deriváltakat egyetlen, a bemenettel azonos dimenziójú vektorba gyűjti:

∇L(𝐰)=[∂L∂w1⋮∂L∂wp].\nabla L(\mathbf w)=\begin{bmatrix}\frac{\partial L}{\partial w_1}\\ \vdots\\ \frac{\partial L}{\partial w_p}\end{bmatrix}.

A ∇\nabla (nabla) operátor jelzi, hogy minden koordináta szerinti deriváltat egyszerre képzünk. A NumPy-tömbben a gradiens shape-je ugyanaz, mint a paramétervektoré, tehát esetünkben (2,)(2,). A példában

∇L(w1,w2)=[2w18w2].\nabla L(w_1,w_2)=\begin{bmatrix}2w_1\\ 8w_2\end{bmatrix}.

A gradiens pontbeli értéke a (2,1.5)(2, 1.5) pontban

∇L(2,1.5)=[412].\nabla L(2,1.5)=\begin{bmatrix}4\\ 12\end{bmatrix}.

A gradiens nem két egymástól független szám: vektorként iránya és hossza is van. A hossz a Mátrixszorzás és lineáris transzformáció alfejezetben bevezetett euklideszi norma:

∥∇L(2,1.5)∥=42+122=160=410≈12.65.\|\nabla L(2,1.5)\|=\sqrt{4^2+12^2}=\sqrt{160}=4\sqrt{10}\approx 12.65.

A norma mértékegysége veszteség per paraméteregység; számszerűen azt mondja meg, hogy a leggyorsabb növekedési irányban egységnyi paraméterelmozdulásra körülbelül 12.6512.65 egység veszteségváltozás jut.

Miért a gradiens mutat a legmeredekebb emelkedő felé? Legyen 𝐮\mathbf u egy egységvektor, azaz ∥𝐮∥=1\|\mathbf u\|=1. Az 𝐮\mathbf u irányú iránymenti derivált azt méri, mennyire változik LL, ha 𝐰\mathbf w-ből 𝐮\mathbf u irányba mozdulunk. Két változóra a lineáris közelítésből:

D𝐮L(𝐰)=∇L(𝐰)⋅𝐮=∥∇L(𝐰)∥cosθ,D_{\mathbf u}L(\mathbf w)=\nabla L(\mathbf w)\cdot \mathbf u = \|\nabla L(\mathbf w)\|\cos\theta,

ahol θ\theta a gradiens és 𝐮\mathbf u közötti szög, a ⋅\cdot pedig a Mátrixszorzás és lineáris transzformáció alfejezetből ismert skalárszorzat. A cosθ\cos\theta akkor maximális, ha θ=0\theta=0, azaz 𝐮\mathbf u párhuzamos a gradienssel. Ekkor a derivált ∥∇L(𝐰)∥\|\nabla L(\mathbf w)\|. A leggyorsabb csökkenés ezért a −∇L-\nabla L irány, amelyet csökkenési iránynak (descent direction) nevezünk.

11.2.2 Szintvonalak és a gradienslépés

A szintvonal (contour) azon pontok halmaza, ahol a függvényérték állandó. A L(w1,w2)=cL(w_1,w_2)=c alakú görbét kell elképzelni. A példánkban

w12+4w22=c.w_1^2+4w_2^2=c.

Ha c=0c=0, akkor csak az origó tartozik ide. Ha c>0c>0, az egyenletet w12c+w22c/4=1\frac{w_1^2}{c}+\frac{w_2^2}{c/4}=1 alakra rendezve látszik: ellipsziseket kapunk, amelyek a w2w_2 tengely mentén laposabbak, mert a 4w224w_2^2 tag miatt ott gyorsabban nő a veszteség. A szintvonalak sűrűsége ezért a w2w_2 irányban nagyobb: ugyanakkora elmozdulás mellett több értékszintet lépünk át.

A gradiens a szintvonal érintőjére merőlegesen áll, és a nagyobb értékek felé mutat. Ez következik az iránymenti deriváltból is: ha 𝐯\mathbf v érintő irányú, akkor a szintvonalon haladva a veszteség nem változik, tehát ∇L⋅𝐯=0\nabla L\cdot\mathbf v=0. A skalárszorzat nulla volta éppen a két vektor merőlegességét jelenti.

A gradiens módszer (gradient descent) a csökkenési irányt használja iteratív lépésekre:

𝐰(k+1)=𝐰(k)−η∇L(𝐰(k)).\mathbf w^{(k+1)}=\mathbf w^{(k)}-\eta\, \nabla L(\mathbf w^{(k)}).

Jelölések: 𝐰(k)\mathbf w^{(k)} a paramétervektor a kk-adik iterációban; η>0\eta>0 a tanulási ráta (learning rate); ∇L(𝐰(k))\nabla L(\mathbf w^{(k)}) a gradiens a kk-adik pontban. A lépés mértékegysége konzisztens: az η\eta paraméteregység négyzete per veszteségegység, így az η∇L\eta\,\nabla L szorzat visszaadja a paraméter mértékegységét. A gyakorlatban η\eta-t dimenziótlan hangolóparaméterként kezeljük.

A lineáris közelítés megmutatja, miért csökken kis lépésnél a veszteség:

L(𝐰−η∇L)≈L(𝐰)−η∥∇L∥2.L(\mathbf w-\eta\nabla L)\approx L(\mathbf w)-\eta\|\nabla L\|^2.

Mivel a ∥∇L∥2\|\nabla L\|^2 tag nemnegatív, kis η\eta mellett a második tag csökkentést ad. A gradiens tehát lokális változási információ: megmondja az irányt, de a távolságot nem. Azt a tanulási ráta dönti el, és túl nagy η\eta esetén a lineáris közelítés érvényét veszti.

11.2.3 Teljes minimális munkapélda

A labor célja a kétdimenziós kvadratikus veszteség contour-rajza és három gradienslépés irányának jelölése. A kód a lab projekt alap numerikus csomagjait használja; a munkakönyvtár legyen a projekt gyökere. Nincs szükség hálózatra vagy külső API-ra. Futtatás platformtól függetlenül:

python s042_gradient_steps.py

A PowerShell és a macOS/Linux terminál is ezt a parancsot használja a projekt gyökeréből. A kód a következő.

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import minimize

def loss(w):
    w1, w2 = w
    return w1**2 + 4 * w2**2

def grad(w):
    w1, w2 = w
    return np.array([2 * w1, 8 * w2])

# Három gradienslépés a (2, 1.5) pontból.
w0 = np.array([2.0, 1.5])
eta = 0.1
points = [w0]
w = w0.copy()
for k in range(3):
    w = w - eta * grad(w)
    points.append(w)

print("Lépések és veszteségek (elméletileg várható):")
for k, p in enumerate(points):
    print(f"k={k}: w=({p[0]:.6f}, {p[1]:.6f}), L={loss(p):.6f}")

# Numerikus ellenőrzés centrális differenciával, s041 öröksége.
h = 1e-5
g_approx = np.array([
    (loss(w0 + np.array([h, 0])) - loss(w0 - np.array([h, 0]))) / (2 * h),
    (loss(w0 + np.array([0, h])) - loss(w0 - np.array([0, h]))) / (2 * h),
])
print("Analitikus gradiens:", grad(w0))
print("Numerikus gradiens:", g_approx)
print("Maximális eltérés:", np.max(np.abs(g_approx - grad(w0))))

# SciPy ellenőrzés: a gradiens és a loss ugyanazt a minimumot adja-e.
res = minimize(loss, x0=[2.0, 1.5], jac=grad, method="BFGS")
print("SciPy minimumhely (elméletileg várható):", res.x, "veszteség:", res.fun)

# Contour- és lépésrajz.
w1 = np.linspace(-2.5, 2.5, 101)
w2 = np.linspace(-2.0, 2.0, 101)
W1, W2 = np.meshgrid(w1, w2)
Z = W1**2 + 4 * W2**2

fig, ax = plt.subplots(figsize=(7, 5))
cs = ax.contour(W1, W2, Z, levels=[0.5, 1, 2, 5, 10, 15], colors="0.7")
ax.clabel(cs, fontsize=8)
ax.scatter([p[0] for p in points], [p[1] for p in points], color="black", s=18, zorder=3)
# A nyilak csak az irányt mutatják, nem a teljes lépéshosszt: -grad / norma.
for p in points[:3]:
    direction = -grad(p) / np.linalg.norm(grad(p))
    ax.arrow(p[0], p[1], 0.4 * direction[0], 0.4 * direction[1],
             width=0.02, color="black", length_includes_head=True, zorder=4)
ax.set_xlabel("w1")
ax.set_ylabel("w2")
ax.set_aspect("equal")
ax.grid(True, alpha=0.3)
ax.set_title("Kvadratikus veszteség és három gradienslépés")
fig.tight_layout()
fig.savefig("s042_gradient_steps.png", dpi=150)

A s042_gradient_steps.png fájl a labor átadandó eredménye. A nyilak a −∇L/∥∇L∥-\nabla L/\|\nabla L\| irányt mutatják, tehát a csökkenési irányt, nem a tanulási rátával skálázott tényleges lépéshosszat. Ez az ábrán a szintvonalra merőleges stációként jelenik meg.

A kód kimenete elméletileg várt, nem e szöveg írásakor futtatott mérés. A várt numerikus értékek:

11.2.4 Eredmény értelmezése

A veszteség 13→2.92→1.6528→1.04915213\to 2.92\to 1.6528\to 1.049152 csökken; tehát az η=0.1\eta=0.1 tanulási ráta ehhez a felülethez elég kicsi, és a lineáris közelítés mindhárom lépésben működik. A gradiens első lépése (4,12)(4,12): az y irányú komponens nagyobb, mert a 4w224w_2^2 tag miatt ott meredekebb a felület. A szintvonalak ennek megfelelően az y tengely mentén sűrűbbek.

Kézi kontroll az első lépésre:

𝐰(1)=(2,1.5)−0.1(4,12)=(2−0.4,1.5−1.2)=(1.6,0.3).\mathbf w^{(1)}=(2,1.5)-0.1(4,12)=(2-0.4, 1.5-1.2)=(1.6,0.3).

A veszteség 1.62+4⋅0.32=2.56+0.36=2.921.6^2+4\cdot 0.3^2=2.56+0.36=2.92. A második lépésben a gradiens (3.2,2.4)(3.2, 2.4), a harmadikban (2.56,0.48)(2.56, 0.48). A csökkenés egyre lassul, mert az origóhoz közeledve a gradiens hossza is csökken. Invariáns: az origóban a gradiens (0,0)(0,0); ott a gradienslépés nem változtat semmit. A numerikus ellenőrzés a h=10−5h=10^{-5} centrális differenciával a Meredekség és numerikus derivált alfejezetben tanult egyensúlyt használja: a hiba O(h2)O(h^2) csonkítási tagjából és a lebegőpontos kerekítésből adódik, ezért a várt eltérés 10−610^{-6} alatt marad.

A gradiens normáját a paraméterek választott skálája befolyásolja. A paraméterek átparaméterezése után a koordinátánkénti gradiens és az optimális lépésköz megváltozik; ezért a konvergenciát ne kizárólag a nyers gradiensnormából ítéljük meg.

11.2.5 Feladatok

  1. Értelmezés. Adott ugyanez az L(w1,w2)=w12+4w22L(w_1,w_2)=w_1^2+4w_2^2 függvény. a) Add meg a parciális deriváltakat és a gradienst a (1,−0.5)(1,-0.5) pontban. b) Igazold számítással, hogy a gradiens irányába mutató 𝐮=∇L/∥∇L∥\mathbf u=\nabla L/\|\nabla L\| egységvektorral vett D𝐮LD_{\mathbf u}L iránymenti derivált ∥∇L∥\|\nabla L\|-lel egyenlő. c) Számítsd ki a (0,1)(0,1) irányú iránymenti deriváltat is, és magyarázd meg, miért kisebb annál, mint a gradiens irányában.

  2. Megvalósítás. Írj egy rövid Python-függvényt, amely loss, grad, w0, eta és steps bemenetekkel elvégzi a gradienslépéseket, és visszaadja a lépések listáját, valamint True értéket, ha a veszteség minden lépésben csökkent, egyébként False-t. Ellenőrizd L(w1,w2)=w12+4w22L(w_1,w_2)=w_1^2+4w_2^2 függvényen 1010 lépéssel, w0=(2,1.5)w_0=(2,1.5), η=0.1\eta=0.1 bemenetekkel. A kódnak a bemeneti hibákra, például a nem 22 hosszú w0-ra, ValueError-t kell dobnia.

  3. Hibadiagnózis. Az alábbi kód állítólag minimalizál, de a veszteség nem csökken:

w = np.array([2.0, 1.5])
for k in range(3):
    g = np.array([8 * w[0], 2 * w[1]])
    w = w + 0.1 * g

Magyarázd meg a két hibát, javítsd ki, és ellenőrizd az első lépés utáni veszteséget.

  1. Megváltozott feltételű transzfer. Adott az L(w1,w2)=(w1−3)2+0.5(w2+1)2+10L(w_1,w_2)=(w_1-3)^2+0.5(w_2+1)^2+10 veszteség. a) Add meg a gradienst és a minimumot. b) Végezz egy gradienslépést η=0.1\eta=0.1-gyel a (0,0)(0,0) pontból, és számítsd ki a veszteséget előtte és utána. c) A gradiens normája a (0,0)(0,0) pontban 37≈6.08\sqrt{37}\approx 6.08, a minimum paramétertérbeli távolsága pedig 10≈3.16\sqrt{10}\approx 3.16. Fejtsd ki, miért nem adja meg a gradiens normája a minimumig hátralévő távolságot.

11.2.6 Megoldások és indoklás

1. feladat. a) A képletből ∂L/∂w1=2w1\partial L/\partial w_1=2w_1, ∂L/∂w2=8w2\partial L/\partial w_2=8w_2. A (1,−0.5)(1,-0.5) pontban ∇L=(2,−4)\nabla L=(2, -4). b) A norma 22+(−4)2=20≈4.47\sqrt{2^2+(-4)^2}=\sqrt{20}\approx 4.47; az egységvektor 𝐮=(1/5,−2/5)≈(0.447,−0.894)\mathbf u=(1/\sqrt{5}, -2/\sqrt{5})\approx(0.447,-0.894). A skalárszorzat ∇L⋅𝐮=2⋅0.447+(−4)(−0.894)=0.894+3.576=4.47\nabla L\cdot \mathbf u=2\cdot 0.447+(-4)(-0.894)=0.894+3.576=4.47, ami a várt normával egyezik 10−210^{-2} kerekítési tűrésen belül. c) A (0,1)(0,1) irányban D(0,1)L=∇L⋅(0,1)=−4D_{(0,1)}L=\nabla L\cdot(0,1)=-4. Ez kisebb, mint 4.474.47; mert a (0,1)(0,1) irány nem a leggyorsabb növekedés iránya.

2. feladat. A függvény:

def descent(loss, grad, w0, eta, steps):
    if len(w0) != 2:
        raise ValueError("A w0 vektor hossza 2 legyen.")
    decreasing = True
    points = [w0.copy()]
    previous = loss(w0)
    w = w0.copy()
    for _ in range(steps):
        w = w - eta * grad(w)
        current = loss(w)
        if current >= previous:
            decreasing = False
        points.append(w)
        previous = current
    return points, decreasing

A 1010 lépés után a veszteség 1313-ról körülbelül 0.002150.00215-ra csökken, és decreasing True, mert az η=0.1\eta=0.1 ennél a felületnél elég kicsi. A ValueError ellenőrzése w0=np.array([1.0]) bemenettel egyszerűen tesztelhető.

3. feladat. Az első hiba: a parciális deriváltak fel vannak cserélve. Az L=w12+4w22L=w_1^2+4w_2^2 gradienséhez [2w1,8w2][2w_1,8w_2] kell, nem [8w1,2w2][8w_1,2w_2]. A második hiba az előjel: a csökkenési irány −∇L-\nabla L, ezért 0.1g0.1\,g hozzáadása helyett ki kell vonni. A javított lépés:

w = w - 0.1 * np.array([2 * w[0], 8 * w[1]])

Az első lépés után w=(1.6,0.3)w=(1.6,0.3), L=2.92L=2.92, szemben a hibás lépés w=(3.6,1.8)w=(3.6,1.8), L=25.92L=25.92 értékével, ami növekedés.

4. feladat. a) A belső (w1−3)2(w_1-3)^2 deriváltja 2(w1−3)2(w_1-3), a 0.5(w2+1)20.5(w_2+1)^2 deriváltja (w2+1)(w_2+1); a 1010 konstans deriváltja 00. Ezért

∇L=(2(w1−3),w2+1),\nabla L=(2(w_1-3), w_2+1),

és a minimum ott van, ahol mindkét komponens nulla: w1=3w_1=3, w2=−1w_2=-1; a minimumérték 1010. b) A (0,0)(0,0) pontban a gradiens (−6,1)(-6,1), a lépés

𝐰(1)=(0,0)−0.1(−6,1)=(0.6,−0.1).\mathbf w^{(1)}=(0,0)-0.1(-6,1)=(0.6,-0.1).

A veszteség előtte L(0,0)=9+0.5+10=19.5L(0,0)=9+0.5+10=19.5, utána L(0.6,−0.1)=5.76+0.405+10=16.165L(0.6,-0.1)=5.76+0.405+10=16.165. c) A gradiens normája a lokális meredekség, nem a minimum távolsága. A veszteség felülete itt anizotrop: a w1w_1 irányban 11-es, a w2w_2 irányban 0.50.5-ös együttható skáláz. A gradiens e skálák kombinációjából adódik, míg a paramétertérbeli távolság (0−3)2+(0−(−1))2=10\sqrt{(0-3)^2+(0-(-1))^2}=\sqrt{10}. A két mennyiség más mértékegységű és más információt hordoz: a gradiens normája a pillanatnyi változási ráta, a távolság a megmaradt út.

11.2.7 Gyakori tévedés, visszautalás és önellenőrzés

Gyakori tévedés. „A gradiens a minimum helye.” Ez hibás. A gradiens pontbeli lokális változási információ, és általában nem a minimum koordinátája. Ellenpélda: az L=w12+4w22L=w_1^2+4w_2^2 felületen a (2,1.5)(2,1.5) pontban a gradiens (4,12)(4,12), de a minimum a (0,0)(0,0). Ha valaki a gradiens értékét minimumként olvasná, a (4,12)(4,12) pontba jutna, ahol a veszteség 42+4⋅122=5924^2+4\cdot 12^2=592, vagyis sokkal rosszabb, mint a kiinduló 1313. A gradienslépés csak a −∇L-\nabla L irányba mozdít; a tényleges célhoz több iteráción át, megfelelő tanulási rátával közelít.

Visszautalás korábbi fogalomra. A Meredekség és numerikus derivált egyváltozós deriváltja a parciális derivált speciális esete: ha p=1p=1, akkor ∇L\nabla L egyetlen szám. A centrális differencia itt koordinátánként ugyanazt a képletet használja, csak a többi koordinátát rögzítjük. A Mátrixszorzás és lineáris transzformáció alfejezetből a vektorok és a skalárszorzat adja a keretet: a gradiens pp dimenziós vektor, az iránymenti derivált pedig az ∇L⋅𝐮\nabla L\cdot\mathbf u skalárszorzat. A Join-kardinalitás és duplázódó célváltozó alfejezethez hasonlóan itt is fontos az egységek következetessége: a veszteség és a paraméterek mértékegységét nem szabad összekeverni.

Önellenőrzés.

  1. Mi a kapcsolat a parciális derivált és az egyváltozós derivált között?
  2. Mit mutat a gradiens iránya, és mit mutat a hossza?
  3. A szintvonal érintőjéhez képest milyen állású a gradiens?
  4. Miért nőhet a veszteség egy gradienslépés után, ha a gradiens nem nulla?

Válaszok: 1. A parciális derivált ugyanaz a határérték, de a többi bemenetet rögzítjük. 2. Az irány a legmeredekebb növekedés, a hossz az abban az irányban vett meredekség nagysága. 3. Merőleges a szintvonal érintőjére. 4. Túl nagy tanulási ráta esetén a lineáris közelítés érvényét veszti, és a módszer túllendül a csökkenő tartományon.

11.2.8 Rövid összefoglaló

A parciális derivált egy koordináta menti változási ráta, a gradiens pedig az összes parciális deriváltból álló, a paramétertérrel azonos dimenziójú vektor. A gradiens iránya a legmeredekebb emelkedőt, hossza a legnagyobb meredekséget mutatja; a csökkenési irány ezért −∇L-\nabla L. A szintvonalakon a gradiens merőleges az érintőre. A gradienslépés w(k+1)=w(k)−η∇Lw^{(k+1)}=w^{(k)}-\eta\nabla L; a tanulási ráta a lépés hosszát szabja, túl nagy értéknél a veszteség nőhet. A kvadratikus felület laborja három ellenőrzött lépéssel és contour-rajzzal igazolta ezt. A következő Láncszabály és számítási gráf a láncszabályon át a számítási gráfot és a többrétegű függvények gradiensét építi fel.