# Латентные модели: autoencoder и VAE > Глава выводит цели обычного autoencoder и variational autoencoder и связывает > ELBO с реконструкцией, регуляризацией и генерацией символов. ## Мотивация и интуиция Изображение глифа содержит тысячи пикселей, но его вариативность часто объясняется меньшим числом факторов: символом, наклоном, толщиной, связностью и стилем. Encoder сжимает \(\mathbf{x}\) в latent code \(\mathbf{z}\), decoder восстанавливает изображение. Узкое место заставляет хранить существенное, но само по себе не гарантирует осмысленного или гладкого пространства. Обычный autoencoder учит детерминированное преобразование и хорошо реконструирует, но пустые области latent space могут декодироваться в мусор. VAE учит распределение кодов и приближает его к prior, чтобы можно было семплировать новые объекты. Цена — часто более размытая реконструкция. ## Autoencoder Для \(\mathbf{x}\in[0,1]^d\): \[ \mathbf{z}=f_{\boldsymbol{\phi}}(\mathbf{x})\in\mathbb{R}^k,\qquad \hat{\mathbf{x}}=g_{\boldsymbol{\theta}}(\mathbf{z}). \] Цель на датасете: \[ \min_{\boldsymbol{\phi},\boldsymbol{\theta}} \frac1n\sum_{i=1}^{n} \ell(\mathbf{x}^{(i)},g_{\boldsymbol{\theta}} (f_{\boldsymbol{\phi}}(\mathbf{x}^{(i)}))). \] Для непрерывной яркости используют MSE; для Bernoulli-модели пикселей — binary cross-entropy. BCE с sigmoid соответствует отрицательному log-likelihood независимых Bernoulli pixels, но реальные antialiased pixels и их зависимости этому предположению не вполне соответствуют. Если сеть слишком мощная и \(k\) велико, она может приблизить identity. Denoising AE получает испорченный \(\tilde{\mathbf{x}}\), но восстанавливает чистый \(\mathbf{x}\); sparse/contractive варианты добавляют регуляризацию. ## Вероятностная постановка VAE Задаём prior \(p(\mathbf{z})=\mathcal{N}(\mathbf{0},\mathbf{I})\) и decoder \(p_{\boldsymbol{\theta}}(\mathbf{x}\mid\mathbf{z})\). Marginal likelihood: \[ p_{\boldsymbol{\theta}}(\mathbf{x}) =\int p_{\boldsymbol{\theta}}(\mathbf{x}\mid\mathbf{z})p(\mathbf{z})d\mathbf{z}. \] Posterior \(p(\mathbf{z}\mid\mathbf{x})\) обычно недоступен. Encoder задаёт приближение \[ q_{\boldsymbol{\phi}}(\mathbf{z}\mid\mathbf{x}) =\mathcal{N}(\boldsymbol{\mu}_{\boldsymbol{\phi}}(\mathbf{x}), \operatorname{diag}(\boldsymbol{\sigma}^2_{\boldsymbol{\phi}}(\mathbf{x}))). \] ## Вывод ELBO Вставим \(q/q\), затем применим неравенство Jensen: \[ \begin{aligned} \log p_{\boldsymbol{\theta}}(\mathbf{x}) &=\log\int q_{\boldsymbol{\phi}}(\mathbf{z}\mid\mathbf{x}) \frac{p_{\boldsymbol{\theta}}(\mathbf{x},\mathbf{z})} {q_{\boldsymbol{\phi}}(\mathbf{z}\mid\mathbf{x})}d\mathbf{z}\\ &=\log\mathbb{E}_{q_{\boldsymbol{\phi}}} \left[\frac{p_{\boldsymbol{\theta}}(\mathbf{x},\mathbf{z})}{q_{\boldsymbol{\phi}}}\right]\\ &\ge \mathbb{E}_{q_{\boldsymbol{\phi}}} \left[\log p_{\boldsymbol{\theta}}(\mathbf{x}\mid\mathbf{z})\right] -D_{\mathrm{KL}}\!\left(q_{\boldsymbol{\phi}}(\mathbf{z}\mid\mathbf{x}) \|p(\mathbf{z})\right) =\mathcal{L}_{\mathrm{ELBO}}. \end{aligned} \] Точнее, \(\log p(\mathbf{x})=\mathcal{L}_{ELBO} +D_{KL}(q(\mathbf{z}\mid\mathbf{x})\|p(\mathbf{z}\mid\mathbf{x}))\), поэтому это нижняя граница. Обучение минимизирует negative ELBO: \[ \mathcal{J}=\underbrace{-\mathbb{E}_q\log p(\mathbf{x}\mid\mathbf{z})} _{\text{reconstruction}}+ \underbrace{D_{KL}(q(\mathbf{z}\mid\mathbf{x})\|p(\mathbf{z}))} _{\text{regularization}}. \] Для diagonal Gaussian и standard normal: \[ D_{KL}=-\frac12\sum_{j=1}^k (1+\log\sigma_j^2-\mu_j^2-\sigma_j^2). \] ## Reparameterization trick Нельзя напрямую backpropagate через случайное семплирование, зависящее от \(\boldsymbol{\phi}\). Переносим случайность: \[ \boldsymbol{\varepsilon}\sim\mathcal{N}(\mathbf{0},\mathbf{I}),\qquad \mathbf{z}=\boldsymbol{\mu}+ \boldsymbol{\sigma}\odot\boldsymbol{\varepsilon}. \] Теперь \(\varepsilon\) независимо от параметров, а \(\mu,\sigma\) участвуют в дифференцируемой операции. Сеть предсказывает `logvar`, затем \(\sigma=\exp(0.5\,\mathrm{logvar})\) для положительности. ## Разобранный пример Для одного объекта \(\boldsymbol{\mu}=(1,0)\), \(\log\boldsymbol{\sigma}^2=(0,\log4)\): \[ D_{KL}=-\frac12[(1+0-1-1)+(1+\log4-0-4)] \approx1.807. \] Первое измерение платит 0.5 за сдвиг mean, второе — примерно 1.307 за variance 4. При \(\mu=0,\sigma^2=1\) вклад равен нулю. ## Runnable PyTorch-код ```python import torch from torch import nn from torch.nn import functional as F class VAE(nn.Module): def __init__(self, d=28*28, k=16): super().__init__() self.enc = nn.Sequential(nn.Linear(d, 256), nn.ReLU()) self.mu, self.logvar = nn.Linear(256, k), nn.Linear(256, k) self.dec = nn.Sequential(nn.Linear(k, 256), nn.ReLU(), nn.Linear(256, d)) def forward(self, x): h = self.enc(x) mu, logvar = self.mu(h), self.logvar(h) z = mu + torch.exp(0.5 * logvar) * torch.randn_like(mu) return self.dec(z), mu, logvar x = torch.rand(8, 28*28) model = VAE() logits, mu, logvar = model(x) recon = F.binary_cross_entropy_with_logits(logits, x, reduction="sum") / len(x) kl = (-0.5 * (1 + logvar - mu.square() - logvar.exp()).sum()) / len(x) loss = recon + kl loss.backward() print(float(recon), float(kl), mu.shape) ``` Суммирование по pixels и latent dimensions, затем деление по batch делает масштаб явным. Нельзя случайно усреднить reconstruction по всем pixels, оставив KL суммой: это радикально меняет баланс. ## Практика для рукописных глифов Делите данные по писателям, иначе модель увидит стиль test-пользователя на train. Нормализуйте canvas и baseline осторожно: чрезмерное выравнивание удалит признаки почерка. Интерполяция между двумя кодами показывает гладкость, но не доказывает disentanglement. Для conditional VAE подавайте label символа и encoder, и decoder; иначе latent обязан одновременно хранить content и style. \(\beta\)-VAE использует \(\mathcal{J}=\text{recon}+\beta KL\). Большое \(\beta\) усиливает prior и иногда disentanglement, но ухудшает детали. KL annealing и free bits помогают против posterior collapse, когда decoder игнорирует \(\mathbf{z}\). ## Типичные ошибки и ограничения - Называть AE генеративной моделью только потому, что decoder рисует: sampling distribution не определено. - Использовать sigmoid перед `binary_cross_entropy_with_logits`. - Сравнивать модели с разными reduction и масштабом loss. - Считать низкую reconstruction loss доказательством полезного latent space. - Допустить writer leakage или дубликаты глифов между split. - Интерпретировать координату latent как конкретный стиль без controlled evidence. - Хранить реальные образцы подписи: это биометрические данные и потенциальный материал для подделки. ## Краткое резюме - AE сжимает и реконструирует, но не формирует автоматически удобный prior. - VAE максимизирует ELBO: likelihood-реконструкцию минус KL к prior. - Reparameterization делает stochastic latent дифференцируемым. - Баланс reconstruction/KL, split по писателям и этика данных критичны. ## Связанные материалы - Следующая глава: [GAN и diffusion](02_gan_diffusion.md). - Термины: [glossary.md](../glossary.md).