リグレット解析のメモ

MLP オンライン機械学習本でリグレット解析について勉強した際のメモ.

リグレット解析の概要

リグレット解析(regret analysis)はアルゴリズムが最適な戦略をとった場合と比べてどの程度悪かったのか, そのリグレット(後悔)を測ることでアルゴリズムの性能を測る. リグレット解析自体はオンライン学習だけでなく、ゲーム理論など広い問題設定で利用されている。

リグレット解析の定義

リグレット解析は次のような問題設定を扱う。 プレイヤーは毎回、可能なアクション集合{K}から1つのアクション{\theta \in K}を選択する。 その後に、コスト関数{f}が提示され、その回のコスト{f(\theta)}が決まる。 この操作を何回も繰り返していく。{t}回目のアクションを{\theta^{(t)}}、コスト関数を{f^{(t)}}とする。 コスト関数{f^{(t)}}は毎回全く違っていても、同じでも構わない。

プレイヤーのアクションを決める方法を戦略と呼ぶことにする。 プレイヤーはどのような戦略をとれば合計コスト{\sum^{(t)} f^{(t)}(\theta^{(t)})}を最小化できるか。 そもそもコスト関数{f^{(t)}}がわからない場合でも、合計コストを最小化できるような戦略をとることができるのか。

同じアクションしか取らない戦略を固定戦略と呼び、このアクションを{\theta^{\ast}}とする。 このとき、ある戦略{A}のリグレットは次のように定義される。

ある戦略Aに基づくアクションの合計コストと最適な固定戦略{\theta^{\ast}}による合計コストとの差を戦略{A}のリグレット {Regret_{T}(A)}という。 {} $$ Regret_{T}(A) = \sum_{i} f^{(t)}(\theta^{(t)}) - \sum_{i}f^{(t)}(\theta^{\ast}) $$ 最適な固定戦略をとっている場合と比べて、現在の戦略がどれだけ悪いのかを測り、「あの固定戦略をとっていれば」と考えるのでリグレットと呼ばれる。

戦略

Follow The Leader(FTL)

最も単純な戦略として、これまでのコストの合計を最小にするようなアクションを次のアクションとしてとる方法を考えてみる。 この戦略では{t}回目のアクション{\theta{(t)}}を次のように決定する。 {} $$ \theta^{(t)} = \arg \min \sum_{i=1} f^{(t)}(\theta) $$ この戦略はFollow The Leader(FTL)と呼ばれる。 一見うまくいくように見えるが、評価するコスト関数{f^{(t)}}はこれまでのコスト関数とは関係ないかもしれない場合には対応できない。

Regularized Follow The Leader(RFTL)

コスト関数以外にアクションを安定させることを考える。 {t}回目のアクション{\theta^{(t)}}を次のように決めることを考えてみる。 {} $$ \theta^{(t)} = \arg \min \sum_{i=1} f^{(t)}(\theta) + R(\theta) $$ ただし、{R(\theta)}は凸関数であり、{\eta \geq 0}はどの程度正則化を考慮するかのパラメータ。 この戦略をRegularized Follow The Leader(RFTL)と呼ぶ。

(諸々の証明はとばす)

コスト関数の正則化関数で割ったノルム{\lambda}を、 {} $$ \lambda = \max \, f^{(t)T} (\nabla^{2}R(\theta))^{-1} f^{(t)} $$ とし、
実行可能領域の正則化関数で割った直径{D}を、 {} $$ D = \max R(\theta)-R(\theta^{(1)}) $$ とすると、
RFTLのリグレットは次のようになる。 {} $$ Regret_{T}(A) = \sum_{i} f^{(t) T}(\theta^{(t)} - u) \leq 2 \sqrt{2 \lambda D T} $$

この式のリグレットには{\lambda}{D}が含まれている。 この2つの値はトレードオフの関係にある。 もし{D}を小さくしたいのであれば、({D=\max R(\theta)-R(\theta^{(1)})}なので)、{R(\theta)}{R(\theta^{(1)})}が小さくなるような{R}を使いたくなる。 しかしその場合、{\nabla^{2} R(\theta)}の各要素は小さく、その逆行列は大きくなるため、{\lambda}は大きくなる。 問題の特徴を活かして、{D}{\lambda}の両方が小さくなるような正則化関数、コスト関数を設計する必要がある。

