Ez az egység a valós függvények differenciálszámításának azt a minimális részét építi fel, amelyre a neurális hálózatok tanításának matematikája épül. A 3.1. Vektor, norma és skalárszorzat alfejezetben bevezetett távolságfogalmat használjuk: a differenciahányados nevezője két pont távolsága, a számláló pedig a hozzájuk tartozó függvényértékek különbsége. A 3.4. Sajátérték, SVD és spektrális határ alfejezetből most csak annyit használunk fel, hogy a lineáris leképezés a későbbi többdimenziós derivált központi gondolata; ebben az alfejezetben minden objektum skalár–skalár függvény.
Induló becslés: egy képfeldolgozó eljárás a bemenetre értéket ad, a bemenetre pedig értéket. Körülbelül mennyit változik a kimenet, ha a bemenetet -ről -ra állítjuk? A válaszhoz a változás és a bemenetváltozás hányadosát kell értelmeznünk.
Legyen valós függvény, és legyen a tartomány belső pontja, azaz valamely esetén az intervallum is -ben van. Minden olyan lépésközre, amelyre , definiáljuk a differenciahányadost (difference quotient):
A kifejezés az és pontokon átmenő szelő meredeksége. A lehet negatív is; ekkor a szelő a bal oldali pont felé mutat.
A derivált (derivative) az pontban a differenciahányados határértéke, ha ez a véges határérték létezik:
Pontosabban: , ha minden számhoz van olyan , hogy minden , esetén . A feltétel fontos: a differenciahányados -ban nincs értelmezve, a határérték mégis közelíthető mindkét oldalról. Ha a határérték nem létezik vagy nem véges, akkor az pontban nem differenciálható.
Az induló kérdésben a két adat közötti differenciahányados
Ha feltesszük, hogy a kimenet közelítőleg ezzel a lokális sebességgel változik, akkor a bemenethez tartozó becsült kimenet
Ez a gondolatmenet pontosan a derivált elsőrendű közelítését használja; a hibáját a későbbi Taylor-részben vizsgáljuk.
Az folytonos az pontban, ha . Szavakkal: elég kis bemenetváltozásra a kimenet is tetszőlegesen kis változást mutat. A folytonosság gyengébb feltétel, mint a differenciálhatóság.
Tétel (differenciálhatóságból következik a folytonosság). Ha differenciálható az pontban, akkor folytonos is -ban.
Bizonyítás. A különbséget szorzattá alakítjuk. Minden esetén, amelyre a hányados értelmes,
Ha , akkor az első tényező a definíció szerint -hoz tart, a második pedig -hoz. A szorzat határértéke a két véges határérték szorzata, tehát
Ebből , vagyis folytonos -ban. A eset triviálisan teljesíti az egyenlőséget. Az állítást beláttuk.
A megfordítás nem igaz. Az függvény folytonos -ban, de nem differenciálható ott. Valóban, esetén
míg esetén
A jobb és bal oldali hányados különböző, így a kétoldali határérték nem létezik.
A kötelező levezetést a , függvényre végezzük el, közvetlenül a definícióból. Rögzített és esetén
Az utolsó lépésben miatt egyszerűsíthetünk. A kifejezés esetén a értékhez tart, mert a konstans -hoz egy nullához tartó tagot adunk. Ezért
Mivel az tetszőleges volt, a deriváltfüggvény minden pontban. A levezetés feltétele pusztán ; a négyzetfüggvény mindenütt differenciálható.
Ellenőrzésként az pontban a valódi derivált . A differenciahányados:
A hányados ; a képlet éppen ezt adja. A hiba a fenti levezetésből pontosan .
A derivált definíciójának átrendezésével kapjuk a lokális lineáris közelítést.
Lemma (elsőrendű Taylor-maradék). Ha differenciálható -ban, akkor megadható olyan függvény, amelyre , ha , és minden elég kis esetén
Bizonyítás. -ra legyen
A derivált definíciója szerint . Ezt átrendezve:
majd -val szorozva és -t mindkét oldalhoz adva a kívánt alakot kapjuk. A maradéktag tehát rendű: nullához tart akkor is, ha elosztjuk -val.
Az elsőrendű Taylor-közelítés ennek a maradéktag elhagyásával kapott lineáris függvénye:
A négyzetfüggvénynél esetén . Például -re , míg a pontos érték . A hiba , és ez a négyzetfüggvényre minden -ra pontosan így alakul, mert
Általános sima függvényre a maradék nagyságrendű, ha a második derivált korlátos; ennek formális, Lagrange-féle alakját itt nem bizonyítjuk, mert a következő numerikus hibaelemzéshez elegendő a fenti konkrét eset.
A számítógépes gyakorlatban a deriváltat gyakran véges differenciákkal közelítjük. Az előre mutató (forward) differencia a már ismert . A középső (central) differencia:
A függvényre a középső differencia valós aritmetikában minden -ra pontosan , mert
A forward differencia hibája ezzel szemben , amint fent láttuk. Ez az algebrai, más néven csonkolási hiba.
A lebegőpontos számítás azonban egy második hibaforrást is bevezet. Jelölje a float64 gépi pontosságot. Ha nagyságrendű, akkor és kiértékelése egyenként körülbelül abszolút hibát hordozhat. A kivonás után a két hiba legfeljebb összeadódik, így a számláló abszolút hibája nagyjából . Ezt a nevezővel osztva a kerekítési eredetű deriválthiba
Ez csökkenésével nő. A forward differencia teljes hibája a esetben közelítőleg
Két ellentétes tag összege: a csonkolási hiba -val csökken, a kerekítési hiba -val nő. A minimum nagyságrendileg ott van, ahol a két tag egyenlő:
esetén ez körülbelül . Általános sima függvényre a középső differencia csonkolási hibája rendű, ezért ott az optimális lépésköz nagyságrendje . Ezek heurisztikus nagyságrendbecslések, nem univerzális képletek: a konstans függ az nagyságától, a deriváltak méretétől és a hardveres kerekítési módtól.
A szélsőséges eset jól mutatja a korlátot. Ha és , akkor float64-ben a összeg a legközelebbi lebegőpontos számára kerekedik, mert a körüli két ábrázolható szám távolsága körülbelül . Ekkor , így mind a forward, mind a középső differencia -t ad a valódi helyett. A tetszőlegesen kis lépésköz tehát nem garantál egyre pontosabb deriváltat.
Tekintsük a függvényt az pontban. A valódi derivált . Kézi számítással:
Valós aritmetikában a középső differencia a négyzetfüggvényre mindig -ot ad. A forward differencia hibája éppen . A float64-ben a nagyon kis -nál a fenti kerekítési határ érvényesül: esetén a függvényértékek numerikusan egybeesnek, és a deriváltbecslés lesz.
A következő önálló, CPU-s Python munkamenet a
lab/n013_numerical_derivative.py fájlba menthető. A feladat
determinisztikus, ezért seedre és GPU-ra nincs szükség. A Python
float típusa alapértelmezés szerint float64, ezt a
kommentben rögzítjük. Futtatás:
python n013_numerical_derivative.py.
"""n013 labor: forward es central difference hibagorbéje q(x)=x^2-re.
Futtatas: python n013_numerical_derivative.py
Kornyezet: CPU, Python 3, float64; nincs veletlen es nincs GPU.
"""
import numpy as np
def q(x):
"""A vizsgalt negyzetfuggveny."""
return x * x
def forward_diff(f, x, h):
"""Elore mutato differenciahanyados, h > 0."""
return (f(x + h) - f(x)) / h
def central_diff(f, x, h):
"""Kozepso differencia, h > 0."""
return (f(x + h) - f(x - h)) / (2.0 * h)
def main():
x0 = 3.0
exact = 2.0 * x0
steps = [1.0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5,
1e-6, 1e-8, 1e-10, 1e-12, 1e-16]
print(f"{'h':>9} {'forward':>14} {'central':>14} "
f"{'err_forward':>14} {'err_central':>14}")
for h in steps:
fwd = forward_diff(q, x0, h)
cen = central_diff(q, x0, h)
print(f"{h:9.1e} {fwd:14.10e} {cen:14.10e} "
f"{abs(fwd-exact):14.6e} {abs(cen-exact):14.6e}")
if __name__ == "__main__":
main()A kód által kiírt táblázat valós aritmetikai (csonkolási) részét az alábbi, képletből számított szemléltető táblázat mutatja. A -os sor a float64 kerekítés következményét jelöli; ez nem elvégzett futtatás, hanem a fenti kerekítési elemzésből származó várt jelenség.
| forward (valós) | középső (valós) | forward hiba | középső hiba | |
|---|---|---|---|---|
| (float64) | (float64) |
A hibagörbe szerkezete a forward differenciára:
Az értelmezés: valós aritmetikában a forward hiba egyenesen arányos -val, ezért a pontok a grafikon bal alsó tartománya felé haladnak. A float64 tartományban egy ponton túl a kerekítési hiba dominál, és a becslés összeomlik: a lépésnél a kimenet , a hiba pedig a teljes derivált értéke.
F1 (fogalmi, nehézség 1). Definiálja a differenciahányadost és a deriváltat. Magyarázza el, miért következik a differenciálhatóságból a folytonosság, és adjon olyan függvényt, amely folytonos, de nem differenciálható. A példán számítsa ki a jobb és bal oldali differenciahányadosokat.
F2 (levezetési, nehézség 2). Vezesse le a függvény deriváltját a definícióból. Adja meg a deriváltat az pontban, majd az elsőrendű Taylor-közelítést esetén. Számítsa ki a pontos függvényértéket, a közelítést és a különbséget.
F3 (implementációs, nehézség 1). Írjon Python-függvényt, amely az függvényhez, az ponthoz és a lépésközhöz visszaadja a forward és a középső differenciát. Tesztelje a , , bemenettel. Ellenőrizze, hogy a forward érték -hez, a középső érték -hoz van abszolút tűrésen belül.
F4 (hibakeresési, nehézség 2). Egy hallgató a deriváltat a lehető legkisebb -val akarja pontosabbá tenni, ezért -at ír a kódba. A , esetben a függvény deriváltat ad vissza. Lokalizálja a hiba okát, mondja meg a következményt, javítsa a lépésközt, és ellenőrizze esetén a javított eredményt.
F5 (kísérlettervezési, nehézség 3). Tervezzen kísérletet egy általánosabb, de zárt alakban deriválható függvény, például , esetén annak meghatározására, hogy a középső differencia mely értéknél adja a legkisebb abszolút hibát a referenciaértékhez képest. Adja meg a -rácsot, a metrikát, a döntési szabályt, az ismétlés szükségességét és az érvényességi korlátokat. Nem egyetlen előre megadott „helyes” -t várunk, hanem korrekt protokollt.
F1. A definíciókat a fenti szakasz tartalmazza. A differenciálhatóságból a folytonosság a szorzat határértékén keresztül következik; a bizonyítás a tételnél olvasható. Ellenpélda: , folytonos -ban, mert . A jobb oldali differenciahányados -ra , a bal oldali -ra . A két oldali határérték különbözik, ezért a derivált nem létezik.
F2. Rögzített -ra és -ra:
esetén a és tagok nullához tartanak, tehát . Az pontban . Az elsőrendű Taylor-közelítés:
-re . A pontos érték , a hiba . A hiba összetevői az elhagyott tagok.
F3. Az előírt függvény:
import numpy as np
def q(x):
return x * x
def numdiff(f, x, h):
forward = (f(x + h) - f(x)) / h
central = (f(x + h) - f(x - h)) / (2.0 * h)
return forward, central
fwd, cen = numdiff(q, 3.0, 1e-2)
print(fwd, cen) # varhatoan 6.01 es 6.0 kornyeken
assert abs(fwd - 6.01) < 1e-12
assert abs(cen - 6.0) < 1e-12A h pozitív, az x float64 skalár. A középső
differencia a
-ra
valós aritmetikában pontosan
,
a
tűrés a kerekítési zajt is elnyeli; a forward érték analitikusan
.
F4. A hiba oka: esetén float64-ben a legközelebbi ábrázolható számra, gyakorlatilag -ra kerekedik, mert a körüli gépi felbontás nagyjából . Ezért , és a hányados . A következmény: a derivált becslése a valódi helyett , vagyis a hiba -os. Javítás: válasszunk mérsékelt lépésközt, például -öt. Ekkor kiszámítható, és a forward differencia körülbelül ; a középső differencia -hoz közeli. A visszaellenőrzés: a fenti F3 kódban -re a forward hiba körüli, a középső hiba alatti tűréssel elfogadható.
F5. Egy lehetséges protokoll. Cél: hatásának feltérképezése a középső differencia hibájára. Megfigyelési egység: egyetlen skalár kiértékelés; nincs mintavételi zaj, ezért ismétlés nem szükséges, legfeljebb több ponton való robusztusságvizsgálat. Rács: geometriai sorozat, például , esetleg az környékén sűrítve. Metrika: , a referencia a zárt alakú derivált. Döntés: azt a -t jelentjük, amely a rácson a legkisebb hibát adja, és mellette megadjuk a hibát a szomszédos értékeken is, ne csak egyetlen minimumot. Érvényességi korlát: az optimum függ az skálájától, a hardveres kerekítéstől és a float64-től; más függvényre vagy más pontra nem vihető át automatikusan. A mérést determinisztikus, seed nélküli CPU-kóddal lehet elvégezni, és a nyers hibasorozatot kell rögzíteni.
A leggyakoribb tévedés: „minél kisebb a numerikus lépésköz, annál pontosabb a derivált”. A fenti , példa cáfolja: esetén float64-ben , ezért a számláló nulla, és a becsült derivált a valódi helyett. A hiba oka a kivonási jegyvesztés (catastrophic cancellation), amit a nagyságrendű kerekítési tag ír le. A helyes szemlélet: a lépésközt a csonkolási és kerekítési hiba együttes optimuma körül kell választani, és az optimum függ a feladattól.
Ellenőrizze, hogy ki tudja mondani a derivált – definícióját, le tudja vezetni deriváltját, és el tudja magyarázni, miért folytonos minden differenciálható függvény. Korábbi fogalom visszahívása: a 3.1. Vektor, norma és skalárszorzat alfejezetben a két pont távolságát a különbségvektor euklideszi normájaként definiáltuk; a differenciahányados nevezője éppen ilyen távolság a valós egyenesen, a számláló pedig a függvényértékek különbsége.
A differenciahányados két függvényérték különbségét osztja a bemenetek különbségével, és a szelő meredekségét adja. A derivált ennek határértéke, ha a lépésköz nullához tart; a négyzetfüggvényre a definícióból adódik. A differenciálhatóságból következik a folytonosság, fordítva nem, amit az abszolútérték-függvény mutat. Az elsőrendű Taylor-közelítés a lokális lineáris helyettesítést adja, maradékkal. Numerikusan a túl kicsi lépésköz kivonási jegyvesztést okoz: a csonkolási hiba csökken, a kerekítési hiba nő, ezért van optimális .
A 4.2. Parciális derivált és gradiens a többváltozós függvények parciális deriváltját és gradiensét vezeti be. A 4.3. Jacobi-mátrix, láncszabály és VJP pedig a Jacobi-mátrixszal és a vektor–Jacobi-szorzattal a backpropagation pontos algebrai nyelvét építi fel; ekkor a skalár lépésköz helyett már az iránymenti deriváltakat vizsgáljuk.