A 9.2. MLP és nemlinearitás alfejezetben beláttuk, hogy a ReLU MLP folytonos, szakaszonként affin függvény, és hogy nemlinearitás nélkül több affin réteg egyetlen affin réteggé vonható össze. Most a kifejezőerőt formalizáljuk: mit tud egyetlen rejtett rétegű háló egyenletesen közelíteni? Az induló kérdés: legyen a intervallumon. Körülbelül hány ReLU neuron szükséges ahhoz, hogy a háló és között a maximális eltérés alatt maradjon? A fejezet először pontos definíciót ad, majd egy olyan approximációs tételt bizonyítunk, amelyre a fenti kérdésre konkrét korlátot kapunk.
Legyen kompakt tartomány (compact domain), azaz korlátos és zárt halmaz. Az 1D esetben zárt intervallum. A tér a -n folytonos valós függvények halmazát jelöli. A két függvény eltérését a szupremumnorma (supremum norm) méri:
Az 1D egy rejtett rétegű MLP alakja a jelen egységben
ahol a bemenet , a rejtett szélesség (width) , tehát , , , . Batchelt jelölésben , és a bias a megfelelő dimenzió mentén sugárzódik.
Definíció (univerzális approximációs tulajdonság). A függvényosztály rendelkezik az univerzális approximációs tulajdonsággal a tartományon, ha minden és minden esetén létezik , amelyre .
Az aktivációs feltétel (activation condition) szerepe a ReLU tulajdonságában látszik: a függvény a pontban visz be egyetlen meredekségugrást, a konstans vagy az affin aktiváció viszont nem hoz létre ilyen töréspontot. Ezért a ReLU alkalmas darabonként affin függvények összerakására.
Először egy teljesen bizonyított, saját lemmát mondunk ki. A szakaszonként affin függvény meredekségét a belső töréspontok kivételével mindenütt az intervallumon belüli derivált adja; a töréspontokban a jobb és bal oldali meredekség különbözik.
Lemma 1 (szakaszonként affin függvény ReLU-előállítása). Legyen folytonos és szakaszonként affin, belső töréspontokkal . Legyen a kezdő meredekség, és legyen
a meredekség ugrása a pontban. Ekkor
Bizonyítás. Legyen a jobb oldal. A folytonos, ezért folytonos, továbbá minden -től különböző pontban mindkét oldal affin, azaz is szakaszonként affin. A pontoktól balra , jobbra pedig a meredeksége , tehát meredeksége a intervallumon
ami éppen meredeksége ugyanazon az intervallumon, hiszen a ugrások kumulálódnak. Az pontban , és szakaszonként affin folytonos függvényt a kezdőérték és a meredekségfüggvény egyértelműen meghatároz, így . ∎
A következő lépés minden folytonos függvényt szakaszonként affin interpolánssal közelít.
Lemma 2 (lineáris interpoláns approximációja). Legyen . Minden -hoz létezik olyan folytonos, szakaszonként affin függvény, hogy .
Bizonyítás. A kompakt intervallumon egyenletesen folytonos, tehát létezik , hogy esetén . Válasszunk egy rácsot, ahol a lépésköz kisebb, mint . Legyen az lineáris interpolánsa a rácspontokban: minden intervallumon
Itt konvex kombinációja két -értéknek, és , ezért
tehát . ∎
A Lemma 2 csak létezést állít: a lépésközt az egyenletes folytonosság -ja adja, amelyről a bizonyítás nem mond számot. Kétszer folytonosan differenciálható célfüggvényre explicit, kvantitatív korlát is levezethető.
Lemma 3 (a lineáris interpoláns hibakorlátja függvényre). Legyen , , és legyen az lineáris interpolánsa egy lépésközű egyenletes rácson. Ekkor
Bizonyítás. Rögzítsünk egy intervallumot és benne egy pontot, ahol (a végpontokban a hiba nulla). Legyen , és tekintsük a segédfüggvényt. Ez , és három pontban nulla: -ben, -ben és -ben. A Rolle-tétel kétszeri alkalmazásával van olyan , ahol . Mivel az intervallum belsejében, , tehát
A szorzat az intervallum közepén maximális, értéke , ezért . ∎
A szükséges lépésközhöz a felső korlátot kell a célhiba alá szorítani: ha , akkor , vagyis elegendő
A lemma valós aritmetikára szól; float32 megvalósításnál
a súlyok és a kiértékelés kerekítése ehhez egy kis, külön kezelendő
többletet ad (nagyságrendileg néhány
relatív hiba a súlyok és az aktivációk méretéhez mérve), ezért a mért
hibát a korláttal tűréssel vetjük össze.
A két lemma kompozíciója adja a saját approximációs tételt.
Tétel (1D univerzális approximáció ReLU-hálózattal). Legyen kompakt intervallum. Ekkor minden és minden esetén létezik egyetlen rejtett rétegű ReLU MLP, amelyre . A Lemma 2 konstrukciójában a rejtett szélesség legfeljebb , ahol az egyenletes folytonossági modulusa az -hoz.
Bizonyítás. A Lemma 2 ad egy szakaszonként affin függvényt, amelyre . A Lemma 1 szerint pontosan előállítható a fenti egy rejtett rétegű alakban: a lineáris taghoz két ReLU egység (), a belső töréspontokhoz további egység tartozik, a kimeneti réteg pedig a és együtthatókat kombinálja. A szélességkorlát a rács lépésközéből következik. ∎
Átvett szakirodalmi eredmény. Az általános, többdimenziós univerzális approximációs eredmények közül a klasszikus Cybenko-tételt [P24] egyetlen rejtett rétegű hálózatra vonatkozóan tartjuk nyilván. A Cybenko-tétel részletes feltételrendszerét (aktiváció-osztály, topológia, dimenzió) és bizonyítását itt nem tárgyaljuk, ezért annak pontos, általános formuláját sem használjuk fel a későbbi számításokhoz. A fenti 1D ReLU-tétel a könyv saját, teljes bizonyítású eredménye; a Cybenko-tétel részletes megfogalmazása nem része az itt bizonyított állításnak.
Legyen , és definiáljuk
A függvény folytonos, belső töréspontjai és . A kezdő meredekség ; a meredekség ugrása -nál , -nél . A Lemma 1 képlete:
Ellenőrzés: esetén ; esetén ; esetén , és a definícióból .
A hálózat reprezentációja négy rejtett egységgel: a lineáris taghoz és , a töréspontokhoz és . A súlyok:
A labor célja az 1D tétel közvetlen használata, és annak bemutatása,
hogy azonos paraméterszámú hálók között a konkrét súlykonfiguráció, nem
pedig a paraméterszám önmagában hozza a jó approximációt. A célfüggvény
a
-en.
A munkakönyvtár lab/, a kód
n035_expressivity.py.
import numpy as np
def relu(x):
return np.maximum(x, 0.0)
def mlp_1hidden(x, W1, b1, W2, b2):
h = relu(x @ W1.T + b1) # (N,m)
return h @ W2.T + b2 # (N,1)
def build_interpolating_mlp(f, a=0.0, b=1.0, n_intervals=10, width=12):
x_nodes = np.linspace(a, b, n_intervals + 1, dtype=np.float32)
interiors = x_nodes[1:-1]
y_nodes = f(x_nodes).astype(np.float32)
h = (b - a) / n_intervals
slopes = np.diff(y_nodes) / h # n_intervals meredekség
s0 = slopes[0]
deltas = np.diff(slopes) # ugrás a belső pontokban
m = width
W1 = np.zeros((m, 1), dtype=np.float32)
b1 = np.zeros((m,), dtype=np.float32)
W1[0, 0] = 1.0 # ReLU(x)
W1[1, 0] = -1.0 # ReLU(-x)
W1[2:2 + len(interiors), 0] = 1.0
b1[2:2 + len(interiors)] = -interiors
W2 = np.zeros((1, m), dtype=np.float32)
W2[0, 0] = s0
W2[0, 1] = -s0
W2[0, 2:2 + len(deltas)] = deltas
b2 = np.array([f(a) - s0 * a], dtype=np.float32)
return W1, b1, W2, b2
def mlp_2hidden(x, W1, b1, W2, b2, W3, b3):
h1 = relu(x @ W1.T + b1)
h2 = relu(h1 @ W2.T + b2)
return h2 @ W3.T + b3
def build_random_two_hidden(seed=20261020):
rng = np.random.default_rng(seed)
W1 = rng.standard_normal((3, 1), dtype=np.float32) * 0.5
b1 = rng.standard_normal((3,), dtype=np.float32) * 0.5
W2 = rng.standard_normal((6, 3), dtype=np.float32) * 0.5
b2 = rng.standard_normal((6,), dtype=np.float32) * 0.5
W3 = rng.standard_normal((1, 6), dtype=np.float32) * 0.5
b3 = rng.standard_normal((1,), dtype=np.float32) * 0.5
return W1, b1, W2, b2, W3, b3
def main():
target = lambda x: np.sin(2 * np.pi * x)
a, b = 0.0, 1.0
n_intervals = 10
W1, b1, W2, b2 = build_interpolating_mlp(target, a, b, n_intervals, width=12)
# A háló paraméterszáma: 12 + 12 + 12 + 1 = 37
x_test = np.linspace(a, b, 1001, dtype=np.float32).reshape(-1, 1)
y_true = target(x_test).astype(np.float32)
y_A = mlp_1hidden(x_test, W1, b1, W2, b2)
err_A = np.max(np.abs(y_A - y_true))
# Elméleti garantált szupremumhiba: max|f''| = 4*pi^2, h = 0.1
h = (b - a) / n_intervals
bound = (h**2 / 8.0) * (4 * np.pi**2)
# B kontraszt: 3+6 rejtett, paraméterszám 3+3+18+6+6+1 = 37
W1b, b1b, W2b, b2b, W3b, b3b = build_random_two_hidden(seed=20261020)
y_B = mlp_2hidden(x_test, W1b, b1b, W2b, b2b, W3b, b3b)
err_B = np.max(np.abs(y_B - y_true))
print(f"A konstrukciós hiba (1001 pontos rácson): {err_A:.6f}")
print(f"Elméleti garantált szupremumhiba: {bound:.6f}")
print(f"B véletlen hiba (1001 pontos rácson): {err_B:.6f}")
assert W1.shape == (12, 1) and W2.shape == (1, 12)
if __name__ == "__main__":
main()Futtatás: python lab/n035_expressivity.py. A kód nem
igényel PyTorch-ot, csak NumPy-t; dtype float32, device CPU. A
lab-profilban (NumPy 2.3.5) mért kimenet: az
konstrukciós hiba az 1001 pontos rácson
,
az elméleti korlát
,
a
véletlen háló hibája
.
Az
hibája tehát a korlát alatt, de ahhoz közel marad, mert a
második deriváltja a szélsőhelyeken eléri
-t;
a
hiba nagy, mert a véletlen súlyok nem a célt reprezentálják.
Az állítástípusok elkülönítése a laborban:
float32 kerekítés ehhez csak elhanyagolható többletet
ad.err_A és err_B a tényleges futásból származik;
ez a rács a teljes intervallumnak csak diszkrét részhalmaza, ezért a
szupremumhibára alsó közelítés.F1 (fogalmi, nehézség 1). Magyarázza el a különbséget a reprezentációs (létezési) és az optimalizálási (megtalálási) állítás között. Adjon egy konkrét példát, amelyben a létezés igaz, de a megtalálás nem garantált. Elvárt eredmény: saját megfogalmazás, a példában az architektúra, a létező súlyok és a megtalálást gátló körülmény megnevezése.
F2 (levezetési, nehézség 2). Legyen és Adja meg a belső töréspontokat, a kezdő meredekséget, a meredekségugrásokat, a Lemma 1 ReLU-képletet és a hálózat súlyait. Ellenőrizze a pontokban.
F3 (implementációs, nehézség 1). Írjon NumPy
függvényt, amely tetszőleges t törésponttömbből,
deltas ugrástömbből, s0 kezdő meredekségből és
f_a = f(a) kezdőértékből felépíti a Lemma 1 szerinti egy
rejtett rétegű súlyokat. Ellenőrizze a F2
függvényén 17 egyenletes ponton; a max abszolút hiba
alatt legyen. Átadandó: futtatható kód, input, output, tolerancia.
F4 (hibakeresési, nehézség 2). Adott a következő hibás érvelés: „A Cybenko-tétel garantálja, hogy a hálózatunk 10 epoch SGD után megtalálja a jó súlyokat.” Lokalizálja a hibát, nevezze meg a következményt, és fogalmazza át az állítást úgy, hogy az az állítástípusoknak megfeleljen. Ellenőrzésként adja meg, mit állít a tétel, és mit nem.
F5 (kísérleti transzfer, nehézség 3). Tervezzen kísérletet annak vizsgálatára, hogy azonos paraméterszám mellett a széles-sekély vagy a keskeny-mély MLP éri el a jobb max abszolút hibát a függvényen. Adja meg a protokollt: cél, hipotézis, baseline, változó tényező, metrika, seed-kezelés, erőforrás és a következtetés érvényességi határa.
F1. A reprezentációs tétel egy osztály kapacitásáról szól: minden -hoz létezik legalább egy , amely közelségben van -hez. Az optimalizálási állítás ezzel szemben azt mondaná, hogy egy adott keresőeljárás egy adott inicializációból kiindulva megtalálja ezt a -t. Konkrét példa: a labor hálója a tétel konstrukciójából létezik, de ugyanaz az architektúra véletlen súlyokkal () nem ad jó hibát; a jó súlyok léteznek, ám a véletlen inicializálásból induló gradienskeresés sikerére a tétel semmit sem mond.
F2. A belső töréspontok , ; a kezdő meredekség ; a meredekségugrás , . A Lemma 1 képlet:
A hálózat súlyai négy rejtett egységgel: , , , . A lineáris tag együtthatója nulla, ezért az első két egység nulla kimeneti súllyal szerepel, de formálisan megtartjuk őket. Ellenőrzés: : ; : ; : ; : ; : .
F3. A kód közvetlenül a Lemma 1 konstrukciót valósítja meg. A lineáris taghoz két identitás-egységet használunk, így az azonosság általánosan érvényesül a teljes -en, nem csak a nemnegatív félegyenesen.
import numpy as np
def relu(x):
return np.maximum(x, 0.0)
def build_lemma1(t, deltas, s0, f_a, a=0.0, with_identity=True):
t = np.asarray(t, dtype=np.float32)
deltas = np.asarray(deltas, dtype=np.float32)
k = len(t)
m = k + 2 if with_identity else k
W1 = np.zeros((m, 1), dtype=np.float32)
b1 = np.zeros((m,), dtype=np.float32)
if with_identity:
W1[0, 0] = 1.0
W1[1, 0] = -1.0
offset = 2
else:
offset = 0
W1[offset:offset + k, 0] = 1.0
b1[offset:offset + k] = -t
W2 = np.zeros((1, m), dtype=np.float32)
if with_identity:
W2[0, 0] = s0
W2[0, 1] = -s0
W2[0, offset:offset + k] = deltas
b2 = np.array([f_a - s0 * a], dtype=np.float32)
return W1, b1, W2, b2
def forward(x, W1, b1, W2, b2):
h = relu(x @ W1.T + b1)
return h @ W2.T + b2
# F2 g függvénye, 17 ponton ellenőrizve
t = np.array([0.2, 0.6], dtype=np.float32)
deltas = np.array([1.5, -1.5], dtype=np.float32)
s0, f_a, a = 0.0, 0.0, 0.0
W1, b1, W2, b2 = build_lemma1(t, deltas, s0, f_a, a)
x = np.linspace(0, 1, 17, dtype=np.float32).reshape(-1, 1)
g_true = np.where(x < 0.2, 0.0,
np.where(x < 0.6, 1.5 * (x - 0.2), 0.6))
y = forward(x, W1, b1, W2, b2)
print("max abs hiba:", float(np.max(np.abs(y - g_true))))
assert W1.shape == (4, 1) and W2.shape == (1, 4)
assert float(np.max(np.abs(y - g_true))) < 1e-5A np.where pontonkénti elágazást ad, ami a 17 pontos
ellenőrzéshez elegendő; a feltétel a x < 0.2 alakú tömb,
ezért a np.where vektorizáltan működik. A tolerance
float32 kerekítést is fedez.
F4. A hiba oka: az állítás összemossa a reprezentációs tételt az optimalizálás konvergenciájával. A Cybenko-típusú tétel létezést mond egy architektúra osztályra, nem pedig az SGD 10 epochja utáni konvergenciát. A következmény téves modellválasztási ígéret: a gyakorló dönthet úgy, hogy 10 epoch elég, pedig a tétel nem ad epoch-számot és nem garantál globális optimumot. A javított állítás: „A tétel garantálja, hogy létezik a hálózatosztályban olyan súly, amely a kompakt tartományon pontossággal közelíti a folytonos függvényt; az, hogy egy adott tanítási eljárás ezt megtalálja-e, külön optimalizálási kérdés.” Ellenőrzés: a tételben nincs „epoch”, „SGD”, „inicializáció”; a hipotézisosztályra és a szupremumnormára vonatkozik.
F5. Egy lehetséges terv. Cél: azonos paraméterszám mellett szélesség vagy mélység hatásának mérése a szintetikus függvényen. Hipotézis: az 1D tétel szerint a széles-sekély háló is elég, ezért a sekély háló ismert konstrukciója ad baseline-t. Változó: A) szélesség 12 egy rejtett réteg, 37 paraméter; B) keskeny-mély, 3+6 rejtett, 37 paraméter. Baseline: a Lemma 1–2 konstrukció A-n, mint levezetett garantált hiba. Metrika: max abszolút hiba 1001 pontos rácson, valamint a szupremumhiba becslése 10000 pontos rácson. A B-t véletlen súlyokkal, 10 seed-del mérjük, és a seedek közötti átlagot, minimumot közöljük. Erőforrás: CPU, NumPy, float32; futásidő másodpercek. Érvényességi határ: az eredmény egyetlen függvényre, egyetlen dimenzióra érvényes; nem általánosítható többdimenziós vagy természetes képadatokra, és a B véletlen súlyos mérése nem training-összehasonlítás.
Az approximáció létezése nem garantálja az SGD sikerét vagy a jó mintakomplexitást. Ellenpélda: legyen a -en. A tétel szerint minden rögzített -re és -ra létezik megfelelő háló, de a második derivált maximuma ; a Lemma 3 hibakorlátja alá szorítva, , elegendő feltételt ad: . A szükséges töréspontszám tehát -nel arányosan nő, a width rögzített értéke mellett nem érhető el tetszőlegesen jó approximáció. A tétel létezést, nem hatékony reprezentációt és nem megtalálást állít.
Ellenőrizze, hogy a Lemma 1 képletében a meredekségugrás a jobb meredekség mínusz bal meredekség, nem fordítva. A töréspontok száma a rejtett szélességben a lineáris tag két egységével együtt jelenik meg. A kompakt feltétel lényeges: nem korlátos tartományon a szupremumnorma végtelen lehet. A 9.2. MLP és nemlinearitás szakaszonként affin jellemzése itt megfordul: minden szakaszonként affin függvény előáll ReLU-hálóval. A 8.3. Kapacitás, regularizálás és modellválasztás kapacitásfogalma szerint az approximációs tétel a hipotézisosztály kifejezőképességét növeli, de a validáció és a tanítási variancia külön kérdés marad. Az 5.3. Mintavételi bizonytalanság és intervallum statisztikai bizonytalansága a labor ismételt seedjeire is vonatkozik.
Az univerzális approximációs tulajdonság azt jelenti, hogy egy hipotézisosztály tetszőleges folytonos függvényt tetszőleges pontossággal közelít kompakt tartományon, szupremumnormában. A fejezet teljes bizonyítással igazolja az 1D esetet: a lineáris interpoláns egyenletesen közelít, majd a szakaszonként affin függvény ReLU-töréspontok és meredekségugrások összegeként áll elő. A rejtett szélesség a töréspontok számától függ. A klasszikus Cybenko-tétel pontos feltételeit ellenőrizetlen forrásállapot miatt nem idézzük; bizonyítása elhagyott. A labor azt mutatja, hogy azonos paraméterszám mellett a konkrét súlykonfiguráció határozza meg a hibát, és a tétel nem ígér tanítási konvergenciát.
A 9.4. Aktivációk és gradiensáramlás egység az aktivációk gradiensáramlásra gyakorolt hatását vizsgálja: a ReLU töréspontjának konvencionális deriváltját, a telítődő szigmoid kis gradiensét és a mély hálók taníthatóságát.