Boundary Equilibrium GAN(BEGAN)でいらすとや画像を生成してみる

このBEGANを使って以下のようないらすとや画像を生成するというのが本記事の主旨。

f:id:yusuke_ujitoko:20170530010053p:plain

完全にmode collapseしてしまった。
結構いろいろ試しているものの、パラメータ調整に今のところ失敗。
悲しい。しくしく。

本論文のcontribution(とIntroに書いてある)

この論文では以下を提案している。

  • 以下の特徴を持つGANの一種(“BEGAN"としている)
    • シンプルかつロバストな構造
    • 高速に収束する
  • DiscriminatorとGeneratorの学習速度のつりあいの制御方法
  • 画像の多様性と質のトレードオフの制御方法
  • 収束の様子を評価する方法

提案手法

BEGANの概要は以下の通り

  • EBGANと同じようにauto-encoderをDiscriminatorとして使う
  • 通常GANのGeneratorは、訓練データと生成データの分布を直接一致させようとするのに対し、 BEGANのGeneratorは、訓練データと生成データ間でauto-encoderの再構成誤差の分布を一致させるように学習させる
    • 再構成誤差の訓練データと生成データ間のWasserstein距離を目的関数として学習させる

auto-encoder用のWasserstein distance

BEGANではauto-encoderの再構成誤差分布を一致させることを目的としている。
この目的に向けて、まずパラメータを定義する。

{\mathcal{L}: \mathbb{R}^{N_{x}} \mapsto \mathbb{R}^{+} } をauto-encoderの{N_{x}}次元のデータの再構成誤差関数(出力はスカラー)とする。
{\mathcal{D}: \mathbb{R}^{N_{x}} \mapsto \mathbb{R}^{N_{x}} } をauto-encoderそのものの処理(encode、decodeの)関数とする。

これらに基づく、auto-encoderの誤差は {\mathcal{L}(v) = | v - \mathcal{D}(v) |^{\eta}  } と表せる。
なおBEGANでは {\eta = 1}を使っている。
十分大きな画像の場合、この再構成誤差はi.i.dとみなせることと中心極限定理から、
画像ごとの再構成誤差は正規分布で近似できることが知られている。
(実際著者らがデータセットで再構成誤差を調べたところ正規分布になったらしい)

さて、再構成誤差が正規分布であると仮定できると、
再構成誤差のWasserstein距離が解析的に計算できる。
訓練データと生成データを、平均 {m_{1,2} \in \mathbb{R}^{p} }・共分散 {C_{1,2} \in \mathbb{R}^{p \times p}}ガウス分布の変量をとすると、
{\mu_{1} = \mathcal{N}(m_{1}, C_{1}) }
{\mu_{2} = \mathcal{N}(m_{2}, C_{2}) }
と表せる。このとき、Wasserstein distanceの二乗は次のように定義できる。 {} $$ W (\mu_{1}, \mu_{2} )^{2} = \mid\mid m_{1} - m_{2} \mid\mid^{2} + tr(C_{1} + C_{2} - 2(C_{2}^{½} C_{1} C_{2}^{½} )^{½} ) $$ さらに次元が1の場合には、 {} $$ W (\mu_{1}, \mu_{2}) = \mid\mid m_{1} - m_{2} \mid\mid_{2}^{2} + (C_{1} + C_{2} - 2 \sqrt{C_{1} C_{2}}) $$ となる。
ここでもうひとつ仮定を入れる。それは、 {\frac{c_{1} + c_{2} - 2 \sqrt{c_{1} c_{2}}}{\mid\mid m_{1} - m_{2} \mid\mid_{2}^{2}}} が定数になるという仮定。 この仮定のもとでは、 {} $$ W (\mu_{1}, \mu_{2}) \propto \mid\mid m_{1} - m_{2} \mid\mid_{2}^{2} \tag{1} $$ とみなせて問題を単純化できる。 (異常に単純化されたが大丈夫か?と思った)

GANの目的関数

Discriminatorがauto-encoderの誤差の距離(1)を最大化するように学習させたい。

  • {\mu_{1}}を訓練データ{x}の誤差{\mathcal{L}(x)}の変量とし、
  • {\mu_{2}}をGeneratorの関数{G}{N_{x}}次元の一様分布変量{z}における誤差{\mathcal{L}(G(z))}の変量とすると、

誤差の距離(1)を最大化するには以下のいずれかの状況となっている必要がある。 {} $$ \begin{align} (a) \begin{cases} W(\mu_1,\mu_2) \propto m_1 - m_2 \\ m_1 \to \infty \\ m_2 \to 0 \\ \end{cases} (b) \begin{cases} W(\mu_1,\mu_2) \propto m_2 - m_1 \\ m_1 \to 0 \\ m_2 \to \infty \\ \end{cases} \end{align}\ $$ 訓練データの誤差{\mathcal{L}(x)}は0になって欲しいので、(b)を選択する。
{m_{1}}{m_{2}}はそれぞれ{\mathcal{L(x)}}{\mathcal{L}(G(z))}の平均)

