xiangze's sparse blog

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

Edwardで一部の変数だけ確率変数にして変分推測する仕組み

VAEやGANなどに組み込まれたニューラルネットでは重み行列やバイアスは確率変数としては定義されていません*1が、
Edwardでは使って確率変数とそうでない変数を同時に推測(学習)させることが可能です。
それはどのようにして実装されているのでしょうか。

確率変数のパラメーターの推測は変分推測ではKLダイバージェンスを最小化させることで行われますが、その処理はinference.update()にあります。
https://github.com/blei-lab/edward/blob/master/edward/inferences/variational_inference.py#L53
初期化部分であるinference.initialize()の中を見ると

”Traverse random variable graphs to get default list of variables.”

とあります。isinstance()を用いて変数がRandomVariableかどうかの判別をし、一旦setとしたvar_listに入れてuniqueにしたのちにlistにするというよくやる手法です。その元となるlatent_varsに対しては親クラスinferenceの中で
check_latent_varsを用いてRandomVariableかどうか判別しています。
https://github.com/blei-lab/edward/blob/master/edward/inferences/inference.py#L77
https://github.com/blei-lab/edward/blob/master/edward/util/random_variables.py#L64


これによって得られた変数のリストvar_listを用いて子クラスで実装されたlossと勾配(build_loss_and_gradients)を計算し、最適化アルゴリズムに渡します。
inference.update()ではそれをtensorflowと同様にsession.run()で実行します。

ではMCMCを使う場合はどうなるかというとEmpirical以外の変数を代入すると例外を出すようになっているようです。
https://github.com/blei-lab/edward/blob/master/edward/inferences/monte_carlo.py#L87

宣伝

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