深層生成モデルを巡る旅(2): VAE

# はじめに
深層生成モデルを巡る旅をしています。
[前回](https://qiita.com/shionhonda/items/0fb7f91a150dff604cc5)はFlowについて理論と各種法の簡単な紹介をしました. 
今回はまた別の深層生成モデルとして **変分自己符号化器 (VAE; variational autoencoder)** [1] を紹介します. 
VAEはGANに比べて安定した学習ができ, Flowと異なり潜在変数を低次元に落とすことができるので, その扱いやすさや解釈性から好まれることが多いように感じます. 一方で, 生成画像がぼやけがちである, 尤度の計算ができないといった欠点もあります. 
この1ヶ月くらいVAEについていろいろと調べてみましたが, GANやFlowのようなモデル乱立状態にはなっていなさそうだったので, 主要な手法を少し詳しめに紹介できればと思います. 

# VAEの基本
最初に, 本記事を読むのに必要な事項をまとめます. 
## 全体像
式での説明は少々長いので, 先にMNISTの画像を扱う例で全体像を示します. 

![vae.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/b170929b-8577-e1f7-12db-fa05df18deac.png)

VAEはEncoderとDecoderという2つのネットワークからなり, 名前の通りautoencoderのような構造をしています. しかし, 出自は変分推論でautoencoderとは全く異なるものなので, 以降はBayes流で説明します. 
潜在変数$\boldsymbol{z}$は, 我々が観測している画像の背後にあるシードのようなもので, 「どの数字か」「筆跡」「線の太さ」といったものを示す低次元の変数です. 多様体仮説によれば, MNISTの画像は28x28で784次元ですが, 実際にはデータは高次元空間のごく一部に分布していて, 情報を落とさずに低次元の空間に埋め込むことが可能です.
詳しくは立ち入りませんが, **グラフィカルモデル**で表すと次のような関係になっています. 

<img width="419" alt="2019-10-30-13-51-55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/b984a92e-8a1e-0dc6-e221-f55b50d527d8.png">

## 目的関数の導出
潜在変数$\boldsymbol{z}$からデータ$\boldsymbol{x}$（通常画像など高次元）を生成する確率的なDecoderを$p(\boldsymbol{x}|\boldsymbol{z})$で表します. DecoderはCNNなどで構成され, パラメータ$\boldsymbol{\theta}$を明示して$p_{\theta}(\boldsymbol{x}|\boldsymbol{z})$と表すこともあります. 
VAEも, 前回のFlowと同様に最尤推定で$\boldsymbol{\theta}$を決めるために（対数）尤度の最大化を目指しますが, 一般にデータ$\boldsymbol{x}$の分布は複雑で$p(\boldsymbol{x})$を直接求めることは難しいです. また, 事後分布$p(\boldsymbol{z}|\boldsymbol{x})$を使って式変形をしようとしても, 「データ$\boldsymbol{x}$を生成するような潜在変数$\boldsymbol{z}$を求める操作」はNNの逆変換となり難しいです. 
これを解決するために, **近似事後分布** $q(\boldsymbol{z}|\boldsymbol{x})$を導入します. これは確率的なEncoderであり, パラメータ$\boldsymbol{\phi}$を持つCNNとして$q_{\phi}(\boldsymbol{z}|\boldsymbol{x})$と表すこともあります. 
それでは式変形をしていきます. 

```math
\begin{eqnarray}
\log{p(\boldsymbol{x})} &=& \log{p(\boldsymbol{x})} \int q(\boldsymbol{z}|\boldsymbol{x})\mathrm{d}\boldsymbol{z}\\
&=& \int q(\boldsymbol{z}|\boldsymbol{x})\log\frac{p(\boldsymbol{z}|\boldsymbol{x})p(\boldsymbol{x})}{p(\boldsymbol{z}|\boldsymbol{x})}\mathrm{d}\boldsymbol{z}\\
&=& \int q(\boldsymbol{z}|\boldsymbol{x})\log\frac{p(\boldsymbol{x},\boldsymbol{z})}{p(\boldsymbol{z}|\boldsymbol{x})}\mathrm{d}\boldsymbol{z}\\
&=& \int q(\boldsymbol{z}|\boldsymbol{x}) \biggl( \log\frac{q(\boldsymbol{z}|\boldsymbol{x})}{p(\boldsymbol{z}|\boldsymbol{x})} + \log\frac{p(\boldsymbol{x},\boldsymbol{z})}{q(\boldsymbol{z}|\boldsymbol{x})} \biggr) \mathrm{d}\boldsymbol{z}\\
&=& D_{KL}[q(\boldsymbol{z}|\boldsymbol{x})||p(\boldsymbol{z}|\boldsymbol{x})] + \mathcal{L}(\boldsymbol{x},\boldsymbol{z})
\end{eqnarray}
```

ここで, 右辺第2項の$\mathcal{L}(\boldsymbol{x},\boldsymbol{z})$は **変分下限 (variational lower bound)** または **ELBO (evidence lower bound)** と呼ばれ, 次式で定義されます. 

$$
\mathcal{L}(\boldsymbol{x},\boldsymbol{z}) := \int q(\boldsymbol{z}|\boldsymbol{x}) \log\frac{p(\boldsymbol{x},\boldsymbol{z})}{q(\boldsymbol{z}|\boldsymbol{x})} \mathrm{d}\boldsymbol{z}
$$

右辺第1項は事後分布を含むため計算が困難ですが, KLダイバージェンスなので次の不等式が成り立ちます（c.f. [イェンセンの不等式](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%82%A7%E3%83%B3%E3%82%BB%E3%83%B3%E3%81%AE%E4%B8%8D%E7%AD%89%E5%BC%8F). 等号は$q(\boldsymbol{z}|\boldsymbol{x})$の近似性能が十分なときに成立します）. 

$$
D_{KL}[q(\boldsymbol{z}|\boldsymbol{x})||p(\boldsymbol{z}|\boldsymbol{x})] \geq 0
$$

したがって, 次のように対数尤度をELBOで下から抑えることができます. 

$$
\log{p(\boldsymbol{x})} \geq \mathcal{L}(\boldsymbol{x},\boldsymbol{z})
$$

ELBOはさらに分解することができます. 

```math
\begin{eqnarray}
\mathcal{L}(\boldsymbol{x},\boldsymbol{z}) &=& \int q(\boldsymbol{z}|\boldsymbol{x}) \log\frac{p(\boldsymbol{x},\boldsymbol{z})}{q(\boldsymbol{z}|\boldsymbol{x})} \mathrm{d}\boldsymbol{z}\\

&=& \int q(\boldsymbol{z}|\boldsymbol{x}) \log p(\boldsymbol{x}|\boldsymbol{z}) \mathrm{d}\boldsymbol{z} - \int q(\boldsymbol{z}|\boldsymbol{x}) \log\frac{q(\boldsymbol{z}|\boldsymbol{x})}{p(\boldsymbol{z})} \mathrm{d}\boldsymbol{z}\\

&=&\mathbb{E}_{q(\boldsymbol{z}|\boldsymbol{x})}[\log p(\boldsymbol{x}|\boldsymbol{z}) ] - D_{KL}[q(\boldsymbol{z}|\boldsymbol{x})||p(\boldsymbol{z})]\\
\end{eqnarray}
```

VAEの学習では, この目的関数を最大化するようにパラメータ$\theta, \phi$を選びます. 

## 目的関数の意味と計算方法
いま導出した目的関数の第1項は, データ$\boldsymbol{x}$を$q_{\phi}(\boldsymbol{z}|\boldsymbol{x})$でエンコードした$\boldsymbol{z}$を$p_{\theta}(\boldsymbol{x}|\boldsymbol{z})$でデコードしたときの再構成誤差で, これがAutoencoderと呼ばれる所以です. 実際, $q(\boldsymbol{z}|\boldsymbol{x})$を正規分布とすれば, 期待値の計算をバッチ内の平均で近似して, 

```math
\begin{eqnarray}
\mathbb{E}_{q(\boldsymbol{z}|\boldsymbol{x})}[\log p(\boldsymbol{x}|\boldsymbol{z}) ] 
&\simeq& \frac{1}{B}\sum_{b=1}^B \log p(\boldsymbol{x}_b|\boldsymbol{z}_b)\\
\boldsymbol{z}_b &\sim& \mathcal{N}(\mu(\boldsymbol{x}_b), \Sigma(\boldsymbol{x}_b))
\end{eqnarray}
```

と求めることができます. 
$\mu(\boldsymbol{x}\_b), \Sigma(\boldsymbol{x}\_b)$はエンコーダ$q_{\phi}(\boldsymbol{z}|\boldsymbol{x})$の出力で, それぞれ多変量正規分布の平均と分散（共分散は0）を表します. $\log p(\boldsymbol{x}_b|\boldsymbol{z}_b)$の部分の計算は, Bernoulli分布や正規分布を仮定して, それぞれ交差エントロピーや平均二乗誤差の最小化に置き換えて行います. 

目的関数の第2項は, 事前分布の正則化を担います. すなわち, データ$\boldsymbol{x}$を$q_{\phi}(\boldsymbol{z}|\boldsymbol{x})$でエンコードした$\boldsymbol{z}$が事前分布（標準正規分布）に従うように, KLダイバージェンスを最小化します. 正規分布同士のKLダイバージェンスは解析的に求まります. 

```math
\begin{eqnarray}
D_{KL}[q(\boldsymbol{z}|\boldsymbol{x})||p(\boldsymbol{z})] &=& D_{KL}[\mathcal{N}(\mu(\boldsymbol{x}), \Sigma(\boldsymbol{x})) || \mathcal{N}(\boldsymbol{0},\boldsymbol{I})]\\
&=&\frac{1}{2} \Bigl( \mathrm{tr}~ \Sigma(\boldsymbol{x}) + \mu(\boldsymbol{x})^{\mathrm{T}}\mu(\boldsymbol{x}) - d - \log{\det \Sigma(\boldsymbol{x})} \Bigr)
\end{eqnarray}
```

$d$は潜在変数$\boldsymbol{z}$の次元数です. 導出は[6]が詳しいです. 



## Reparametrization Trick
さて, 以上の定式化を踏まえてVAEの図をもう一度眺めてみましょう. . 

![vae.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/b170929b-8577-e1f7-12db-fa05df18deac.png)

このままでは誤差逆伝搬でVAEを学習させることができません. なぜなら, $\boldsymbol{z}$をサンプリングする操作は微分不可能であり, それより前のEncoder側に勾配を伝えることができないからです. 
そこで, **reparametrization trick**という方法でこの問題を回避します. これは, $\boldsymbol{z}$の代わりに標準正規分布から$\epsilon$をサンプリングし, これを使って$\boldsymbol{z}$を構成するという方法です. 

```math
\begin{eqnarray}
\boldsymbol{z} &=& \mu(\boldsymbol{x}) + \epsilon \odot \Sigma(\boldsymbol{x})\\
\epsilon &\sim& \mathcal{N}(\boldsymbol{0},\boldsymbol{I})
\end{eqnarray}
```

![vae2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/71ac7108-53c2-47d8-98c8-97a114ad2d60.png)


これで, Encoder側にも勾配が伝わるようになりました. 

これまでの流れを一旦まとめます. 

1. 対数尤度を直接最大化するのは難しいため, 近似事後分布$q(\boldsymbol{z}|\boldsymbol{x})$を導入してELBO（変分下限）の最大化に帰着
2. ELBOを再構成誤差と正則化項に分解し, 計算可能な形にする
3. 誤差逆伝搬を可能にするためReparametrization Trickを用いる

# 様々なVAE
それでは, 様々なVAE（といっても5種類ですが）を紹介していきます.

### "Vanilla" VAE [Kingma+, 2013]
元祖VAEは, ここまでで説明したVAEを3層MLPというシンプルなモデルで実装しました. 潜在変数$\boldsymbol{z}$を2次元にして, $\boldsymbol{z}$を動かしたときにDecoderから得られた画像$\boldsymbol{x}$を並べると, 数字が連続的に変化していく様子が見て取れます. 

<img width="419" alt="2019-10-30-13-51-55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/52d4183c-16f6-d874-a629-ca76e00c835d.png">
[Auto-Encoding Variational Bayes](https://arxiv.org/abs/1312.6114)

### Conditional VAE　[Kingma+, 2014]
MNISTの例で言うと, 生成時にランダムなサンプルではなく「0」の数字だけを生成したい, といったケースがあると思います. これに応えられるように, EncoderとDecoderをラベル$y$で条件付けたのが**Conditional VAE (CVAE)** です. 

```math
\mathcal{L}(\boldsymbol{x},\boldsymbol{z},y) =\mathbb{E}_{q(\boldsymbol{z}|\boldsymbol{x},y)}[\log p(\boldsymbol{x}|\boldsymbol{z},y) ] - D_{KL}[q(\boldsymbol{z}|\boldsymbol{x},y)||p(\boldsymbol{z}|y)]\\
```

潜在変数とラベルをDecoderに入力することで, 「2」「3」のようにラベルを指定した生成ができるようになります. このとき, ラベルの情報は潜在変数から取り除かれ, 筆跡や線の太さを表すようになります.

<img width="500" alt="2019-10-30-14-02-42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/4f794b6d-404a-350d-55af-fbb1db012db8.png">
[Semi-Supervised Learning with Deep Generative Models](https://arxiv.org/abs/1406.5298)

### β-VAE [Higgins+, 2017]
少し時間が空いてしまいますが, 画像特徴の"**disentanglement**"に注目したのが**β-VAE**です. 
disentangleは「もつれを解く」という意味で, 画像の特徴が潜在空間上で分離されていることを表します. 具体的には, 顔の画像に対して潜在変数の1次元目が顔の向きを, 2次元目が表情を…というように各次元がそれぞれ独立な特徴を担当している状態を想像してください. これができると, 生成された顔画像の向きを調節したければ潜在変数の1次元目を調節すれば良い, ということがわかって生成モデルとして扱いやすくなります. 
β-VAEは, 目的関数の正則化項に係数$\beta (> 1)$を導入するというシンプルな変更により, 特徴のdisentanglementを実現しました. 

```math
\mathcal{L}(\boldsymbol{x},\boldsymbol{z}) =\mathbb{E}_{q(\boldsymbol{z}|\boldsymbol{x})}[\log p(\boldsymbol{x}|\boldsymbol{z}) ] - \beta D_{KL}[q(\boldsymbol{z}|\boldsymbol{x})||p(\boldsymbol{z})]\\
```

係数$\beta (> 1)$で正則化項の寄与を大きくすることで, 潜在変数が標準正規分布に従うようにするための制約を強めています. 
下図は, 64x64のCelebAで訓練したCNNベースのVAEで, 潜在変数の1次元のみを変化させたときの生成画像を並べたものです. VAEでは向き（上段）や表情（下段）以外の要素（眼鏡や髪の色）も変わっているのに対し, β-VAEではその要素以外は保存されています. 

<img width="428" alt="2019-10-30-14-15-55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/e298763e-91b0-c657-5606-1e50fb22ac92.png">
[beta-VAE: Learning Basic Visual Concepts with a Constrained Variational Framework](https://openreview.net/forum?id=Sy2fzU9gl)

しかし, 係数$\beta$を大きくしすぎると再構成誤差が大きくなることが報告されていて, そこのトレードオフが課題です. 
なお, 特徴のdisentanglementについては[8]が詳しいです. 

### Vector Quantised-VAE [van den Oord+, 2017]
「自然界の様々な事物は離散的に表現され得る」（言語は離散的ですし, 画像も離散的な言語によって記述され得ます. 生物の潜在変数とも言えるDNAも離散的ですね！）という発想から, 潜在変数を離散値にしたのが**Vector Quantised-VAE (VQ-VAE)** です. 

<img width="493" alt="2019-10-30-15-07-21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/b0f2b268-1e12-3a58-d4f7-92ca7272f11e.png">

VQ-VAEでは, 埋め込み$\boldsymbol{z}\_e$を丸めるために**コードブック**$E = \\{\boldsymbol{e}\_k \in \mathbb{R}^D|k=1,...,K\\}$を用意します. 上図のように, Encoderから出力された特徴マップ$\boldsymbol{z}\_e \in \mathbb{R}^{H\times W\times D}$に対して, 各$\boldsymbol{z}\_e(i,j,:)$をコードブックの最近傍コード$\boldsymbol{e}\_k$で置き換え, $\boldsymbol{z}\_q\in \mathbb{R}^{H\times W\times D}$とします. また, 最近傍コード$\boldsymbol{e}\_k$のインデックス$k$を並べたものを, 離散化された潜在変数$\boldsymbol{z} \in \mathbb{Z}^{H \times W}$とします. Decoderは$\boldsymbol{z}_q$から画像$\boldsymbol{x}$を再構成します. このとき, 近似事後分布は$K$個のコードから最近傍コードを選ぶone-hotな分布となります. 

```math
q(\boldsymbol{z}(i,j)=k|\boldsymbol{x})=
\begin{cases}
1 & (\text{if}~k=\mathrm{argmin}_l\|\boldsymbol{z}_e(i,j,:)-\boldsymbol{e}_l\|_2)\\
0 &(\text{otherwise})
\end{cases}
```

式で書くとややこしいですが, 図の水色の部分のように 最近傍コードの番号を選ぶだけです.
ちなみに, ImageNetの128x128の画像の実験では, 特徴マップは$\boldsymbol{z}_e , \boldsymbol{z}_q \in \mathbb{R}^{32\times 32\times 1}$で, コードブックは$K=512$個のコードからなります. 

VQ-VAEの学習中には, 事前分布$p(\boldsymbol{z})$は**一様分布で固定します**. 学習が終わったら, 事前分布を自己回帰モデルの一種であるPixelCNNで学習させます. 

次に, 目的関数についてです. VQ-VAEは近似事後分布がone-hotで, かつ事前分布が一様分布であるため, 学習中はKLダイバージェンスの項が一定となり, 無視できます（詳しくは[9]）. 
最終的に目的関数は, 再構成誤差と, $\boldsymbol{z}_e$とコードブックの差を埋めるための項からなります. 

```math
\mathcal{L} = \mathbb{E}_{q(\boldsymbol{z}|\boldsymbol{x})}[\log p(\boldsymbol{x}|\boldsymbol{z}_q) ] +
\|\text{sg}[\boldsymbol{z}_e] - \boldsymbol{e}_k\|_2^2+ 
\beta \|\boldsymbol{z}_e - \text{sg}[\boldsymbol{e}_k]\|_2^2
```

$\text{sg}[\cdot]$は, 誤差逆伝播時に勾配を計算しないようにする処理です. 
（最近傍コードを選ぶ操作は微分不可能ですが, これでEncoderまで勾配を伝えられる理由が納得できていません. 詳しい方がいらっしゃったら教えてください. ）

以上の工夫により, VAEで起きやすいと指摘されていた**posterior collapse** を解決できたそうです. posterior collapseは, PixelCNNのような強いDecoderを使うときに潜在変数を無視した生成が行われてしまうという現象です.
なお, posterior collapseに関しては, VQ-VAEチームのRazaviらが2019年に[**δ-VAE**](https://arxiv.org/abs/1901.03416)を提案しています. 

ImageNetの128x128の画像の生成に成功しました. 
――と言われても, これらの画像は鮮明ではありますが, 大域的な特徴が掴めておらず, 何を生成しているのかわからないと思います. 列ごとに異なるカテゴリで, 左から順にキツネ, クジラ, クマ, チョウ, サンゴ礁, 山, 電子レンジ, トラックだそうです. 

<img width="851" alt="2019-10-30-15-03-35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/c9f213f1-ab86-02c6-948c-c1958f7a267f.png">
[Neural Discrete Representation Learning](https://arxiv.org/abs/1711.00937)

また, ここには掲載しませんが, 論文では音声や映像での実験も行っています. 

### Vector Quantised-VAE-2 [Razavi+, 2019]
**VQ-VAE-2**は基本的に, VQ-VAEを階層構造にして, さらに高解像度の画像を生成できるようにしたというものです. 
今度はImageNetの256x256の画像を, 大域的な特徴を保って生成できています. 

<img width="527" alt="2019-11-01-08-42-38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/b957660e-ed7c-211e-c34e-cf961b3e5bc1.png">

また, 1024x1024のFFHQの画像が生成できるようになりました. これはStyleGANやBigGANに並んだとも言える品質ではないでしょうか. 

<img width="532" alt="2019-10-30-15-19-54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144878/89e3f901-3524-1c6c-0d0b-5e34663d90b3.png">
[Generating Diverse High-Fidelity Images with VQ-VAE-2](https://arxiv.org/abs/1906.00446)

# おわりに
本記事では, VAEの解説とdisentanglementや高解像度化のための工夫を紹介しました. 
「VAEはGANのような鮮明な画像を生成するのが難しい」とはよく言われますが, VQ-VAE-2はそのような課題を克服できていると思います. 今後は再現実装を動かしたりしてさらに掘り下げて見たいと思います. 

（追記）
2019/12/3: [次回](https://qiita.com/shionhonda/items/330c9fdf78e62db3402b#_reference-c4b4850da3b310d98b5e)はGANです.

# 参考文献
[1] Diederik P. Kingma et al. "[Auto-Encoding Variational Bayes](https://arxiv.org/abs/1312.6114)." ICLR. 2014.
VAEの元論文です. 第一著者のKingmaはAdamやGlowの著者としてもお馴染みですね. 

[2] Carl Doersch. "[Tutorial on Variational Autoencoders](https://arxiv.org/abs/1606.05908)." arXiv. 2016.
VAEがグラフィカルモデルから丁寧に解説されています. 

[3] [Variational Autoencoder徹底解説 - Qiita](https://qiita.com/kenmatsu4/items/b029d697e9995d93aa24)
こちらは日本語の丁寧な解説記事です. Chainerの実装にも触れられています. 

[4] Kazuki Nitta. "[Variational AutoEncoder](https://www.slideshare.net/KazukiNitta/variational-autoencoder-68705109)." 2016.
こちらも日本語の丁寧な解説記事です. 

[5] Lilian Weng. "[From Autoencoder to Beta-VAE](https://lilianweng.github.io/lil-log/2018/08/12/from-autoencoder-to-beta-vae.html)." 2018.
オートエンコーダの発展としてVAEを解説した記事です. 

[6] [多変量正規分布の場合のKullback Leibler Divergenceの導出 - Qiita](https://qiita.com/kenmatsu4/items/c107bd51503462fb677f)

[7] Atsushi Suyama. "[線形回帰を１つ１つ改造して変分オートエンコーダ（VAE）を作る - 作って遊ぶ機械学習. ](http://machine-learning.hatenablog.com/entry/2018/03/25/010430)." 2018.

[8] Hideki Tsunashima. "[Disentanglement Survey:Can You Explain How Much Are Generative models Disentangled?](https://www.slideshare.net/HidekiTsunashima/disentanglement-surveycan-you-explain-how-much-are-generative-models-disentangled)." 2019.

[9] [Neural Discrete Representation Learning | Reading Notes](https://ameroyer.github.io/reading-notes/representation%20learning/2019/04/29/neural_discrete_representation_learning.html)
VQ-VAEの解説記事です.