さて、DiscriminatorとGeneratorの目的関数を定義しよう。
{\theta_{D}}はDiscriminatorのパラメータ、
{\theta_{G}}はGeneratorのパラメータ、
{z_{D}}{z_{G}}{N_{z}}次元のノイズベクトルとすると、
DiscriminatorとGeneratorの目的関数は {} $$ \begin{align} {\mathcal{L}}_{D} &= {\mathcal{L}}(x;\theta_{D}) - {\mathcal{L}}(G(z_{D};\theta_{G});\theta_{D})\\ {\mathcal{L}}_{G} &= {\mathcal{L}}(G(z_{G};\theta_{G});\theta_{D}) \end{align}\ %]]> $$ と定義できる。 この目的関数では、

  • Discriminatorは、訓練データの再構成誤差が小さくなり、一方で生成データの再構成誤差が大きくなることを目指す
  • Generatorは、生成データの再構成誤差が小さくなることを目指している。

この目的関数はWGANのものと似ているが、大きく以下の点で異なっている。

  • 正規分布の誤差の分布を扱っていること
  • Wasserstein distanceの計算を単純化していること。WGANではK-リプシッツ性を必要としていたのに対して提案手法では気にしていない

Equilibrium(平衡)

上記の目的関数をうまく機能させるには、 GとDの学習速度をバランスさせる必要がある。

Generatorによる生成データを訓練データと見分けられないような「釣り合い」の状態は、 誤差分布の期待値は等しくなるはずである。 {} $$ \begin{align} {\mathbb{E}}[{\mathcal{L}}(x)] = {\mathbb{E}}[{\mathcal{L}}(G(z))] \end{align}\ $$ 通常GANでは、この状態を目指すように学習させるのだが、 今回は、{\frac{c_{1} + c_{2} - 2 \sqrt{c_{1} c_{2}}}{\mid\mid m_{1} - m_{2} \mid\mid_{2}^{2}}} が定数になるという仮定を置いたのを思い出してほしい。 この釣り合いの状態では{m_{1} - m_{2} \rightarrow 0}となり仮定が成り立たなくなる。

この問題を解決するために、 釣り合いの状態を目指さず、 {} $$ \begin{align} \gamma = \frac{{\mathbb{E}}[{\mathcal{L}}(G(z))]}{{\mathbb{E}}[{\mathcal{L}}(x)]} \tag{2} \end{align}\ $$ の状態を満たすように、ハイパーパラメータ{\gamma \in (0,1)}を導入し、学習をコントロールする。

BEGAN

