Ebben az egységben azt tanuljuk meg, hogyan lesz egy alkalmazási ötletből ellenőrizhető modellezési feladat: bemeneti tér, döntési tér, megfigyelt cél és mérhető sikerkritérium. Előismeret nem szükséges a könyvből; a programozói előismeret annyi, hogy a hallgató ciklust, függvényt és tömböt tud írni. Induló becslésként válaszold meg magadban: ha egy levélszemét-szűrő azt a kézzel írt szabályt használja, hogy az „ingyen” szó előfordulása spamet jelent, tanult modellről beszélünk-e? Mi hiányzik ahhoz, hogy a szűrő adatból tanuljon?
Az alábbi meghatározások e könyv munkadefiníciói, tehát definíciók, nem bizonyítandó tételek. Az AI (artificial intelligence, mesterséges intelligencia) tág munkakategória: olyan rendszer, amely emberi módon leírható, döntés jellegű feladatot lát el. Ennek nincs egységes formális definíciója, ezért a további fogalmakat ettől függetlenül, az adat szerepén keresztül pontosítjuk.
A viszony tehát: a könyvben tárgyalt mély CNN-ek a DL részhalmazát alkotják (az egyetlen konvolúciós rétegű háló a határeset), a DL az ML részhalmaza, az ML pedig az AI egyik, adatközpontú részhalmaza. A kurzusjegyzet [S01] is ebben az értelemben tárgyalja a konvolúciós hálókat mint a mély modellek egy osztályát. A CNN klasszikus, dokumentumfelismerő alkalmazását [P01] tárgyalja; a részletes architektúrák és mérési eredmények pontos forráshelyeinek megjelölése a későbbi architektúrafejezetek feladata.
Ellenpélda a szinonima-kezelésre: egy 1990-es évekbeli szabályalapú spam-szűrő lehet AI-alkalmazás, de nem ML, mert az adat nem befolyásolta a döntési függvényt. Egy legkisebb négyzetes lineáris regresszió ML, de nem DL és nem CNN. Egy CNN alapú képfelismerő mindhárom kategóriába tartozik.
A feladat szerződéséhez négy objektumot választunk szét.
Definíció (feladatszerződés). Adott egy bemeneti tér és egy döntési tér. A megfigyelés , a cél (target) felügyelt esetben , a döntés pedig . A sikerkritérium egy olyan függvény, amely a döntés és a cél egyezését méri; többosztályos osztályozásnál , és az egyszerű választás az egyezési arány ahol az indikátorfüggvény: igaz esetén 1, hamis esetén 0.
Definíció (modell, hipotézisosztály, tanítás, inference). A döntési modell egy paraméterezett leképezés , ahol a paraméter. Többosztályos neurális osztályozásban érdemes különválasztani a hálózat logitfüggvényét és a döntési szabályt (például az argmaxot): . A hipotézisosztály az összes ilyen döntési leképezés halmaza: A tanító adat . A tanító algoritmus olyan eljárás, amely alapján egy paramétert választ; a tanítás tehát az folyamat. Az inference a már rögzített kiértékelése új bemeneten; ekkor nem változik.
A két életciklus szétválasztása azért fontos, mert a tanítás alatt az algoritmus látja a célokat, az inference alatt pedig a döntést a bemenetből kell előállítani. Egy modell önmagában nem „tud” semmit: a tanító algoritmus választotta ki a hipotézisosztály egy elemét.
Tensoralak szempontjából a későbbi képosztályozási főút ezt a konvenciót használja: a képbatch (batch, csatorna, magasság, szélesség), az osztályozási cél , a döntést pedig egy pontszámtömbből, a logitból képezzük. A GlyphLab alapadata erre konkrét példa: , , .
A tanulási mód leírja, mi a megfigyelt cél:
Ugyanaz a háló lehet unsupervised módon tanított reprezentáció, amelyet később felügyelt osztályozó fejjel használunk; a tanulási mód és a felhasználási cél külön dimenzió. Ezt a megkülönböztetést később a kontrasztív és generatív fejezetben is használjuk.
A következő kis példa nem tétel, hanem három objektum definíciója és számítási kontroll, amely megalapozza a későbbi állítások feltételrendszerét.
Adat. Legyen a kétdimenziós XOR-osztályozási példa tehát , , . A dimenziós vektorokat elvileg oszlopvektorként írjuk; a Python-kódban a batch egy sora az oszlopvektor transzponáltja.
Hipotézisosztály. A lineáris küszöbös osztályozók halmaza Mindegyik elem tehát egy félsík, amelyet a normálvektor és a eltolás ad meg.
Algoritmus. A tanító algoritmus egy véges rácson keresi a legkisebb tanítóhibájú elemet: A rács: és ; holtversenyben a bejárási sorrend szerinti első modellt választjuk. Ez az algoritmus tehát nem azonos a hipotézisosztállyal: végtelen, az algoritmus viszont csak 45 modellt vizsgál meg.
A , modellre , így Ezért . A XOR-pontok nem lineárisan szeparálhatók: a és pontokat összekötő szakasz a 0 osztályú, a és pontokat összekötő szakasz az 1 osztályú pontok konvex burkában van, és a két szakasz metszi egymást a pontban. Ezért nincs olyan félsík, amely mind a négy pontot helyesen osztályozná, tehát a teljes osztályon is a minimális tanítóhiba. A példa így azt is mutatja, hogy a hipotézisosztály megválasztása korlátozza az elérhető tanítóhibát, függetlenül az algoritmus ügyességétől.
A rácskeresés kézzel áttekinthető, de a kód a hallgató számára
ellenőrizhetővé teszi. Input: X float32, y
int64; a kimenet a legjobb rácspont, a hiba és a predikció.
# munkakönyvtár: lab/
import numpy as np
X = np.array([[0.0, 0.0],
[1.0, 0.0],
[0.0, 1.0],
[1.0, 1.0]], dtype=np.float32) # (4, 2)
y = np.array([0, 1, 1, 0], dtype=np.int64) # (4,)
def train_error(w1, w2, b):
z = X @ np.array([w1, w2], dtype=np.float32) + b
pred = (z > 0).astype(np.int64)
return np.mean(pred != y)
grid_w = [-1, 0, 1]
grid_b = [-2, -1, 0, 1, 2]
best = (None, None, None, np.inf)
for w1 in grid_w:
for w2 in grid_w:
for b in grid_b:
err = train_error(w1, w2, b)
if err < best[3]:
best = (w1, w2, b, err)
print(best) # (-1, -1, 2, 0.25)A kiírt érték a megadott bejárási sorrendből számított eredmény: a minimális 0,25 hibát több rácspont is eléri, de az első a paraméterhármas. A hallgató futtassa le, és a kapott négyest illessze a F3. feladat kontrolljához.
Ez a labor dokumentációs labor, nem betanított modell. Célja, hogy a hallgató a mellékelt GlyphLab adatra két külön felhasználási feltétellel rendelkező problémalapot írjon.
Laborcsomag. A könyv minden laborja a
cnn-labor laborcsomagra épül, amelyet a könyv a
cnn-labor-1.0.0.zip mellékletként ad; a csomag a korábbi
V8-as példatár utódja, és a jelen kiadás forrásszövegéből készül.
Tartalma: a lab/ munkakönyvtár a GlyphLab eredeti
adatgenerátorával (generate_data.py, seed
20261020, generátorverzió 1.0), az előre legenerált
data/ fájlokkal, a quickcheck.py ellenőrzővel
és a könyv lab/... fejlécű laborfájljaival; a lockolt
környezet (lab/pyproject.toml, lab/uv.lock:
Python 3.12, NumPy 2.3.5, CPU-s PyTorch 2.14.1, Matplotlib 3.10.8,
pandas 2.3.3, SciPy 1.18.1); a könyv minden kódblokkja alfejezetenként
(examples/, catalog.json) és alfejezetenkénti
notebookokban (notebooks/); valamint a fájlonkénti SHA-256
lenyomatokat tartalmazó RELEASE_MANIFEST.json.
Licenc: a kód MIT, a generált GlyphLab-adat és a
dokumentáció CC BY 4.0 (a csomag LICENSE fájlja). Az adat
szintetikus: külső képet, személyes adatot vagy letöltött adatkészletet
nem tartalmaz. Telepítés kicsomagolás után egyetlen
paranccsal: cd cnn-labor-1.0.0/lab && uv sync (a
környezetről részletesen: 2.3. Izolált környezet,
notebook és verzió). Az adat a csomagban is benne van, de üres
data/ könyvtárból is előállítható:
uv run python generate_data.py --output data, majd
uv run python quickcheck.py. A generátor azonos
NumPy-verzió mellett bitazonos fájlokat ad; a referencia-lenyomatok (a
data/manifest.json sha256 mezője, amelyet a
quickcheck.py ellenőriz):
images.npy
cdb84fcbcdf6f2b6a09bfeba3b1f81b83a2c1f120b5be7cdac5fffb3b65a48e2
masks.npy
bd884de178f2fc43c4bea3203cc21c47c466a99e0438fd783a34dc8cb4d966b2
labels.npy
073013f0be8aa25c5c1cf81bf9aeb85a07b501335493af2481799921e3286539
corrupted_test.npy
0936e20e7830744acd1519d81d3f0364fc2a1707985370fe4378d5cfc2967515
metadata.csv
5acc5c5d4c6e1866b30519c84c35c895b60b499feff12c680bfbaf02fb5c1b9b
Környezeti adatok. Munkakönyvtár: lab/.
Az adatfájlok: data/images.npy alakja
(360,1,24,24) és típusa float32, értékkészlete
;
data/labels.npy alakja (360,) és típusa
int64, értékei {0,1,2};
data/masks.npy alakja (360,1,24,24), típusa
uint8, értékei {0,1};
data/metadata.csv oszlopai
index, scene_id, view_id, label, split, xmin, ymin, xmax, ymax.
A data/corrupted_test.npy csak a test sorrendjét követi,
alakja (60,1,24,24). A generálási seed
20261020; a későbbi tanítási seed ettől külön rögzítendő. A
jövőbeli modell bemenete float32, a címke
int64, a maszk uint8; eszköz CPU, ettől eltérő
eszközt külön dokumentálni kell. Az adat-ellenőrző parancs a hallgatói
futtatáshoz: uv run python quickcheck.py a
lab/ könyvtárban; a kimenetét a hallgató a saját
jegyzőkönyvébe menti. A lockolt profilban (Python 3.12.3, NumPy 2.3.5) a
generátor újrafuttatása a fenti lenyomatokkal bitazonos fájlokat adott,
és a quickcheck.py hiba nélkül lefutott.
A leadandó lab/problem_specs.md két blokkból áll.
Mindkettő kötelező rovatai: Bemenet, Döntés,
Cél, Siker, Split, Megfigyelési
egység, Baseline, Felhasználási feltételek.
A. Orientáció-osztályozó. Bemenet: a képtensor
.
Döntés:
(0 függőleges, 1 vízszintes, 2 átlós). Cél:
,
int64. Siker: test-beli per-image egyezési arány; a predikció és metrika
elemi egysége a kép, a split és a bizonytalanságbecslés független
mintavételi egysége a scene_id, mert egy jelenet két nézete
nem független. Split: osztályonként train 40, val 10, test 10 jelenet;
összesen 120/30/30 jelenet, azaz jelenetenként két nézettel 240/60/60
kép. Baseline: a train-beli leggyakoribb osztály konstans döntése.
Felhasználási feltételek: modellt és hiperparamétert csak train/val
alapján választunk; a testet a rögzített választás után legfeljebb
egyszer értékeljük; a korrupt tesztet csak befagyasztott modellen,
utólagos ráhangolás nélkül értékeljük; a maszk, doboz és
scene_id nem lehet az osztályozó bemenete; a 90°-os
forgatás nem címkemegőrző augmentáció, mert a függőleges és vízszintes
címkét felcseréli.
B. Pixelmaszk. Bemenet: a képtensor. Döntés:
előtér-háttér előrejelzés. Cél: a masks.npy
tömb. Siker: képenkénti
ahol a halmaz a nemnulla pixelek halmaza; a GlyphLab képei tartalmaznak
előteret, ezért az üres unió esete nem fordul elő, de ha mégis, a
megfigyelést kizárjuk és jelentjük. Megfigyelési egység: kép és jelenet;
a per-pixel átlag nem keverendő a per-image átlaggal. Felhasználási
feltételek: a maszk csak cél, nem bemenet; a kép és a maszk geometriai
transzformációját együtt kell végezni; a metadata.csv
doboza a maszk legkisebb befoglaló, nullától indexelt, félig nyílt xyxy
téglalapja,
,
.
A két problémalap külön feltételeket rögzít, mert az osztályozó egy képszintű döntést, a maszkmodell pedig pixelenkénti döntést ad; a kettő sikerfogalma és adatszivárgási felülete sem azonos.
F1 (fogalmi, nehézség 1). Sorold be az AI/ML/DL/CNN halmazokba: (a) kézzel írt szabályokkal működő spam-szűrő; (b) legkisebb négyzetes lineáris regresszió; (c) konvolúciós háló képfelismerésre; (d) az a klasszifikátor, amely a train halmaz leggyakoribb osztályát adja vissza. Cáfold meg a „minden ML-rendszer mélytanulás” állítást. Átadandó: 4–8 mondat indoklással.
F2 (levezetési, nehézség 2). Adott a egydimenziós adat, a hipotézisosztály és a félreosztályozási arány mint tanítóhiba. Igazold esetszétválasztással, hogy a minimális tanítóhiba . Adj meg egy bővebb hipotézisosztályt, amelyen a tanítóhiba , konkrét paraméterrel. Átadandó: az esetek, a számolás és a bővebb modell paramétere.
F3 (implementációs, nehézség 2). Írj futtatható
Python függvényt grid_linear(X, y) néven az
XOR-rácskeresésre. Input: X float32 (N,2),
y int64 (N,); output
(w1, w2, b, err, pred) a fenti rács legkisebb hibájú
pontjával, holtversenyben a bejárási sorrend szerinti elsővel. Futtasd a
XOR-adaton, és ellenőrizd a (-1,-1,2),
err=0.25, pred.shape=(4,) értékeket.
Átadandó: a teljes függvény importokkal, inputtal és
assert kontrollal.
F4 (hibakeresési, nehézség 2). Az alábbi vázlat a küszöböt a teljes adaton választja, majd ugyanazon az adaton számol hibát:
X = ... # a teljes megfigyelés
y = ...
grid = [...]
best = min(grid, key=lambda a: np.mean((X > a) != y))
report = np.mean((X > best) != y)Lokalizáld a hibát: miért nem tekinthető a report
független teszt eredménynek? Átadandó: az ok, a következmény, a
javított protokoll és a visszaellenőrzés módja.
F5 (kísérleti/transzfer, nehézség 3). A GlyphLab osztályozót olyan új jeleneteken szeretnénk vizsgálni, amelyek felbontásúak és erősebb zajt kaptak. Tervezz előzetes kísérletet: kérdés, baseline, megfigyelési egység, adatválasztási szabály, metrika, protokoll és érvényességi korlátok. A modellt a célválasztáshoz ne hangold újra. Átadandó: egy protokollterv a fenti rovatokkal, a korlátok indoklásával.
F1 megoldás. (a) A szabályalapú spam-szűrő AI-alkalmazás lehet, de nem ML, mert a döntési függvényt nem adatból választottuk. (b) A lineáris regresszió adatból becsli a paramétereit, tehát ML és AI, de nem DL, mert nem sok rétegű paraméterezett háló. (c) A képfelismerő CNN a gyakorlatban több konvolúciós rétegből álló mély háló, ezért DL és ML is; AI-besorolása a tág munkadefiníció szerint szintén teljesül. (d) A leggyakoribb osztályt visszaadó klasszifikátor tanul, ha a többségi osztályt a trainből becsüljük; ez ML, de egyben a legegyszerűbb baseline, és sem nem DL, sem nem CNN. A „minden ML-rendszer mélytanulás” hamis, mert (b) és (d) ML, de nem DL.
F2 megoldás. Az paraméter esetei: ha , mindhárom predikció , hiba ; ha , a -hez , a másik kettőhöz tartozik, hiba (az határeset ugyanígy); ha , a ponthoz tartozik, pedig célja , az ponthoz tartozik, pedig célja , hiba ; ha , hasonlóan ; ha , az pont jó, a pont rossz, hiba . Tehát a minimum . Bővebb hipotézisosztály az intervallum-jellegű ez valóban bővebb, mert mellett , tehát . A , paraméter mindhárom pontot helyesen osztályozza, hibája . (A végpont nélkül az intervallumosztály nem tartalmazná -t; ekkor csak a megadott véges mintán vett megszorítások kifejezőerejét hasonlíthatnánk össze.)
F3 megoldás. A teljes függvény:
# lab/f3_grid_linear.py
import numpy as np
def grid_linear(X, y):
assert X.ndim == 2 and X.shape[1] == 2
assert X.dtype == np.float32
assert y.ndim == 1 and y.dtype == np.int64
assert X.shape[0] == y.shape[0] > 0, "azonos, pozitív mintaszám kell"
best = None
grid_w = [-1, 0, 1]
grid_b = [-2, -1, 0, 1, 2]
for w1 in grid_w:
for w2 in grid_w:
w = np.array([w1, w2], dtype=np.float32)
for b in grid_b:
z = X @ w + b
pred = (z > 0).astype(np.int64)
err = np.mean(pred != y)
if best is None or err < best[3]:
best = (w1, w2, b, err, pred.copy())
return best
X = np.array([[0.0, 0.0], [1.0, 0.0],
[0.0, 1.0], [1.0, 1.0]], dtype=np.float32)
y = np.array([0, 1, 1, 0], dtype=np.int64)
w1, w2, b, err, pred = grid_linear(X, y)
assert (w1, w2, b) == (-1, -1, 2)
np.testing.assert_allclose(err, 0.25, rtol=1e-7, atol=1e-10)
assert pred.shape == y.shape == (4,)
np.testing.assert_array_equal(pred, np.array([1, 1, 1, 0], dtype=np.int64))A bemeneti assert-ek csak azt állítják, amit ténylegesen
ellenőriznek: X kétdimenziós, két oszlopú és float32
típusú; y egydimenziós és int64; a mintaszám pozitív, és
X meg y sorainak száma azonos. Ebből
következik, hogy a pred alakja megegyezik y
alakjával, és hogy az átlagolt hiba nem üres tömbön számolódik. Például
X.shape == (4, 2) és y.shape == (1,) esetén a
függvény AssertionError: azonos, pozitív mintaszám kell
hibával áll meg, ahelyett hogy a pred != y összehasonlítás
csendben broadcastolna. A numerikus tolerancia az átlag pontos értékére
vonatkozik, mert négy mintán a hiba
alakú.
F4 megoldás. A hiba oka adatszivárgás: a küszöb
kiválasztása a teljes X, y páron történik, tehát a „teszt”
megfigyelések is befolyásolták a modellt. Következménye optimista
torzítás: a jelentett hiba a már látott mintákon mér, ezért a
hiba nem általánosítási bizonyíték. Javítás: a splitet a keresés előtt
rögzítjük, a küszöböt csak a train indexeken választjuk, majd a testen
egyszer számolunk:
train_idx, test_idx = fixed_split(...)
best = min(grid, key=lambda a: np.mean((X[train_idx] > a) != y[train_idx]))
report = np.mean((X[test_idx] > best) != y[test_idx])Visszaellenőrzés: rögzítsük a split azonosítót és a nyers hibát;
ismételt futtatáskor ugyanazzal a splittel ugyanazt az eredményt kell
kapnunk, és a test nem vehet részt a min keresésben.
F5 megoldás (minta). Kérdés: mennyit romlik a már
rögzített GlyphLab-osztályozó, ha a felbontás
és a zaj nő? Baseline: a régi train leggyakoribb osztályát konstansként
adó szabály az új teszten, hogy a modell ennél jobb-e. Megfigyelési
egység: scene_id; az új generátor 30 tesztjelentből 60
képet készít, osztályonként 10 jelenetet, hogy a korábbi split szerkezet
megmaradjon. A modellválasztás kizárólag a régi train/val halmazon
történt; az új adat csak zárt kiértékelésre szolgál. Metrika: per-image
accuracy, majd a scene-párok figyelembevételével bootstrap intervallum
scene-resamplinggel. Protokoll: a modell súlyait befagyasztjuk, az új
teszt predikcióit egyszer mentjük, a nyers hibamátrixot és a seedeket
naplózzuk. Érvényességi korlát: a felbontás és a zaj egyszerre változik,
ezért a kettő hatása nem választható szét faktoriális kísérlet nélkül; a
GlyphLab továbbra sem természetes képi benchmark, így a romlás nem
általánosítható valós alkalmazásra.
A leggyakoribb tévedés, hogy a CNN az összes AI-modell szinonimája. Ellenpélda: a lineáris regresszió ML-modell, mert paramétereit adatból becsüljük, de nincs konvolúciós rétege, ezért nem CNN. Megfordítva, egy konvolúciós háló sem fedi le az összes AI-t: egy kézzel írt sakkszabály-motor AI lehet, de nincs tanuló paraméterezése. A rövidítések tehát halmazviszonyt jelölnek, nem stíluscímkét.
Ellenőrizd magad: minden állításnál meg tudod-e nevezni a bemeneti teret, a döntési teret, a célt és a sikerkritériumot? El tudod-e különíteni, hogy egy lépés a tanításhoz vagy az inference-hez tartozik? Korábbi könyvfogalom híján a visszahívás a feltételezett programozói előismeretre korlátozódik: a tanító algoritmus is egy függvény, csak a visszatérési értéke nem közvetlen predikció, hanem az a paraméter, amellyel később predikciót számítunk.
Ebben az egységben az AI, ML, DL és CNN fogalmát különválasztottuk: az AI tág munkakategória, az ML adatból választ modellt, a DL paraméterezett neurális hálócsalád, a CNN lokális súlymegosztott rétegeket használ. A modell, a tanítás és az inference külön életciklus; a feladatszerződés bemenetből, döntésből, célból és mérhető sikerből áll. Az XOR-példán definiáltuk az adatot, a hipotézisosztályt és a kereső algoritmust: a legjobb lineáris modell tanítóhibája , mert a pontok nem lineárisan szeparálhatók. A GlyphLab-labor két szerződést rögzít: orientáció-osztályozás és pixelmaszk, eltérő megfigyelési és felhasználási feltételekkel.
A következő egység a szakmailag megalapozott modellezési állítások feltételeit, a bizonyítékok típusait és az ellenőrzés módszereit tárgyalja. Az itteni feladatszerződést ott hipotézisekkel és kísérleti naplóval egészítjük ki.