画像生成モデルは深層学習における最も活発な研究分野の1つです。VAE(変分オートエンコーダ)、GAN(敵対的生成ネットワーク)、拡散モデル(Diffusion Model) の3つが代表的な生成モデルとして知られていますが、それぞれ異なる数学的原理に基づいており、生成品質・多様性・学習安定性・推論速度において異なるトレードオフを持ちます。
本記事では、これら3つのモデルを統一的な視点から比較し、数学的フレームワークの違い、評価指標(FID, IS)の定義と導出、各モデルの長所・短所を体系的に解説します。さらに、Python でFIDの計算を実装し、生成モデルの定量的な比較手法を示します。
本記事の内容
- 3大生成モデルの統一的な理解(学習目的・アーキテクチャ・サンプリング)
- 数学的フレームワークの比較(VAE: ELBO最大化、GAN: ミニマックス、拡散: デノイジングスコアマッチング)
- FID(Fréchet Inception Distance)の定義と計算(2つの多変量正規分布間のフレシェ距離の導出)
- IS(Inception Score)の定義
- 各モデルの長所・短所の体系的比較
- 歴史的発展の流れ
- Python で FID の計算実装と定量比較
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
3大生成モデルの統一的な理解
共通の目的
3つのモデルすべてに共通する目標は、データ分布 $p_{\text{data}}(\bm{x})$ を近似するモデル分布 $p_\theta(\bm{x})$ を学習し、$p_\theta$ からサンプリングすることで新しいデータを生成することです。
しかし、この目標に至るアプローチは大きく異なります。
VAE: 潜在変数モデルと変分推論
学習目的: 対数尤度の変分下界(ELBO)の最大化
$$ \mathcal{L}_{\text{VAE}} = \mathbb{E}_{q_\phi(\bm{z}|\bm{x})}\left[\log p_\theta(\bm{x}|\bm{z})\right] – D_{\text{KL}}(q_\phi(\bm{z}|\bm{x}) \| p(\bm{z})) $$
直感: エンコーダ $q_\phi(\bm{z}|\bm{x})$ がデータを潜在空間に圧縮し、デコーダ $p_\theta(\bm{x}|\bm{z})$ が潜在変数から再構成します。KLダイバージェンス項が事前分布 $p(\bm{z}) = \mathcal{N}(\bm{0}, \bm{I})$ への正則化を行います。
サンプリング: $\bm{z} \sim p(\bm{z})$ → $\bm{x} \sim p_\theta(\bm{x}|\bm{z})$(1ステップ)
GAN: 暗黙的生成モデルと敵対的学習
学習目的: 生成器 $G$ と識別器 $D$ のミニマックスゲーム
$$ \min_G \max_D \mathbb{E}_{p_{\text{data}}(\bm{x})}[\log D(\bm{x})] + \mathbb{E}_{p(\bm{z})}[\log(1 – D(G(\bm{z})))] $$
直感: 生成器はランダムノイズからデータを生成し、識別器は本物と偽物を見分けようとします。このゲームの均衡点(ナッシュ均衡)で $p_G = p_{\text{data}}$ が達成されます。
サンプリング: $\bm{z} \sim p(\bm{z})$ → $\bm{x} = G(\bm{z})$(1ステップ)
最適な識別器のもとでの生成器の目的関数は、Jensen-Shannon ダイバージェンスの最小化と等価です。
$$ \min_G \; 2\,D_{\text{JS}}(p_{\text{data}} \| p_G) – \log 4 $$
拡散モデル: デノイジングとスコアマッチング
学習目的: 簡略化されたデノイジング損失
$$ L_{\text{simple}} = \mathbb{E}_{t, \bm{x}_0, \bm{\epsilon}}\left[\|\bm{\epsilon} – \bm{\epsilon}_\theta(\bm{x}_t, t)\|^2\right] $$
直感: データにノイズを段階的に加える前方過程を定義し、そのノイズを除去する逆過程をニューラルネットワークで学習します。
サンプリング: $\bm{x}_T \sim \mathcal{N}(\bm{0}, \bm{I})$ → $T$ ステップの逐次デノイジング → $\bm{x}_0$($T$ ステップ)
理論的には、DDPMの損失は変分下界の一部(KLダイバージェンスの重み付き和)に対応し、スコアマッチングの観点からは
$$ \bm{\epsilon}_\theta(\bm{x}_t, t) \approx -\sqrt{1 – \bar{\alpha}_t}\,\nabla_{\bm{x}_t} \log p_t(\bm{x}_t) $$
となり、ノイズ予測はスコア関数の推定と等価です。
数学的フレームワークの比較
3つのモデルの数学的構造を統一的に整理しましょう。
確率的視点からの比較
| 特性 | VAE | GAN | 拡散モデル |
|---|---|---|---|
| 確率モデル | 明示的 | 暗黙的 | 明示的 |
| 尤度計算 | 下界(ELBO) | 不可 | 下界(ELBO) |
| 学習の最適化 | 勾配降下(安定) | ミニマックス(不安定) | 勾配降下(安定) |
| 密度推定 | 可能(近似) | 不可 | 可能(近似) |
情報理論的視点
各モデルが最小化する発散(ダイバージェンス)を比較します。
VAE: ELBO の最大化は次と等価です。
$$ -\text{ELBO} = D_{\text{KL}}(q_\phi(\bm{z}|\bm{x}) \| p(\bm{z}|\bm{x})) – \log p(\bm{x}) $$
つまり、近似事後分布と真の事後分布の KL ダイバージェンスを間接的に最小化しています。
GAN: オリジナル GAN は Jensen-Shannon ダイバージェンスを最小化します。
$$ D_{\text{JS}}(p_{\text{data}} \| p_G) = \frac{1}{2}D_{\text{KL}}\left(p_{\text{data}} \middle\| \frac{p_{\text{data}} + p_G}{2}\right) + \frac{1}{2}D_{\text{KL}}\left(p_G \middle\| \frac{p_{\text{data}} + p_G}{2}\right) $$
WGAN は Wasserstein 距離(Earth Mover’s Distance)を最小化します。
$$ W_1(p_{\text{data}}, p_G) = \inf_{\gamma \in \Pi(p_{\text{data}}, p_G)} \mathbb{E}_{(\bm{x}, \bm{y}) \sim \gamma}[\|\bm{x} – \bm{y}\|] $$
拡散モデル: 変分下界の各項は $D_{\text{KL}}(q(\bm{x}_{t-1}|\bm{x}_t, \bm{x}_0) \| p_\theta(\bm{x}_{t-1}|\bm{x}_t))$ の形で、2つのガウス分布間のKLダイバージェンスを最小化しています。
潜在変数の役割
VAE: 潜在変数 $\bm{z}$ は意味のある構造(連続的な潜在空間)を持ち、補間や属性操作が可能です。ただし、KL正則化により潜在空間が過度に平滑化される傾向があります。
GAN: 入力ノイズ $\bm{z}$ はそのまま潜在変数の役割を果たしますが、推論方向($\bm{x} \to \bm{z}$)の写像がありません。BiGAN/ALI ではエンコーダを追加しますが、これは追加のモデルが必要です。
拡散モデル: 潜在変数は $\bm{x}_1, \bm{x}_2, \dots, \bm{x}_T$ の系列全体であり、入力データと同じ次元を持ちます。これはVAEの潜在空間とは根本的に異なります。
FID(Fréchet Inception Distance)の定義と導出
定義
FID は、生成画像の品質と多様性を同時に評価する最も広く使われている指標です。Heusel et al. (2017) が提案しました。
FID は、実画像と生成画像のそれぞれを学習済み Inception ネットワークの中間層特徴に埋め込み、その特徴分布を多変量正規分布で近似した上で、2つの正規分布間のフレシェ距離(Fréchet Distance)を計算します。
Inception 特徴の抽出
学習済み Inception v3 ネットワークの pool3 層(2048次元)の出力を特徴ベクトルとして使用します。
実画像集合 $\{\bm{x}_i\}_{i=1}^N$ と生成画像集合 $\{\bm{y}_j\}_{j=1}^M$ から、それぞれの Inception 特徴を
$$ \bm{h}_i^{\text{real}} = \text{Inception}(\bm{x}_i), \quad \bm{h}_j^{\text{gen}} = \text{Inception}(\bm{y}_j) $$
として抽出し、多変量正規分布で近似します。
$$ \bm{h}^{\text{real}} \sim \mathcal{N}(\bm{\mu}_r, \bm{\Sigma}_r), \quad \bm{h}^{\text{gen}} \sim \mathcal{N}(\bm{\mu}_g, \bm{\Sigma}_g) $$
フレシェ距離の導出
2つの多変量正規分布 $\mathcal{N}(\bm{\mu}_1, \bm{\Sigma}_1)$ と $\mathcal{N}(\bm{\mu}_2, \bm{\Sigma}_2)$ 間のフレシェ距離(Wasserstein-2 距離)を導出します。
Wasserstein-2 距離の定義:
$$ W_2^2(P, Q) = \inf_{\gamma \in \Pi(P, Q)} \mathbb{E}_{(\bm{x}, \bm{y}) \sim \gamma}\left[\|\bm{x} – \bm{y}\|^2\right] $$
ここで $\Pi(P, Q)$ は $P$ と $Q$ を周辺分布とするすべての同時分布(カップリング)の集合です。
ガウス分布の場合の解析解: $P = \mathcal{N}(\bm{\mu}_1, \bm{\Sigma}_1)$、$Q = \mathcal{N}(\bm{\mu}_2, \bm{\Sigma}_2)$ の場合、最適なカップリングもガウス分布であり
$$ \gamma^* = \mathcal{N}\left(\begin{pmatrix}\bm{\mu}_1 \\ \bm{\mu}_2\end{pmatrix}, \begin{pmatrix}\bm{\Sigma}_1 & \bm{C} \\ \bm{C}^T & \bm{\Sigma}_2\end{pmatrix}\right) $$
ここで $\bm{C} = \bm{\Sigma}_1^{1/2}(\bm{\Sigma}_1^{1/2}\bm{\Sigma}_2\bm{\Sigma}_1^{1/2})^{1/2}\bm{\Sigma}_1^{-1/2}$ です。
$W_2^2$ を計算します。
$$ \begin{align} W_2^2 &= \mathbb{E}\left[\|\bm{x} – \bm{y}\|^2\right] \\ &= \mathbb{E}\left[\|\bm{x}\|^2\right] + \mathbb{E}\left[\|\bm{y}\|^2\right] – 2\mathbb{E}\left[\bm{x}^T\bm{y}\right] \\ &= (\|\bm{\mu}_1\|^2 + \text{tr}(\bm{\Sigma}_1)) + (\|\bm{\mu}_2\|^2 + \text{tr}(\bm{\Sigma}_2)) – 2(\bm{\mu}_1^T\bm{\mu}_2 + \text{tr}(\bm{C})) \end{align} $$
ここで $\mathbb{E}[\|\bm{x}\|^2] = \|\bm{\mu}_1\|^2 + \text{tr}(\bm{\Sigma}_1)$(分散の定義)、$\mathbb{E}[\bm{x}^T\bm{y}] = \bm{\mu}_1^T\bm{\mu}_2 + \text{tr}(\bm{C})$ を用いました。
$$ \begin{align} W_2^2 &= \|\bm{\mu}_1 – \bm{\mu}_2\|^2 + \text{tr}(\bm{\Sigma}_1) + \text{tr}(\bm{\Sigma}_2) – 2\text{tr}(\bm{C}) \end{align} $$
$\bm{C}$ のトレースを計算します。$\text{tr}(\bm{C}) = \text{tr}((\bm{\Sigma}_1^{1/2}\bm{\Sigma}_2\bm{\Sigma}_1^{1/2})^{1/2})$ です。これは $(\bm{\Sigma}_1 \bm{\Sigma}_2)^{1/2}$ のトレースに等しいことが示せます(トレースの巡回性)。
$$ \text{tr}(\bm{C}) = \text{tr}\left((\bm{\Sigma}_1^{1/2}\bm{\Sigma}_2\bm{\Sigma}_1^{1/2})^{1/2}\right) = \text{tr}\left((\bm{\Sigma}_1\bm{\Sigma}_2)^{1/2}\right) $$
最終的にFIDの公式を得ます。
$$ \boxed{\text{FID} = \|\bm{\mu}_r – \bm{\mu}_g\|^2 + \text{tr}\left(\bm{\Sigma}_r + \bm{\Sigma}_g – 2(\bm{\Sigma}_r\bm{\Sigma}_g)^{1/2}\right)} $$
FIDが0に近いほど、生成画像の品質と多様性が実画像に近いことを意味します。
FIDの各項の解釈
- $\|\bm{\mu}_r – \bm{\mu}_g\|^2$: 平均の差。生成画像全体の「見た目」が実画像とどれだけ異なるか。
- $\text{tr}(\bm{\Sigma}_r + \bm{\Sigma}_g – 2(\bm{\Sigma}_r\bm{\Sigma}_g)^{1/2})$: 共分散の差。生成画像の多様性が実画像とどれだけ異なるか。
IS(Inception Score)の定義
IS は Salimans et al. (2016) が提案した生成画像の品質指標です。
$$ \text{IS} = \exp\left(\mathbb{E}_{\bm{x} \sim p_g}\left[D_{\text{KL}}(p(y|\bm{x}) \| p(y))\right]\right) $$
ここで $p(y|\bm{x})$ は Inception ネットワークによるクラス条件付き分布、$p(y) = \mathbb{E}_{\bm{x}}[p(y|\bm{x})]$ は周辺クラス分布です。
ISが高いほど良い生成モデルとされ、以下の2条件を評価します。
- 品質: 各生成画像が特定のクラスに自信を持って分類される → $p(y|\bm{x})$ のエントロピーが低い
- 多様性: 生成画像全体が多くのクラスにまたがる → $p(y)$ のエントロピーが高い
これら2条件が同時に満たされるとき、$D_{\text{KL}}(p(y|\bm{x}) \| p(y))$ が大きくなり、ISが高くなります。
ISの限界
- 実画像との比較を行わない(生成画像のみで計算)
- ImageNet の1000クラスに偏ったバイアスがある
- モード崩壊を十分に検出できない場合がある
これらの理由からFIDの方がより信頼性の高い指標として広く使われています。
各モデルの長所・短所の体系的比較
比較表
| 特性 | VAE | GAN | 拡散モデル |
|---|---|---|---|
| サンプル品質 | 中(ぼやけやすい) | 高 | 最高 |
| 多様性 | 高 | 中(モード崩壊) | 高 |
| 学習安定性 | 高(安定) | 低(不安定) | 高(安定) |
| 尤度計算 | 可能(ELBO) | 不可 | 可能(ELBO) |
| 推論速度 | 高速(1ステップ) | 高速(1ステップ) | 低速($T$ステップ) |
| 潜在空間 | 構造的 | 非構造的 | なし(同次元) |
| モード被覆 | 良い | 悪い場合あり | 良い |
各項目の詳細
サンプル品質: VAEは再構成損失(MSEやBCE)を使うため、生成画像がぼやける傾向があります。これは $p_\theta(\bm{x}|\bm{z})$ がガウス分布の場合、複数のモードの平均的な画像を生成するためです。GANは敵対的学習により鮮明な画像を生成しますが、トレードオフとして多様性が犠牲になることがあります。拡散モデルは段階的なデノイジングにより高品質かつ多様な画像を生成でき、FIDスコアで最高性能を達成しています。
モード崩壊: GANは生成器が識別器を「騙す」ために特定のモード(パターン)のみを生成する「モード崩壊」が発生しやすいです。VAEと拡散モデルは尤度ベースの学習であるため、モード被覆が良好です。
数学的に、これはKLダイバージェンスの非対称性と関係します。VAEが最小化する $D_{\text{KL}}(q \| p)$ はモード被覆(mean-seeking)の特性を持ち、GANが最小化する $D_{\text{JS}}$ はモード崩壊に寄与する可能性があります。
推論速度: VAEとGANは1回のフォワードパスで生成できるのに対し、拡散モデルは $T$(典型的に1000)ステップの逐次デノイジングが必要です。DDIM(Song et al., 2021)やDPM-Solver(Lu et al., 2022)などの加速手法により$T$を数十ステップまで削減できますが、1ステップの手法に比べると依然として遅いです。
歴史的発展の流れ
VAEの系譜
| 年 | モデル | 主な貢献 |
|---|---|---|
| 2013 | VAE (Kingma & Welling) | 変分推論 + 再パラメータ化トリック |
| 2015 | CVAE | 条件付き生成 |
| 2016 | VQ-VAE | 離散潜在変数 |
| 2020 | VQ-VAE-2 | 階層的離散潜在変数 |
GANの系譜
| 年 | モデル | 主な貢献 |
|---|---|---|
| 2014 | GAN (Goodfellow et al.) | 敵対的学習の枠組み |
| 2015 | DCGAN | 畳み込みアーキテクチャ |
| 2017 | WGAN | Wasserstein距離 |
| 2018 | Progressive GAN | 段階的高解像度化 |
| 2019 | StyleGAN | スタイルベース生成 |
| 2020 | StyleGAN2 | パス長正則化 |
拡散モデルの系譜
| 年 | モデル | 主な貢献 |
|---|---|---|
| 2015 | Deep Unsupervised Learning (Sohl-Dickstein et al.) | 拡散過程の概念 |
| 2019 | NCSN (Song & Ermon) | スコアベース生成モデル |
| 2020 | DDPM (Ho et al.) | 簡略化損失関数 |
| 2021 | Score SDE (Song et al.) | SDEフレームワーク |
| 2021 | DDIM (Song et al.) | 非マルコフサンプリング |
| 2021 | Guided Diffusion (Dhariwal & Nichol) | 分類器ガイダンス |
| 2022 | Stable Diffusion (Rombach et al.) | 潜在空間拡散 |
Pythonでの実装
FIDの計算を NumPy で実装し、合成データを用いて3つの生成モデルの出力を疑似的に定量比較します。
import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg
np.random.seed(42)
# --- FID計算の実装 ---
def compute_fid(mu1, sigma1, mu2, sigma2):
"""
2つの多変量正規分布間のFréchet Inception Distance (FID) を計算
FID = ||mu1 - mu2||^2 + tr(sigma1 + sigma2 - 2*(sigma1 @ sigma2)^{1/2})
"""
# 平均の差のノルム二乗
diff = mu1 - mu2
mean_term = np.dot(diff, diff)
# 行列平方根の計算
# sigma1 @ sigma2 の行列平方根
product = sigma1 @ sigma2
# scipy.linalg.sqrtm で行列平方根を計算
sqrt_product, _ = linalg.sqrtm(product, disp=False)
# 数値誤差で虚数部が出る場合があるため実部のみ取る
if np.iscomplexobj(sqrt_product):
sqrt_product = sqrt_product.real
# トレース項
trace_term = np.trace(sigma1 + sigma2 - 2.0 * sqrt_product)
fid = mean_term + trace_term
return fid
def compute_statistics(features):
"""特徴量の平均と共分散を計算"""
mu = np.mean(features, axis=0)
sigma = np.cov(features, rowvar=False)
return mu, sigma
# --- 合成データで3つのモデルを模擬 ---
# 実データの特徴分布(ターゲット)
d = 64 # 特徴次元(実際のFIDは2048次元)
n_samples = 5000
# 実データの統計量
mu_real = np.random.randn(d) * 0.5
A_real = np.random.randn(d, d) * 0.3
sigma_real = A_real @ A_real.T + np.eye(d) * 0.1
# 実データからのサンプル
real_features = np.random.multivariate_normal(mu_real, sigma_real, n_samples)
# --- VAE模擬: 平均は近いが分散が小さい(ぼやけた生成) ---
mu_vae = mu_real + np.random.randn(d) * 0.1
sigma_vae = sigma_real * 0.6 + np.eye(d) * 0.05 # 分散が小さい
vae_features = np.random.multivariate_normal(mu_vae, sigma_vae, n_samples)
# --- GAN模擬: 一部の分散が非常に小さい(モード崩壊) ---
mu_gan = mu_real + np.random.randn(d) * 0.05 # 平均は近い
sigma_gan = sigma_real.copy()
# 一部の次元の分散を大幅に縮小(モード崩壊を模擬)
for i in range(0, d, 4):
sigma_gan[i, :] *= 0.1
sigma_gan[:, i] *= 0.1
sigma_gan[i, i] = max(sigma_gan[i, i], 0.01)
sigma_gan = (sigma_gan + sigma_gan.T) / 2 + np.eye(d) * 0.01
gan_features = np.random.multivariate_normal(mu_gan, sigma_gan, n_samples)
# --- 拡散モデル模擬: 平均も分散も近い ---
mu_diff = mu_real + np.random.randn(d) * 0.02
sigma_diff = sigma_real * 0.95 + np.eye(d) * 0.02
diff_features = np.random.multivariate_normal(mu_diff, sigma_diff, n_samples)
# --- FID計算 ---
mu_r, sig_r = compute_statistics(real_features)
mu_v, sig_v = compute_statistics(vae_features)
fid_vae = compute_fid(mu_r, sig_r, mu_v, sig_v)
mu_g, sig_g = compute_statistics(gan_features)
fid_gan = compute_fid(mu_r, sig_r, mu_g, sig_g)
mu_d, sig_d = compute_statistics(diff_features)
fid_diff = compute_fid(mu_r, sig_r, mu_d, sig_d)
print(f"FID (VAE): {fid_vae:.2f}")
print(f"FID (GAN): {fid_gan:.2f}")
print(f"FID (Diffusion): {fid_diff:.2f}")
# --- IS(簡易版)の計算 ---
def compute_is(class_probs, n_splits=10):
"""
Inception Score の計算(簡易版)
IS = exp(E[KL(p(y|x) || p(y))])
"""
n = len(class_probs)
split_size = n // n_splits
scores = []
for i in range(n_splits):
part = class_probs[i * split_size:(i + 1) * split_size]
# 周辺分布 p(y)
p_y = np.mean(part, axis=0)
# KL divergence
kl = part * (np.log(part + 1e-10) - np.log(p_y + 1e-10))
kl = np.sum(kl, axis=1)
scores.append(np.exp(np.mean(kl)))
return np.mean(scores), np.std(scores)
# 疑似的なクラス確率(10クラス)
n_classes = 10
# VAE: 多様だがやや不明瞭
vae_probs = np.random.dirichlet(np.ones(n_classes) * 2.0, n_samples)
# 少しクラスを明確にする
for i in range(n_samples):
top = np.random.randint(n_classes)
vae_probs[i, top] += 1.0
vae_probs[i] /= vae_probs[i].sum()
# GAN: 明確だが多様性が低い
gan_probs = np.random.dirichlet(np.ones(n_classes) * 0.1, n_samples)
# 特定クラスに集中(モード崩壊)
for i in range(n_samples):
top = i % 5 # 5クラスにしか生成しない
gan_probs[i, top] += 5.0
gan_probs[i] /= gan_probs[i].sum()
# 拡散モデル: 明確かつ多様
diff_probs = np.random.dirichlet(np.ones(n_classes) * 0.3, n_samples)
for i in range(n_samples):
top = i % n_classes # 全クラスにまたがる
diff_probs[i, top] += 3.0
diff_probs[i] /= diff_probs[i].sum()
is_vae, is_vae_std = compute_is(vae_probs)
is_gan, is_gan_std = compute_is(gan_probs)
is_diff, is_diff_std = compute_is(diff_probs)
print(f"\nIS (VAE): {is_vae:.2f} ± {is_vae_std:.2f}")
print(f"IS (GAN): {is_gan:.2f} ± {is_gan_std:.2f}")
print(f"IS (Diffusion): {is_diff:.2f} ± {is_diff_std:.2f}")
# --- 可視化 ---
fig, axes = plt.subplots(1, 3, figsize=(18, 5))
# FID比較
models = ['VAE', 'GAN', 'Diffusion']
fids = [fid_vae, fid_gan, fid_diff]
colors = ['#3498db', '#e74c3c', '#2ecc71']
axes[0].bar(models, fids, color=colors)
axes[0].set_ylabel('FID (lower is better)')
axes[0].set_title('FID Comparison')
for i, v in enumerate(fids):
axes[0].text(i, v + 0.5, f'{v:.1f}', ha='center', fontsize=12)
# IS比較
iss = [is_vae, is_gan, is_diff]
is_stds = [is_vae_std, is_gan_std, is_diff_std]
axes[1].bar(models, iss, yerr=is_stds, color=colors, capsize=5)
axes[1].set_ylabel('IS (higher is better)')
axes[1].set_title('Inception Score Comparison')
# 特徴空間の2D射影(PCA)
from numpy.linalg import svd
all_feats = np.vstack([real_features, vae_features, gan_features, diff_features])
mean_all = all_feats.mean(axis=0)
centered = all_feats - mean_all
U, S, Vt = svd(centered, full_matrices=False)
proj = centered @ Vt[:2].T
n = n_samples
axes[2].scatter(proj[:n, 0], proj[:n, 1], s=1, alpha=0.3, c='gray', label='Real')
axes[2].scatter(proj[n:2*n, 0], proj[n:2*n, 1], s=1, alpha=0.3, c='blue', label='VAE')
axes[2].scatter(proj[2*n:3*n, 0], proj[2*n:3*n, 1], s=1, alpha=0.3, c='red', label='GAN')
axes[2].scatter(proj[3*n:, 0], proj[3*n:, 1], s=1, alpha=0.3, c='green', label='Diffusion')
axes[2].legend(markerscale=5)
axes[2].set_title('Feature Space (PCA 2D)')
axes[2].set_xlabel('PC1')
axes[2].set_ylabel('PC2')
plt.tight_layout()
plt.show()
上のコードでは、合成データを用いて FID と IS を計算し、3つのモデルの特性を定量的に比較しました。FID は拡散モデルが最も低く(最良)、IS も拡散モデルが高いことが確認できます。GAN は FID ではそこそこの値を示しますが、モード崩壊により IS が制限されています。
FIDの行列平方根の計算について
FIDの計算で最も技術的に重要なのは、$(\bm{\Sigma}_r \bm{\Sigma}_g)^{1/2}$ の計算です。一般に $\bm{\Sigma}_r \bm{\Sigma}_g$ は対称行列とは限らないため、固有値分解ではなく Schur 分解を用いた行列平方根の計算(scipy.linalg.sqrtm)が必要です。
ただし、$\bm{\Sigma}_r$ と $\bm{\Sigma}_g$ がともに正定値対称行列であれば、以下の計算が安定です。
$$ (\bm{\Sigma}_r \bm{\Sigma}_g)^{1/2} = \bm{\Sigma}_r^{1/2}(\bm{\Sigma}_r^{1/2}\bm{\Sigma}_g\bm{\Sigma}_r^{1/2})^{1/2}\bm{\Sigma}_r^{-1/2} $$
ここで $(\bm{\Sigma}_r^{1/2}\bm{\Sigma}_g\bm{\Sigma}_r^{1/2})$ は対称正定値なので、固有値分解で安全に平方根を取れます。
まとめ
本記事では、VAE・GAN・拡散モデルの3大生成モデルを統一的に比較しました。
- VAE は ELBO 最大化で安定に学習でき尤度計算が可能だが、生成画像がぼやけやすい
- GAN はミニマックスゲームにより鮮明な画像を生成するが、学習が不安定でモード崩壊のリスクがある
- 拡散モデル はデノイジングスコアマッチングにより高品質・高多様性の生成を実現するが、推論が遅い
- FID は $\|\bm{\mu}_r – \bm{\mu}_g\|^2 + \text{tr}(\bm{\Sigma}_r + \bm{\Sigma}_g – 2(\bm{\Sigma}_r\bm{\Sigma}_g)^{1/2})$ で計算され、品質と多様性を同時評価する
- IS は生成画像のクラス分類の鮮明さと多様性を $D_{\text{KL}}(p(y|\bm{x}) \| p(y))$ の期待値で測定する
次のステップとして、以下の記事も参考にしてください。