以上を踏まえてBEGANの目的関数を、 {} $$ \begin{align} {\mathcal{L}}_{D} &= {\mathcal{L}}(x) - k_{t} \cdot {\mathcal{L}}(G(z_{D})) \tag{3} \\ {\mathcal{L}}_{G} &= {\mathcal{L}}(G(z_{G})) \tag{4} \\ k_{t+1} &= k_{t} + \lambda_{k}(\gamma {\mathcal{L}}(x) - {\mathcal{L}}(G(z_{D})) \tag{5} \end{align}\ $$ としている。
著者らはPropotional Control Theoryという枠組みとして提案しており、 {\gamma{\mathbb{E}} \left[{\mathcal{L}}(x) \right] = {\mathbb{E}} \left[{\mathcal{L}}(G(z))\right] }の釣り合いを保つことを目的としている。

はじめは{k_{0} = 0}と初期化する。 {\lambda_{k}}{k}のpropotional gainで、0.001を用いている。

この目的関数は、式(2)を保つフィードバック系となっている。
例えば学習初期には、

  • Gは簡単にautoencoderが再構成できるデータを生成するので、{\mathcal{L}(G(z))}は小さい。
  • また,kが小さいと、式(3)における{\mathcal{L}(x)}の重要性が増すため、Discriminatorは訓練データの再構成誤差を小さくするよう学習する。

よって、このとき{\mathcal{L}(x) > \mathcal{L}(G(z))}となっているため、 式(5)からkが徐々に大きくなっていく.

{k}が大きくなってくると、式(3)における{\mathcal{L}(G(z_{D}))}の重要性が増す。 そうなるとDiscriminatorはこの{\mathcal{L}(G(z_{D}))}を大きくするよう学習するため、 訓練データと生成データの区別をするような学習が促進される。 一気に学習が進んだときには,今度は式(5)からkが小さくなり調整される.

最終的には,式(3)の{{ \mathcal{L}}_{D} = {\mathcal{L}}(x) - k_{t} \cdot {\mathcal{L}}(G(z_{D})) = 0}となる平衡状態へ達する.

一方,Generatorは,式(4)でひたすら生成データの誤差が小さくなるよう学習する. (Discriminatorからすると,生成データと訓練データの区別が難しくなっていく)

いらすとや画像の生成

このBEGANでいらすとや画像を生成してみた。
結論からいうと、mode collapseしてしまいうまく行かなかった。
かなり綿密なパラメータ調整が必要のよう。

誤差など

f:id:yusuke_ujitoko:20170530010947p:plain mode collapseが起きた40000epochあたりで誤差が激減している。

生成画像

学習開始(0epoch)

f:id:yusuke_ujitoko:20170530005500p:plain

うっすらと何かが見え始める(1000epoch)

f:id:yusuke_ujitoko:20170530005512p:plain

輪郭が現れてくる(5000epoch)

f:id:yusuke_ujitoko:20170530005538p:plain

肌色が付き始める(6000epoch)

f:id:yusuke_ujitoko:20170530005600p:plain ここからしばらく変化なしの状態が続く。

色んなmodeが現れる(33000epoch)

f:id:yusuke_ujitoko:20170530005913p:plain

mode collapse状態になる(45000epoch)

f:id:yusuke_ujitoko:20170530010001p:plain

以降はずっとmode collapseしたまま…(100000epoch)

60000epochあたりから、背景が白固定になる。

f:id:yusuke_ujitoko:20170530010053p:plain

animation(チカチカするので注意)

f:id:yusuke_ujitoko:20170530011340g:plain

BEGANはmode collapseしやすいのがよく分かった。
パラメータ調整は今後も続けて、うまく行ったら追記することとする。

"How to Train a GAN" at NIPS2016 workshopのメモ

NIPS2016でのWorkshop on Adversarial Training「How to train a GAN」での,
GANを学習させるTipsのまとめ。

Workshopの動画 (30分程度で軽めなので観てみると良いと思います) www.youtube.com

以下は登壇者による↓のメモ
https://github.com/soumith/ganhacks

前置き

GANは現状House of cardsのようなもの.

  • Generator,Discriminatorが上手く学習しているのかわからない
  • 上手く言ってると思ったら突然崩壊する
  • モデルの評価が難しい

まだまだ発展途上で,今後新たなアルゴリズムや理論が登場する見込み.
だが現状,以下のようなテクニックは重要と思われる.
(以下のテクニックはZero scienceで単なるHackだと述べている)

1. 入力を正規化する

  • Discriminatorへ入力する訓練データ画像を-1から1の範囲に正規化する
  • Generatorの出力が-1から1の範囲となるよう,Generatorの出力層でtanhを使う

2. 誤差関数を修正する

JS divergenceから誤差関数を導くと,Generatorの学習の際には、{min (log 1-D)}を目的関数とすることとなるが、 実用的には {max log D}を使ったほうがよい。

  • 前者は勾配消失しやすい
  • Goodfellow et. al,(2014)参照

3. 球形のZを使う

Generatorに入力するノイズを一様分布からサンプリングするのではなく、
f:id:yusuke_ujitoko:20170528190404p:plain

ガウス分布からサンプリングする方がよい。
f:id:yusuke_ujitoko:20170528191319p:plain

  • ガウス分布上の点同士の内分点をもとに画像生成する場合には、 単純に点と点を結ぶ線分上の内分点を使うのではなく、 大きな球上の点同士とみて内分点を決定するとよい。 (DCGAN paperでこのミスがあったらしい)
  • 詳しくはTom Whiteの Sampling Generative Networksコード参照

4. BatchNormalization

  • 訓練データと生成データでそれぞれミニバッチ群をつくる。
    (一つのミニバッチに訓練データと生成データが混ざらないようにする)

  • BatchNormalizationを使わないときには、個々のデータに対して正規化処理を行う

f:id:yusuke_ujitoko:20170528191855p:plain

5. スパースな勾配にならないようにする(ReLUやMaxPoolを避ける)

  • スパースな勾配を使うと、GANのmini max gameが不安定になる
  • GeneratorとDiscriminatorの両方でLeakyReLUは有効
  • Downsamplingには、Average PoolingやConv2d+strideを使う
  • Upsamplingには、 PixelShuffleやConvTranspose2d + strideを使う

6. SoftでNoisyなラベルを使う

  • Labelをsoftにする
    訓練データ=1、生成データ=0というラベルであれば、例えば以下のようにする
    • 訓練データのラベルを0.7〜1.2の間のランダム値にする
    • 生成データのラベルを0.0〜0.3の間のランダム値にする
    • Salimans et. al. 2016 参照
  • Discriminatorのラベルをnoisyにする
    • Discriminator学習時に時々ラベルを反転させるなど

7. DCGAN/Hybrid Modelを使う

  • 使えるならDCGANを使う
  • DCGANを使えず、他のモデルでも安定しないときには、hybrid modelを使う
    • KL + GAN
    • VAE + GAN

8. 強化学習の安定学習のためのトリックを取り入れる

  • 強化学習でも学習が不安定になる深刻な問題がある

    • David house?のpaperを読むべき
  • Experience Replayを使う

    • 過去の生成画像をバッファしておき、ときどきそれらを用いる
    • 過去のGeneratorとDiscriminatorを覚えておき、ときどき現世代のGeneratorとDiscriminatorと入れ替える
  • Deep Deterministic Policy Gradientsに対して成功した安定学習のためのトリックを使う
  • Pfau & Vinyals (2016)を参照

9. Adam Optimizerを使う

  • Adamを使う(Radford et. al., 2015参照)
    • 良い結果が出てるlearning rateはだいたい同じ
  • もしくはDiscriminatorに対してはSGDを使い、Generatorに対してはAdamを用いるとよい。

10. 失敗を早めに発見する

  • Discriminatorの誤差が0になったら失敗
  • 勾配の大きさをチェックする。100を超えていれば失敗
  • うまく行っているときには、Discriminatorの誤差の分散は小さく、徐々に小さくなっていく。 一方、分散が大きくスパイクがあるときは失敗
  • Generatorの誤差が安定的に小さくなっているときには、ゴミのような無関係な画像でDiscriminatorを騙している可能性がある。

11. 理論なしで,GeneratorとDiscriminatorのlossがバランスするように制御しない

  • Generatorの学習回数とDiscriminatorの学習会数の比をスケジューリングするのは難しい。
  • もし試みるのであれば、直観的に行うのではなく、理論に基づいて行うほうがよい。

12. ラベルが手元にあるなら使う

  • 何らかの意味を持つラベルが手元にあれば、Discriminatorがサンプルを分類するよう学習させるとよい
    • Auxillary GANs

13. ノイズを入力に混ぜる

14. Discriminatorを多く学習する

  • noiseがあるときには特にDiscriminatorを多く学習する
  • (実際には)GとDの学習回数比を見つけるのは難しい

15. Batch Discrimination

  • 1つのデータを分類するのではなく,バッチごとに分類する手法
  • うまくいく場合とうまくいかない場合がある

16. Conditional GANsの離散変数を使う

  • Embedding layerを使う
  • 画像に追加のチャネルとして付与する
  • embedding dimensionalityを低く保ち、画像チャネルサイズにupsamplingする

17. Generatorの学習時とテスト時両方でDropoutを使う

質疑

登壇者によるhackは有意義だが,これらhackを越えたtheoretical prospectを得るにはどうすればいいの?

hackを越えたところに到達するには, GANがどのように学習するかにfocusする必要がある. そのためには個々のデータに着目するのではなく, lossとデータの関連を見つけるのが重要

Tutorial on Variational Autoencodersを読む

Tutorial on Variational Autoencoders(VAEs)を読み解いていこうと思う。
先人たちによる日本語の詳細な解説はネット上にゴロゴロあるので、
本記事は自分自身の理解のためのメモという位置づけ。

潜在変数

生成モデルは、高次元空間におけるデータ{X}の分布{P(X)}自体をモデル化するもののこと。

例えば、MNISTのような0〜9からなる手書き文字を生成する目的の生成モデルがある. このとき、モデルの生成対象は0〜9の文字なので、 モデルはまずどの文字を生成するかを決めて、その決定のもとでデータを生成するものだ,と仮定してみる。

このときの予め決定しておくパラメータのことを潜在変数(latent variable) {z}と呼ぶ。 モデルが文字を描く前に、{z}を[0,…,9]からランダムにサンプリングするというイメージ. なぜ「潜在」と呼んでいるかというと、どの潜在変数が文字を生成したかについては必ずしも知っておく必要がないため。

潜在変数{z}を決める確率分布を{P(z)}とする。 固定のパラメータ{\theta}のもとで、ランダムにサンプリングした{z}から、{X}を生成する。 この{X}が訓練データのものとよく一致すればよい生成モデルと言えそう.

数学的に記述すると、次のようになる。 {} $$ \begin{equation} P(X) = \int P(X \, | \, z;\theta) P(z) dz \tag{1} \end{equation} $$

訓練データ{X}の周辺尤度を最大化することで,潜在変数{z}を推定する.

VAEでは、{P(X \, | \, z;\theta)}ガウス分布をよく使う。
この場合のガウス分布{P(X \, | \, z;\theta) = \mathcal{N}(X \, | \, f(z;\theta), σ^{2}*I)}となる。

VAEs

VAEはいわゆるAutoencoderとはあまり関係がない。 ではなぜAutoencoderと呼ばれているかというと,最終的な目的関数を構成するのがencoderとdecoderからなるから.

上記の(1)を解くにあたって、VAEは以下の2つの問題を解決しなくてはならない。

  • 潜在変数{z}をどう定義するか(どのような情報を表現するものと定義するか)
  • 潜在変数{z}積分をどう扱うか。

1つめの問題は「文字の角度」「文字のストローク」「ストロークの太さ」「文字のスタイル」…など様々な性質が関わって複雑なため、できれば直接{z}の表す情報を決定するのは避けたい。 VAEではこの問題に対して、変わったアプローチをとっている。 それは、{z}を単純な分布、例えば正規分布{\mathcal{N}(0,I)}からサンプリングするというもの。 本当にこのアプローチは正しいのだろうか。

実は{d}次元のどのような分布であっても、正規分布からサンプルされた{d}個の変数を複雑な関数でマッピングすれば表現可能なのである。 例として以下の図のようなリング状の二次元空間状の分布を得たい場合を考える。 正規分布からサンプルされた{z}を、{g(z) = z/10 + z/ ||z||}写像すると、うまいことリング状になる。

f:id:yusuke_ujitoko:20170525215054p:plain (arxiv論文から引用)

したがって、表現力豊かな関数があるのであれば、normally-distributedな{z}を用いて、目的の分布を得ることができ、訓練データ{X}を表現できる。

{P(X)}を計算するためのコンセプトは明快。

  1. {z}をサンプリングする( {\left[z_{1}, \cdots, z_{n} \right] })
  2. {P(X) = \frac{1}{n} \sum P(X \mid z_{i}) }を計算する

ここでの問題は、 高次元空間の場合、正確に{P(X)}を推定するには、{n}が非常に大きくなってしまうということ。

目的関数の設定

(1)式を簡単に計算する方法はなにかないだろうか? よく考えると、大抵の{z}に対して、{P(X \mid z)}はほぼ0となることに気づく。 大抵の{z}はなにも寄与しない。

VAEはこの考え方を利用していて、{X}を生成するような{z}のみをサンプリングしようとする。
そこで{Q(z \mid X)}という新たな関数を考える。 この関数は、{X}のもとで、{z}の分布を与えるもので、逆から考えるとその{z}は結局{X}を生成するようなものである。 このような{z}の空間は事前確率{P(z)}において極めて小さい。 これにより、例えば{\mathbb{E}_{z \sim Q}P(X \mid z)}の計算が簡単になる。

一方、{P(X)}の計算は簡単になるだろうか。 とりあえず最初にしてみるのは{\mathbb{E}_{z \sim Q}P(X \mid z)}{P(X)}の関係付けである。

{\mathbb{E}_{z \sim Q} P(X \mid z)}{P(X)}の関係は、変分ベイズで片付けられる。 まず{P(X \mid z)}{Q(z)}間のKL divergenceを任意の{Q}に対して定義する。 {} $$ D \left[ Q(z) \mid\mid P(z \mid X) \right] = \mathbb{E}_{z \sim Q} \left[ \log Q(z) - log P(z \mid X) \right] $$

この式に対して、ベイズの定理を適用して変換して、さらに{z}に無関係な項を期待値からはずす操作を施す。 {} $$ D \left[ Q(z) \mid\mid P(z \mid X) \right] = \mathbb{E}_{z \sim Q} \left[ \log Q(z) - \log P(X \mid z) - \log P(z) \right] + \log P(X) $$

両辺にマイナスをかけて、期待値の項の中身の一部をKL divergenceに書き換える。 {} $$ \log P(X) - D \left[ Q(z) \mid\mid P(z \mid X) \right] = \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] - D \left[ Q(z) \mid\mid P(z) \right] $$

