A 29.2. Denoising és korrupciós modell egységben az autoencodert egy konkrét szerződésként írtuk fel: a bemenet a zajos , a tanulási cél a tiszta , az encoder–decoder páros pedig a rekonstrukciós hibát csökkenti. Ebben az alfejezetben a rekonstrukció mögötti latent reprezentációt vizsgáljuk. A szükséges előismeret a 25.3. Kis adat és feature-alapú baseline lineáris pixel-baseline gondolata, a 28.3. Retrieval-értékelés és adatfelosztás csoportos kiértékelési fegyelme és a 17.3. VGG és kis kernelek kompozíciója kapacitás/recepciós mező megkülönböztetése.
Induló kérdés: ha egy autoencoder empirikus rekonstrukciós hibája nulla, következik-e ebből, hogy a kód „szemantikailag” használható, például egy lineáris osztályozó fejjel jól leolvasható? A válasz nem: a triviális identitásleképezés tökéletesen rekonstruálhat, miközben semmilyen új, downstream feladat számára kedvező átrendezést nem végez.
A fejezet jelölésében a bemenet . A GlyphLab-kép , méretű NCHW-tensor, ezért a vektorizált bemenet dimenziója . Egy batch soronként egy-egy megfigyelést tartalmaz.
D1 (autoencoder és rekonstrukciós loss). Az encoder , a decoder , ahol a tanulandó paraméterek. A latent kód
Az empirikus rekonstrukciós veszteség elemenkénti átlagolással:
Az -es normálásnak itt nincs valószínűségi jelentése; pusztán az átlagos négyzetes eltérést adja batch- és pixelméreten.
D2 (bottleneck). Bottlenecknek vagy szűkületnek azt nevezzük, amikor . A kód tehát kisebb dimenziójú, mint a bemenet. Ha , akkor a modell magában foglalhatja a triviális megoldást:
amelyre minden bemeneten . Ez a triviális identitásleképezés. Fontos, hogy a feltétel sem oldja meg automatikusan a tanulási problémát: alacsony dimenziós altéren is létezhet olyan kód, amely a downstream feladat szempontjából rossz, vagy éppen összeomolhat a 29.2. Denoising és korrupciós modell alfejezetben tárgyalt módon.
D3 (latent collapse). Azt mondjuk, hogy a -edik latent koordináta összeomlott egy adott mátrixon, ha a koordinátánkénti szórása közel nulla. A -edik koordinátára
Teljes collapse esetén minden koordináta szórása eltűnik, tehát a decoder minden inputhoz lényegében ugyanazt az értéket kapja, és a rekonstrukció csak egy konstans képet tud előállítani. Részleges collapse ennél gyakoribb: egy dead unit nulla vagy konstans, a többi koordináta viszi az információt.
Ahhoz, hogy a „szemantikai tudást” matematikailag kezelhessük, nem definiáljuk általános filozófiai fogalomként. Rögzítünk egy downstream feladatot -nal, és egy lineáris leolvasó családot:
többosztályú logitokkal, vagy bináris esetben előjelfüggvénnyel. A „jobb reprezentáció” ekkor azt jelenti: a rögzített -családdal, azonos adatfelosztás mellett nagyobb downstream pontosság érhető el.
1. állítás (identitásleképezés mint ellenpélda, saját bizonyítás). Legyen a bemenetek halmaza
minden pont egyenletes valószínűséggel. Legyen a downstream címke
tehát , a másik két ponté . Tekintsük a triviális identitás-autoencodert: , . Ekkor
Ugyanakkor ezen a reprezentáción egyetlen lineáris osztályozó sem érhet el downstream pontosságot.
Bizonyítás. Legyen a lineáris leolvasó , és döntsünk esetén , egyébként mellett. Ha mindkét pozitív mintát jól osztályoznánk, akkor
A kettőt összeadva , azaz . Ha mindkét negatív mintát is jól osztályoznánk, akkor
Ezeket összeadva , azaz . Ez ellentmond -nak, tehát a négy pont nem osztályozható tökéletesen. A pontosság éles: az , , választással
ami három helyes döntést ad.
A kontraszt kedvéért vegyük ugyanezen a négy ponton a következő, szintén dimenziós reprezentációt:
A négy ponton , ezért az osztás értelmes, és mind a négy esetben. Tehát ennek a modellnek is
A lineáris leolvasó viszont mind a négy pontot jól osztályozza, mert pontosan akkor, ha . Az 1. állítás következménye tehát nem az, hogy a kis rekonstrukciós hiba „rossz”, hanem az, hogy önmagában nem bizonyítja a downstream hasznosságot. A két modell azonos kapacitással és azonos rekonstrukciós hibával is eltérő downstream viselkedést adhat.
A bizonyításnak van egy gyakorlati geometriai üzenete is: az identitás encoder megtartja a bemenet koordinátarendszerét. A downstream feladatot leíró döntési határ ebben a koordinátarendszerben nem lineáris, ezért a lineáris fej nem tudja leolvasni. Egy alkalmas nemlineáris encoder viszont kiszámíthat egy olyan új koordinátát, amelyben a feladat lineárissá válik. A rekonstrukciós cél ehhez semmilyen külső jelet nem ad; lehet szerencsés, de nem garantált.
Mivel a rekonstrukciós loss nem bünteti automatikusan a triviális vagy kedvezőtlen latent geometriát, a tanítási célhoz pótlólagos regularizáló tagot adhatunk. Két gyakori család:
Sparse regularizálás. Az aktivációk átlagos -normáját büntetjük:
A cél nem az, hogy minden kód nulla legyen, hanem hogy egyszerre kevés koordináta legyen aktív. Sztochasztikus gradiens alatt az -tag általában ritkító irányba tol, de egzakt nullákat nem feltétlenül állít elő; ez heurisztikus hatás, nem tétel. A értékét a rekonstrukcióval együtt kell ellenőrizni.
Contractive regularizálás. Az encoder Jacobi-mátrixának Frobenius-normáját büntetjük:
Itt , mert a sorok a kimeneti koordinátának, az oszlopok a bemeneti koordinátának felelnek meg. A tag azt méri, mennyire változik a kód a bemenet kis megváltoztatására. A triviális identitáson , ezért , tehát ez a regularizáló közvetlenül drágítja az identitásleképezést. Fontos korlát: ez lokális simasági heurisztika, nem általános robusztussági vagy azonosíthatósági tétel.
A latent térben a kódok elhelyezkedése, a latent geometry, nem automatikusan rendezett. Például a 28.3. Retrieval-értékelés és adatfelosztás alfejezetben tárgyalt kontrasztív tanulás explicit normalizálással egységgömbre vetít; egy sima MSE-autoencoder latent terében ilyen kényszer nincs. Ezért a következő kontrollokat érdemes külön kezelni:
A downstream kontroll azért nem bizonyít általános reprezentációminőséget, mert csak egyetlen címkére és egyetlen lineáris családra vonatkozik. Egy másik downstream feladat más rendezést igényelhet.
A labor kérdése az, hogy a GlyphLab orientációfeladatán a és latentméretű autoencoder hogyan viselkedik rekonstrukcióban és befagyasztott lineáris downstream pontosságban. A protokollt a futtatás előtt rögzítjük:
lab/data/images.npy, labels.npy,
metadata.csv; a splitet a metadata.csv
split oszlopa adja, a függetlenségi egység a
scene_id, tehát nem keverjük a nézeteket a felosztások
között.Linear(576,64), ReLU,
Linear(64,b); decoder Linear(b,64), ReLU,
Linear(64,576). Csak
változik, a hidden szélesség és az inicializálás receptje nem.20261020.Linear(b,3) fejet tanítunk cross-entropyval,
torch.manual_seed(20261020), Adam,
,
epoch, batch méret
;
validációs pontosságot jelentünk.A megadott numerikus kimenet szemléltető, tényleges értékét futtatással kell ellenőrizni.
# lab/n115_latent_probe.py
import csv
from pathlib import Path
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset
ROOT = Path("lab/data")
SEED = 20261020
D = 24 * 24
torch.manual_seed(SEED)
np.random.seed(SEED)
dtype, device = torch.float32, torch.device("cpu")
def read_splits():
idx = {"train": [], "val": [], "test": []}
with (ROOT / "metadata.csv").open(newline="") as f:
for row in csv.DictReader(f):
idx[row["split"]].append(int(row["index"]))
return idx
idx = read_splits()
X = np.load(ROOT / "images.npy").astype(np.float32).reshape(-1, D)
Y = np.load(ROOT / "labels.npy").astype(np.int64)
class AE(nn.Module):
def __init__(self, d, b, h=64):
super().__init__()
self.enc = nn.Sequential(nn.Linear(d, h), nn.ReLU(), nn.Linear(h, b))
self.dec = nn.Sequential(nn.Linear(b, h), nn.ReLU(), nn.Linear(h, d))
def forward(self, x):
z = self.enc(x)
return self.dec(z), z
def make_loader(indices):
tensors = (
torch.tensor(X[indices], dtype=dtype, device=device),
torch.tensor(Y[indices], dtype=torch.int64, device=device),
)
return DataLoader(TensorDataset(*tensors), batch_size=48, shuffle=True)
def train_ae(b, epochs=15):
torch.manual_seed(SEED)
model = AE(D, b).to(device)
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
loader = make_loader(idx["train"])
for _ in range(epochs):
for xb, _ in loader:
opt.zero_grad()
xh, _ = model(xb)
loss = nn.functional.mse_loss(xh, xb)
loss.backward()
opt.step()
return model
@torch.no_grad()
def embed_batch(model, indices):
out = []
for i in indices:
x = torch.tensor(X[i], dtype=dtype, device=device)[None, :]
out.append(model.enc(x)[0].cpu().numpy())
return np.stack(out)
@torch.no_grad()
def val_mse(model, indices):
x = torch.tensor(X[indices], dtype=dtype, device=device)
xh, _ = model(x)
return nn.functional.mse_loss(xh, x).item()
def downstream_acc(features_tr, label_tr, features_val, label_val, out_dim=3, epochs=30):
torch.manual_seed(SEED)
head = nn.Linear(features_tr.shape[1], out_dim).to(device)
opt = torch.optim.Adam(head.parameters(), lr=1e-2)
ce = nn.CrossEntropyLoss()
zt = torch.tensor(features_tr, dtype=dtype, device=device)
yt = torch.tensor(label_tr, dtype=torch.int64, device=device)
zv = torch.tensor(features_val, dtype=dtype, device=device)
yv = torch.tensor(label_val, dtype=torch.int64, device=device)
for _ in range(epochs):
opt.zero_grad()
loss = ce(head(zt), yt)
loss.backward()
opt.step()
pred = head(zv).argmax(dim=1)
return (pred == yv).float().mean().item()
def report(latent_b):
model = train_ae(latent_b)
z_tr = embed_batch(model, idx["train"])
z_val = embed_batch(model, idx["val"])
acc = downstream_acc(z_tr, Y[idx["train"]], z_val, Y[idx["val"]])
mse = val_mse(model, idx["val"])
print(f"b={latent_b:2d} val_MSE={mse:.4f} val_acc={acc:.3f}")
report(4)
report(16)
# Baseline: nyers pixel + ugyanaz a downstream fej.
acc_raw = downstream_acc(
X[idx["train"]], Y[idx["train"]],
X[idx["val"]], Y[idx["val"]],
)
print(f"raw pixel baseline val_acc={acc_raw:.3f}")A futtatás a projektgyökérből:
python lab/n115_latent_probe.pyJelölt, nem mért szemléltető kimenet:
| Modell | validációs MSE | downstream val_acc |
|---|---|---|
| AE | 0,0311 | 0,650 |
| AE | 0,0194 | 0,533 |
| nyers pixel baseline | — | 0,500 |
A táblázat számai nem futásból származnak, csak a lehetséges kimenet formáját mutatják. A tényleges futásban sem a kisebb, sem a nagyobb latentméret győzelmét nem ígérjük előre. Az értelmezéshez nemcsak az átlagpontosság kell: a modell kisebb rekonstrukciós hibája nem jelenti automatikusan a jobb downstream reprezentációt, éppen az 1. állítás tanulsága szerint. Emellett a koordinátánkénti -t is meg kell vizsgálni; ha például mellett több dead unit van, akkor a tényleges effektív dimenzió kisebb lehet a névlegesnél.
A gyakori tévedés: „ha a rekonstrukciós hiba kicsi, akkor a latent reprezentáció szükségképpen jó szemantikai reprezentáció.” Az 1. állítás konstrukciója cáfolja: az identitásleképezés értékű, de a XOR-feladaton a lineáris downstream fej legfeljebb pontosságot ér el. Egy másik, ugyancsak nulla rekonstrukciós hibájú nemlineáris reprezentáció viszont -et ér. A hiba forrása, hogy a rekonstrukciós cél nem tartalmazza a downstream címkét, a bemenet koordinátarendszerének megtartása pedig önmagában nem hoz létre lineárisan leolvasható jellemzőt.
Önellenőrzés. (1) Megkülönböztettem-e a névleges
dimenziót az effektív, nem összeomlott koordináták számától? (2) A
downstream pontosságot befagyasztott encoderen mértem-e, nem közös
finomhangolás után? (3) A validációs split megőrizte-e a
scene_id függetlenséget a 28.3.
Retrieval-értékelés és adatfelosztás szerződése alapján? (4) A
lineáris pixel-baseline-t ugyanarra a splitre és ugyanarra a fejre
futtattam-e, mint a 25.3. Kis adat és feature-alapú
baseline alfejezetben? (5) Nem állítottam-e általános
reprezentációminőséget egyetlen downstream feladatból?
F1. feladat (fogalmi, nehézség 1). Magyarázza el saját szavaival a bottleneck, a triviális identitásleképezés és a latent collapse közötti különbséget a , GlyphLab-példán. Adja meg mindhárom fogalom formális feltételét is.
F2. feladat (levezetési/bizonyítási, nehézség 2). Bizonyítsa be az 1. állításban használt -es felső korlátot: a négy XOR-ponton az identitás-reprezentációhoz tartozó lineáris osztályozó nem érhet el négy helyes döntést. Írja le azt is, miért lehet három helyes döntés éles.
F3. feladat (implementációs, nehézség 1). Írjon
Python-függvényt xor_readout_acc(alpha, beta, gamma) néven,
amely a négy XOR-pontra kiszámítja a
osztályozó pontosságát. Ellenőrizze, hogy az
eset
-ös
pontosságot ad, és adja meg azt a nemlineáris reprezentációt, amelyen a
lineáris leolvasó
-t
ér el.
F4. feladat (hibakeresési, nehézség 2). Egy hallgató a következő kóddal ellenőrzi a collapse-ot:
z = encoder(x_batch) # alak: (N, b)
print("collapse?", float(z.std().item()) < 1e-4)Mi a hiba? Írja le az okot, a lehetséges következményt, a javítást és a javítás utáni shape-ellenőrzést.
F5. feladat (kísérleti/transzfer, nehézség 3). Tervezze meg a GlyphLabon a és autoencoder összehasonlítását úgy, hogy a következtetés a befagyasztott lineáris downstream pontosságra és a rekonstrukcióra is korrekt korlátot adjon. Adja meg a megfigyelési egységet, a splitet, a baseline-t, a rögzített metrikákat és a legfőbb érvényességi korlátot. Győztest nem kell előre mondani.
F1 megoldás. A bottleneck a feltétel, tehát az encoder kimenete kisebb dimenziós, mint a bemenet. A esetben ; az identitásleképezés ekkor nem rendelkezik a szükséges -os súlyú lineáris identitásmátrixszal, pontosabban a leképzés nem viheti át általánosan mind a bemeneti koordinátát kódkoordinátán. A triviális identitás ehhez képest a esetben , . A collapse nem dimenziófeltétel, hanem aktivációeloszlás-feltétel; a kódmátrix valamely oszlopának szórása közel nulla. Ha , de egyetlen koordináta szórása sem nulla, még lehet rossz downstream pontosság; a csak kapacitás, nem minőség.
F2 megoldás. Tegyük fel, hogy a lineáris osztályozó mind a négy pontot jól osztályozza. A pozitív pontokra és előírt feltételekből
ezért . A negatív pontokra és előírt feltételekből
amelyek összege . Ez ellentmond -nak, tehát a négyes pontosság lehetetlen. A éles, mert az választás három helyes döntést ad, ahogy az 1. állításban kiszámoltuk. A bizonyítás fontos előfeltétele, hogy a döntési szabály , nem pedig ; a szigorú egyenlőtlenség a nulla küszöbnél elkerüli a degenerált esetet.
F3 megoldás.
import numpy as np
P = np.array([[1, 1], [-1, -1], [1, -1], [-1, 1]], dtype=np.float64)
Y = np.array([1, 1, 0, 0], dtype=np.int64)
def xor_readout_acc(alpha, beta, gamma):
q = alpha * P[:, 0] + beta * P[:, 1] + gamma
pred = (q > 0).astype(np.int64)
return float((pred == Y).mean())
print(xor_readout_acc(10.0, 10.0, -0.1)) # 0.75
# Nemlineáris reprezentáció: z=(x1*x2, x1), leolvasó q=z1.
Z = np.column_stack([P[:, 0] * P[:, 1], P[:, 0]])
pred_z = (Z[:, 0] > 0).astype(np.int64)
print((pred_z == Y).mean()) # 1.0A függvény kimenete a várt és ; a bemenő pontokra nincs szükség numerikus toleranciára, mert a döntés csak előjel-egyenlőtlenségeket használ.
F4 megoldás. A hiba oka: a z.std()
hívás a teljes (N,b) tensor minden elemére számít egyetlen
skalár szórást. Ez a skalár magas lehet akkor is, ha a tensor
oszlopából
teljesen nulla vagy konstans. A következmény: a részleges vagy teljes
collapse észrevétlen marad. Javítás:
unit_std = z.std(dim=0) # alak: (b,)
collapsed = unit_std < 1e-4
print("koordinátánként:", unit_std)
print("collapsed:", collapsed.sum().item(), "/", collapsed.numel())Ellenőrzés:
alakja (N, b), ezért z.std(dim=0) alakja
(b,); a küszöb alá eső koordinátákat egyesével jelentjük.
Numerikusan a teljes tensor-szórás és az oszloponkénti szórás nem
összekeverhető reduction-konvenció.
F5 megoldás (lehetséges terv). Megfigyelési egység:
egy kép, de a split függetlenségi egysége a scene_id, tehát
egyetlen jelenet mindkét view-ja azonos részbe kerül. Protokoll: a
tanító spliten tanítunk két MSE-autoencodert
és
mellett, azonos hidden szélességgel, seeddel és epochszámmal. Utána
mindkét encoder súlyát befagyasztjuk; a tanító kódokon lineáris fejet
tanítunk orientációra, a fejet a validációs spliten értékeljük.
Baseline: ugyanaz a lineáris fej a nyers
dimenziós pixelveken. Metrikák: validációs MSE, validációs downstream
pontosság, a latent koordinátánkénti szórása és a collapsed koordináták
száma. A teszt splitet csak a protokoll lezárása után használjuk.
Érvényességi korlát: a GlyphLab három, geometriailag szintetikus
osztályt tartalmaz, így a következtetés nem vihető át természetes
képfelismerésre; a downstream eredmény egyetlen lineáris fejre
vonatkozik, tehát nem általános reprezentációminőség. A rekonstrukciós
és downstream rangsor akár el is válhat, ahogy az 1. állítás
mutatja.
Az autoencoder rekonstrukciós célja nem rögzíti a latent tér downstairs hasznosságát. A triviális identitásleképezés nulla hibát ad, miközben egy XOR-szerű downstream címkén a lineáris fej legfeljebb pontosságot ér el; egy alkalmas nemlineáris encoder ugyanakkora dimenzióval és ugyancsak nulla rekonstrukciós hibával teljes pontosságot adhat. Ezért a nullához közeli MSE önmagában nem bizonyít szemantikai tudást. A bottleneck, ritka aktiváció és kontraktív büntetőtag heurisztikus irányt ad, de a tényleges ellenőrzéshez külön kell mérni a rekonstrukciót, a koordinátánkénti collapse-ot és egy előre rögzített downstream kontrollt.
A következő 29.4. Anomáliapontszám rekonstrukcióból egység az anomáliapontszám rekonstrukcióból való származtatását vizsgálja; az itteni azonosság és kapacitás-megkülönböztetés ott annak korlátjaként tér vissza, hogy a kis rekonstrukciós hiba nem automatikusan jelent ismert mintát.
Felhasznált források: