xiangze's sparse blog

機械学習、ベイズ統計、コンピュータビジョンと関連する数学について

Edwardを試してみた(2)変分オートエンコーダー(VAE)

だいぶ間が空いてしまいましたがEdwardのサンプルコードを動かしてみました。

シンプルなVEA

f:id:xiangze:20180104223118p:plain
gist.github.com

1層前結合ニューラルネットをEncoder,Decoderに使っています。

kerasの関数Denseを使ってEncoder,Decoderが定義されています。同じTensorFlowベースのライブラリなのでこのようにして書くことができます。
EdwardではVEAのようなモデルがかける反面前回のコードのように変分ベイズMCMCを使ったベイズ推定では確率モデルと因子分解した近似モデルの2つを書かねばならずstanなどに比べて冗長でした。少し広い枠組みの確率的プログラミングができるということになります。

隠れた変数qzの推測の過程で勾配を用いるので隠れた変数として正規分布に従うqzのパラメータloc,scaleを定義し、これを更新するようにしています。
(Reparameterization Trick)
計算はできるものの出力される画像は全く数字っぽくないものでした。

VAE with CNN

gist.github.com

kerasをEdwardと組合せて使う例はMixture Density Networks with Edward, Keras and TensorFlow — Adventures in Machine Learning
などにあるのですが、最新のEdwardではed.Dataが無くなっていたのでclassを作ってその中でkerasのmodelを返し、ed.MAP()等にdataとともに渡す方法はでできなくなっています。
そこでexampleにあるようにTensorflowのラッパー(の一つ)Tensorflow slimを使いました。networkのオブジェクトを返すような関数としてgenerative_network(decoder), inference_network(encoder)を定義しています。
Bayesian NNでは全ての重みに事前分布を設定する手法がありますが、ここではニューラルネットの部分は事前分布を定義せず、最適化に任せているようです。
生Tensorflowを使った場合よりコードは短く、わかりやすくなっていると思いますが、KL-divergenceとデータxのloss関数が全体のloss関数になっているところがわかりづらいです。*1

結果はシンプルな場合よりは数字っぽくなっており、期待した動作に近いようです。

課題

  • 係数λの導入
  • 学習誤差の図示,定量的評価
  • (個人的)GPUでの計算

その他

Edwardチュートリアルを翻訳しています。
github.com

*1:あとx,x_phのスケールをいじれば本当は重み係数λを設定することができます。