{X}は固定値であり、{Q}はあらゆる分布がありうることに注意しておく。 {P(X)}を推論することに興味があるため、{X}に依存するような{Q}を構築したい。 それはつまり{D \left[ Q(z) \mid\mid P(z \mid X) \right]}が小さくなるような場合。 {} $$ \begin{equation} \log P(X) - D \left[ Q(z \mid X) \mid\mid P(z \mid X) \right] = \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] - D \left[ Q(z \mid X) \mid\mid P(z) \right] \tag{2} \end{equation} $$

この式はVAEのコアになる部分なので詳しくみていく。

  • 左辺の{P(X)}は最大化したい。 (一方で、左辺の{D \left[ Q(z \mid X) \mid\mid P(z \mid X) \right]}を最小化しつつ)
  • 右辺は、勾配降下法でうまく{Q}を選んでいけば最適化できる。 この右辺の項はAutoencoderとみなせる。 {Q}{X}{z}にencodeし、一方{P}{z}から{X}を復元しようとしている。

左辺では{ D \left[ Q(z \mid X) \mid\mid P(z \mid X) \right]}を最小化しつつ、{P(X)}を最大化する。

{P(z | X)}は解析的に計算できない。 しかし、左辺の二項目の{Q(z | x)}{P(z | x)}に近づいていくことを考えてみる。 もし、{Q(z | x)}の表現力が高く、{P(z | x)}と近い場合には、これらの間のKL divergenceは0になる。 この仮定のもとでは {\log P(X)}のみを最適化すればよい。

