Az autoencoder 29.4. Anomáliapontszám rekonstrukcióból determinisztikus leképezése akkor hasznos, ha csak rekonstrukció kell, de nem ad generatív leírást: nincs definiált valószínűségi modellje az adatra, és nincs értelmezett előzetes eloszlása a látens téren, amelyből új mintát húzhatnánk. A variational autoencoder (VAE) ezt egészíti ki egy látens változós valószínűségi modellel. Előismeret: a 11.4. Egy teljes PyTorch tanítási iteráció tanítási lépés, a 7.4. Numerikus stabilitás és jelentésmegőrző implementáció stabil log-likelihood-számítás, a 29.4. Anomáliapontszám rekonstrukcióból rekonstrukciós pontszám korlátai, és az 5.4. Függő képek, seedek és resampling statisztikai mintavételi egység gondolata. Visszautalás: a 30.1. Pretext és downstream feladat alfejezetben a reprezentációt downstream feladathoz kötöttük; a 27.1. Pixelszintű klasszifikáció és FCN pixelcélok átlagolását itt a rekonstrukciós likelihood tag átlagolásához idézzük vissza.
Induló kérdés: ha a megfigyelt mögött látens áll, akkor a posterior a Bayes-szabályból adódna, de a nevező . Mi a helyes tréningcél, ha ez az integrál gyakorlatban nem számolható? Becslés: nem a posterior közvetlen tanítása, hanem egy eltolható alsó korlát maximalizálása.
Legyen a megfigyelt adatvektor , a látens vektor , tipikusan . Rögzítünk egy priort (előzetes eloszlást) ; a leggyakoribb választás .
A decoder likelihood egy paraméterezett feltételes sűrűség amely kimondja, hogyan keletkezik az adat a látens változóból. NCHW képbatch esetén , de a jelen levezetésben az egyetlen megfigyelt vektor; batchelt alaknál az dimenziót külön redukció hordozza.
A közös modell a marginális likelihood pedig A valódi posterior amely általában nem zárt alakú, mert a nevező nagydimenziós integrál.
Emiatt bevezetünk egy encoder distribution-t, amely a posterior közelítése. Tensorparaméterezés: az encoder egy bemenetből és tenzort ad; ezzel A paraméterezés numerikusan előnyös: a szórásnégyzet pozitivitása kerül a logaritmus mögé, hasonlóan ahhoz, ahogy a 7.4. Numerikus stabilitás és jelentésmegőrző implementáció alfejezetben a logitok stabilitását kezeltük.
A KL-divergencia két folytonos sűrűség között ahol a természetes alapú. A divergencia csak akkor véges, ha ott, ahol ; ezt nevezzük a jelen fejezetben támogatási feltételnek. , egyenlőség akkor és csak akkor, ha a két sűrűség egybeesik (a nullmértékű eltéréstől eltekintve).
A variációs alsó korlát, más néven ELBO (evidence lower bound):
A levezetéshez a Jensen-egyenlőtlenséget megadott alakban vesszük:
Jensen (adott alak). Ha véges várható értékű véletlen változó, és konkáv, akkor , ahol a is megengedett. A szigorú konkavitás miatt egyenlőség akkor van, ha konstans a valószínűség szerint egy szettől eltekintve. A mértékelméleti finomságot itt nem tárgyaljuk; a tankönyv véges sűrűségekre szorítkozik.
Tétel (ELBO alsó korlát). Tegyük fel, hogy rögzített -re mindenütt, ahol , és . Ekkor Egyenlőség akkor és csak akkor áll fenn, ha a szerint majdnem mindenütt.
Bizonyítás. A támogatási feltétel miatt a marginális felírható a következőképpen: ahol . A véges-ELBO feltétel miatt integrálható, és a szerint. Alkalmazzuk a Jensen-egyenlőtlenséget a konkáv -ra: Az egyenlőség feltételéből konstans -szerint; mivel az átlaga , ezért átrendezve .
A gyakorlatban használt felbontás:
Lemma. A fenti feltételek mellett
Bizonyítás. és a második tag éppen a KL-divergencia.
Az első tag a rekonstrukciós tag: a látensből adott log-likelihoodja. Ha a dekóder Gauss-likelihood rögzített varianciával: tehát a rekonstrukciós tag az MSE negatív, konstans- és skálafaktorral összekötve. Ez a 29.4. Anomáliapontszám rekonstrukcióból alfejezetben használt rekonstrukciós pontszám valószínűségi jelentése.
Két további, gyakran kevert állapot:
Legyen , , , , a dekóder lineáris Gauss: , , , és az adat . A Gauss–Gauss KL zárt alakját (lásd az F2 feladatot) használva:
A rekonstrukciós tag várható értékéhez a lineáris dekóder miatt: Itt , , ezért . A konstanssal: Így az ELBO .
Ellenőrzésként a modell marginálisa zárt alakú, mert lineáris Gauss: , mivel a generatív prior varianciája , nem pedig a közelítő posterior -ban szereplő . Numerikusan , tehát valóban , a rés körülbelül , ami .
| Mennyiség | Képlet/közelítő | Érték |
|---|---|---|
| ELBO | rekonstrukciós tag mínusz KL | |
| Egymintás MC a -nál |
Az egymintás Monte-Carlo érték nagymértékben eltér az ELBO-tól; ez a jelölt szemléltetés, nem annak a bizonyítéka, hogy az ELBO-t egy mintával becsülni kell.
A következő kód a fenti kézi példát hajtja végre float64 CPU-n; a
determinisztikus értékek a 4. szakasz számításaiból jönnek, az MC-sorok
csak a kód tényleges futtatása után tekinthetők mértnek. Munkakönyvtár:
lab/n121.
# munkakönyvtár: lab/n121
# parancs: python vae_elbo_toy.py
import math
import torch
torch.manual_seed(20261020)
torch.set_default_dtype(torch.float64)
x = torch.tensor([0.4, -0.2]) # (D,), D=2
mu = torch.tensor([0.2]) # (K,), K=1
sigma2 = torch.tensor([0.25]) # q szórásnégyzete
W = torch.tensor([1.0, -0.5]) # (K,D) dekódolt lineáris súly
sigma_d2 = 0.16
D = x.shape[0]
def gauss_kl(mu, sigma2):
# q=N(mu, diag(sigma2)), p=N(0,I)
return 0.5 * (sigma2 + mu**2 - 1.0 - torch.log(sigma2)).sum()
def recon_expected(x, mu, sigma2, W, sigma_d2):
# E_q ||x - W z||^2 = ||x - W mu||^2 + sigma2 * ||W||^2
mean_residual = x - W * mu
quad = mean_residual.pow(2).sum() + sigma2 * W.pow(2).sum()
const = -0.5 * D * math.log(2.0 * math.pi * sigma_d2)
return const - quad / (2.0 * sigma_d2)
def mc_elbo(x, mu, sigma2, W, sigma_d2, n_samples):
sigma = sigma2.sqrt()
with torch.no_grad():
z = mu + sigma * torch.randn(n_samples, 1) # (n_samples, K)
log_pz = -0.5 * (math.log(2.0 * math.pi) + z.pow(2)).sum(dim=1)
log_qz = -0.5 * (math.log(2.0 * math.pi * sigma2)
+ (z - mu).pow(2) / sigma2).sum(dim=1)
diff = x - W * z # (n_samples, D)
log_px = -0.5 * D * math.log(2.0 * math.pi * sigma_d2) \
- diff.pow(2).sum(dim=1) / (2.0 * sigma_d2)
return (log_px + log_pz - log_qz).mean()
kl = gauss_kl(mu, sigma2)
recon = recon_expected(x, mu, sigma2, W, sigma_d2)
elbo = recon - kl
C = sigma_d2 * torch.eye(2) + torch.outer(W, W) # p(z)=N(0,1), nem q varianciája
logdet = torch.slogdet(C).logabsdet
maha = x @ torch.linalg.solve(C, x)
log_px = -0.5 * D * math.log(2.0 * math.pi) - 0.5 * logdet - 0.5 * maha
print(f"KL(q||prior) = {kl.item():.6f}")
print(f"E_q log p(x|z) = {recon.item():.6f}")
print(f"ELBO (zart) = {elbo.item():.6f}")
print(f"log p(x) = {log_px.item():.6f}")
print(f"ELBO <= log p(x) : {(elbo <= log_px).item()}")
print("MC 100000 (jelolt) ~ -1.4763; csak futtatas utan rogzitendo")Jelölt kimenet (a determinisztikus sorok a kézi számításból, nem mért futásból):
KL(q||prior) = 0.338147
E_q log p(x|z) = -1.138108
ELBO (zart) = -1.476255
log p(x) = -1.164303
ELBO <= log p(x) : True
MC 100000 (jelolt) ~ -1.4763; csak futtatas utan rogzitendo
Értelmezés: a rekonstrukciós tag skálája csak a likelihood-varianciával együtt értelmezhető; a KL-tag bünteti a priorhoz képesti eltérést. A két tag összege alsó korlát, tehát ha az egyik tagot önkényes súllyal skálázzuk, az már nem ugyanazon marginális likelihood alsó korlátja (ez a -VAE heurisztika, amelyet nem tárgyalunk ELBO-állításként). A valós futtatás után az MC-érték abszolút tűrésnél közelebb kell legyen a zárt ELBO-hoz.
F1 (fogalmi, nehézség 1). Különböztesse meg a encoder eloszlást és a valódi posteriort. Adjon olyan -t és -t, ahol nem véges, és nevezze meg, mely támogatási feltétel sérül. Átadandó: rövid magyarázat és képletpélda.
F2 (levezetési, nehézség 2). Vezesse le a , KL-zárt alakot -re, majd számítsa ki , értéket. Átadandó: teljes levezetés és numerikus érték.
F3 (implementációs, nehézség 2). Készítsen batchelt függvényt, amely mátrixra, diagonális Gauss paraméterekkel és lineáris Gauss dekóderrel kiszámolja a zárt ELBO-t, majd MC-becsléssel ellenőrzi. Átadandó: teljes kód, shape-ellenőrzés, -es tolerancia.
F4 (hibakeresési, nehézség 2). Az alábbi sor
hibás: z = mu + logvar * eps, ahol logvar a
encoder kimenet. Azonosítsa a hibát, következményét, javítását és
empirikus ellenőrzését. Átadandó: ok, következmény, javított kód,
visszaellenőrzés.
F5 (kísérleti/transzfer, nehézség 3). Tervezzen
GlyphLab VAE-kísérletet, amely a corrupted_test
rekonstrukciós romlását párosan méri a tiszta test adathoz képest,
anélkül hogy a korrupt halmazt modellválasztásra használná. Átadandó:
protokoll a split, baseline, metrika, statisztikai egység és
következtetési határ megadásával.
F1 megoldás. A egy encoder által paraméterezett, zártan előállítható közelítő sűrűség; a a modell posteriorja, amely a Bayes-szabályból adódik, és általában nem számolható, mert integrált tartalmaz. Példa: , . Ekkor pozitív tömeget ad -en kívül, ahol ; a tag divergál, így . A véges KL feltétele az, hogy ott, ahol .
F2 megoldás. A Gauss-sűrűség logaritmusa: A szerinti várható értékben és , ezért Kivonva: A megadott értékekkel . Ellenőrzés: , a zárójeles tag , felezve .
F3 megoldás. A lineáris dekóder teljesíti alakot; a zárt várható négyzetes hiba a diagonális variancia miatt összegként bomlik.
import math, torch
torch.set_default_dtype(torch.float64)
def closed_elbo_batch(x, mu, var, W, sigma_d2):
# x: (N,D), mu: (N,K), var: (N,K), W: (K,D)
N, D = x.shape
K = mu.shape[1]
recon_const = -0.5 * D * math.log(2.0 * math.pi * sigma_d2)
mean_quad = (x - mu @ W).pow(2).sum(dim=1) # (N,)
w_norm2 = W.pow(2).sum(dim=1) # (K,)
var_quad = (var * w_norm2.unsqueeze(0)).sum(dim=1) # (N,)
recon = recon_const - (mean_quad + var_quad) / (2.0 * sigma_d2)
kl = 0.5 * (var + mu.pow(2) - 1.0 - var.log()).sum(dim=1)
return recon - kl, recon, kl
def mc_elbo_batch(x, mu, var, W, sigma_d2, S):
N, D = x.shape
N_, K = mu.shape
eps = torch.randn(N, S, K)
z = mu.unsqueeze(1) + var.unsqueeze(1).sqrt() * eps
log_pz = -0.5 * (math.log(2.0 * math.pi) + z.pow(2)).sum(-1)
log_qz = -0.5 * (torch.log(2.0 * math.pi * var.unsqueeze(1))
+ (z - mu.unsqueeze(1)).pow(2) / var.unsqueeze(1)).sum(-1)
diff = x.unsqueeze(1) - z @ W # (N,S,D)
log_px = (-0.5 * D * math.log(2.0 * math.pi * sigma_d2)
- diff.pow(2).sum(-1) / (2.0 * sigma_d2))
return (log_px + log_pz - log_qz).mean(dim=1)
x = torch.tensor([[0.4, -0.2], [0.1, 0.3]])
mu = torch.tensor([[0.2], [0.0]])
var = torch.tensor([[0.25], [1.0]])
W = torch.tensor([[1.0, -0.5]])
closed = closed_elbo_batch(x, mu, var, W, 0.16)[0]
# ellenőrzés: closed = [-1.476255, -4.224046]
torch.manual_seed(7)
mc = mc_elbo_batch(x, mu, var, W, 0.16, 100000)
print(closed)
print(mc)
assert torch.allclose(closed, mc, atol=0.02), "MC eltérés túl nagy"A második sor zárt értéke: , miatt , a rekonstrukciós tag , a KL .
F4 megoldás. A hiba oka: logvar a
,
ezért közvetlen szorzóként nem a szórást használja. A mintavételezett
eloszlása nem az a
,
amelynek KL-jét kiszámoljuk, így a gradiensbecslés inkonzisztens.
Következmény: a tényleges mintavételi variancia
lenne
helyett, ami a paramétertől függően túl nagy vagy túl kicsi is lehet
(például
esetén
a helyes
helyett). Javítás:
z = mu + torch.exp(0.5 * logvar) * epsEllenőrzés: sok eps minta után
,
például z.std(0).pow(2) és logvar.exp()
összevetése
tűréssel.
F5 megoldásminta. Adat: GlyphLab
images.npy, splitet metadata.csv
scene_id szerint megtartva; train/val/test a kezdőlabor
szerint. Modell:
látens dimenziós, konvolúciós encoder/decoder VAE; baseline: azonos
architektúra determinisztikus autoencoder. Metrika: képenkénti MSE, majd
jelenetenként a két nézet átlaga. Választás: a legjobb checkpoint
kizárólag val rekonstrukciós veszteségen. Teszt: tiszta és
corrupted_test páronként ugyanazon scene/view sorrendben; a
páros különbséget jelenetalapú cluster bootstrap intervallummal
jellemezzük, mert a független mintavételi egység a scene, nem a kép.
Következtetési határ: a korrupt hiba növekedése a betanítási tartomány
érzékenységét méri, nem általános valós képminőséget; negatív vagy nulla
eredmény is elfogadható korrekt riporttal.
A gyakori tévedés: „a VAE nem más, mint hagyományos autoencoder zajos latenssel.” Ez hiányos, mert nem mond likelihoodot. Tekintsünk két modellt, amelyek ugyanazt az encoder–decoder párt használják, és mindkettő ugyanazt a mintavételezett rekonstrukciót adja. Az egyik értékkel definiálja a likelihoodot, a másik -vel. Az MSE-optimum ugyanaz, de a rekonstrukciós tag skálája és a teljes ELBO különbözik, mert az explicit likelihood normalizáló konstansa más. Zajos latenttér önmagában nem ad generatív célfüggvényt; a VAE-t az maximalizálása és a hozzá tartozó likelihood definiálja.
Ellenőrzés: a kézi példában
KL;
ELBO;
az egymintás MC nem helyettesíti a zárt várható értéket. Kódellenőrzés:
,
szorzás W*z broadcasthellyel
-t
ad; a KL-tag a
dimenzión összegzendő. Numerikus ellenőrzés: float64,
cpu, tolerancia
–.
Visszahívás: a 29.4. Anomáliapontszám
rekonstrukcióból alfejezetben bevezetett rekonstrukciós pontszám itt
a Gauss-dekóder likelihood negatív, konstanseltolt változataként jelenik
meg; a 7.4. Numerikus stabilitás és jelentésmegőrző
implementáció log-likelihood-stabilizálást kategorikus dekódernél
kell újra elővenni.
A VAE látens változót vezet be, priorral és dekóder-likelihooddal. A posterior a marginalizáló integrál miatt általában nem zárt, ezért encoder-közelítést illesztünk. Az ELBO a Jensen-egyenlőtlenségből a alsó korlátjaként vezethető le, és felbomlik rekonstrukciós tagra és büntetőtagra. A levezetés feltétele a támogatási feltétel és az integrabilitás. A toy Gauss-példa a rekonstrukció/KL skáláját, a labor a zárt képlet és az MC-becslés viszonyát ellenőrzi.
A 31.2. GAN mint minimax probléma a GAN minimax célját mutatja be; ott az adott likelihoodú generatív cél helyett egy diszkriminátor jelenti a tanítójelet. A most megismert likelihood-, prior- és posteriorfogalom ahhoz kell, hogy a két modellcsalád feltevéseit elkülönítsük.