目的関数を最適化する

(2)の右辺をどのように最適化すればよいだろうか? {Q(z | X)}をどうするかという問いになるが、 普通は {Q(z | X) = \mathcal{N} (z | \mu(X;\theta), Σ(X;\theta))}とする。 ここで{\mu}{Σ}はパラメータ{\theta}を持つ任意の関数でデータから学習する。 実際、{\mu}{Σ}ニューラルネットワークで決める。 この手法は計算量は小さいのが利点。

もうひとつの項は、{D \left[ Q(z|X || P(z) \right]}はKL divergenceである。 多変量ガウス分布のKL divergenceは、次のようなclosed formで書ける。 {} $$ D [ \mathcal{N}(\mu_{0}, Σ_{0}) || \mathcal{N}(\mu_{1}, Σ_{1}) ] = \frac{1}{2} \bigl( tr(Σ_{1}^{-1} Σ_{0}) + (\mu_{1} - \mu_{0})^{T} Σ_{1}^{-1} (\mu_{1} - \mu_{0}) -k + \log(\frac{det Σ_{1}}{det Σ_{0}}) \bigr) $$ 今回に適用するとシンプルになる。 {} $$ D [ \mathcal{N}(\mu(X), Σ(X)) || \mathcal{N}(0,I) ] = \frac{1}{2} \bigl( tr(Σ(X)) + (\mu(X))^{T} (\mu(X) -k - \log det (Σ(X)) \bigr) $$

さて、(2)の式に戻る。 (2)の右辺第一項に対する対応は、{z}を1つサンプルして、それに基づく{P(X \mid z)}{\mathbb{E}_{z \sim Q}[log P(X \mid z)}とみなすこととする。

最後に、データセット全体からサンプル{X}をとって期待値を計算すると、 最適化したい式は次のようになる。 {} $$ \begin{equation} E_{X \sim D} [ log P(X) - D[Q(z|X) || P(z|X)] ] = E_{X \sim D} [ E_{z \sim Q} [ log P(X | z)] - D[Q(z|X) || P(z) ]] \tag{3} \end{equation} $$ この式に基づいて勾配計算をするときには、期待値の中身を計算すればよい。
つまり{X}{Q(z|X)}をサンプルして、以下の勾配を計算する。 {} $$ log P(X|z) - D[ Q(z|X) || P(z) ] $$

ところが実は{\mathbb{E}_{z \sim Q}\left[log P(X \mid z)\right]}の計算に際して 深刻な問題 がある。 {log P(X \mid z)}{P}だけでなく{Q}にも依存している。 しかし、(3)ではこの依存が消滅してしまっている。 VAEを上手く機能させるためには、{Q}を経た上で、{P}{X}を復元させるようにする必要がある。

下図の(左)が問題を示している。

f:id:yusuke_ujitoko:20170525224357p:plain (arxiv論文から引用)

forward passは問題ない。 しかしbackpropagate時に、計算グラフが途切れているため、誤差を{z}から{Q(z \mid X}へ伝播することができない。

ここで reparameterization trick を使う。
この手法ではサンプリング操作の代わりに{z}{Q}の出力結果を元に関数で生成する。 具体的には、{\mu(X)}{Σ(X)}のもとで、{z = \mu(X) + Σ^{\frac{1}{2}} \odot \epsilon}として{z}を計算する。(ここで{\epsilon}は最適化とは無関係のハイパーパラメータ) よって実際に勾配を取る式は次のようになる。 {} $$ E_{X \sim D} \left[ E_{\epsilon \sim N(0, I)}[log P(X|z = \mu(X) + Σ^{½} \odot \epsilon)] - D[Q(z|X) || P(z) ] \right] $$

学習済みモデルを試すためには

新しいデータを生成したい時には、decoderに{z \sim N(0,I)}を投入する。 単純にVAEからencoderを取り除く操作となる。

いらすとや画像を生成してみる

VAEをtensorflowで実装し, いらすとや画像を生成してみた.
実装に誤りがあるのか, 現状うまく生成できなかった..

f:id:yusuke_ujitoko:20170526000145p:plain

mode collapseが起きている。

(追記)

上の記述だと, 式変形を追いにくいので,全体の変形をまとめて書いてみる. 上よりも式変形を補った. {} $$ \begin{align} D \left[ Q(z) \mid\mid P(z \mid X) \right] &= \int Q(z) [\log Q(z) - \log P(z \mid X)] dz \\ &= \mathbb{E}_{z \sim Q} \left[ \log Q(z) - \log P(z \mid X) \right] \\ &= \mathbb{E}_{z \sim Q} \left[ \log Q(z) - \log P(X \mid z) - \log P(z) + \log P(X) \right] \\ &= \mathbb{E}_{z \sim Q} \left[ \log Q(z) - \log P(X \mid z) - \log P(z) \right] + \log P(X) \\ &= \mathbb{E}_{z \sim Q} \left[ \log Q(z) - \log P(z)\right] - \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] + \log P(X) \\ &= D \left[ Q(z) \mid\mid P(z) \right] - \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] + \log P(X) \end{align} $$ 左辺と右辺を入れ替えて, {} $$ \begin{align} \log P(X) - D \left[ Q(z \mid X) \mid\mid P(z \mid X) \right] &= \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] - D \left[ Q(z \mid X) \mid\mid P(z) \right] \\ \log P(X) & \geq \mathbb{E}_{z \sim Q} \left[ \log P(X \mid z) \right] - D \left[ Q(z \mid X) \mid\mid P(z) \right] = L(\theta, \phi; x) \end{align} $$ 左辺を最大化する代わりに右辺を最大化する.