Pyroチュートリアル(3)

今回もPyroのチュートリアルを読んでいきたいと思います。前回は「An Introduction to Inference in Pyro」というチュートリアルを読みました。今回はその次のチュートリアルである「SVI PartI: An Introduction to Stochastic Variational Inference in Pyro」を読み進めていきます。

まず、チュートリアルではあまり触れられていないStochastic Variational Inferenceについてお話していきたいと思います。

Stochastic Variational Inferenceとは?

はじめに、Stochastic Variational Inferenceは、日本語では「確率的変分推論法」もしくは「確率的変分ベイズ法」と言います。こちらはどのような手法であるかというと、一言で表すならば、「変分ベイズに確率的勾配降下法を導入した手法」です。変分ベイズについては、本サイトの過去の記事で軽く触れているのでそちらをご覧ください。

確率的勾配降下法と言うワードに関して聞いたことがあるという方は多いと思います。この手法は深層学習でよく使われている手法であり、簡単に説明すると「大量のデータから任意のデータを取り出して繰り返しモデルを学習すること」です。この手法を変分ベイズでもほぼ同様の形で取り入れます。

やはりビッグデータを扱うことが増えてきている状況で、ミニバッチ学習は必須だということですね。

詳しいアルゴリズムについて知りたい方は、「Stochastic Variational Inference」というキーワードで検索していただくと論文などいくつか参考になるものが出てくると思いますのでそちらを参照することをお勧めします。

セットアップ

モデルはPyroで定義済みである前提で話を進めます。Pyroでは観測変数、潜在変数などは以下のように書くことができます。

  1.  観測変数→obsという引数をもつpyro.sampleメソッド
  2. 潜在変数→pyro.sample
  3. パラメータ→pyro.param

また、モデルは観測変数x、潜在変数z、パラメータΘを持っています。よって、観測変数xと潜在変数zの同時分布は以下のように表される。

$$ p_{\theta}(x, z) =  p_{\theta}(x|z)p_{\theta}(z)$$

 

モデルの学習

モデルの学習は、エビデンスを最大化するように行われます。エビデンスとは、「データがxが出現する尤もらしさ」を表しています。エビデンスh、パラメータθを用いて計算します。つまり、エビデンスを最大化するということは、エビデンスを最大化するパラメータを求めることによって実現できる、ということになります。式で表すと以下のようになります。

$$\theta_{max} = argmax_{\theta}logp_{\theta}(x)$$

また、エビデンスの対数をとったものは以下のように表されます。

$$logp_{\theta_{max}}(x) = log\int dz p_{\theta}(x, z)$$

となります。これは、エビデンスは潜在変数zについて周辺化することで得られるということです。

エビデンスの計算は、一般的に難しいことが多いです。その理由は、周辺化の積分計算が不可能であったり、潜在変数zが高次元で非現実的な計算時間を要するといったところにあります。

また、エビデンスを最大化するパラメータを探索する際に、潜在変数に関する事後分布を計算する必要があります。式で表すと以下のようになります。

$$p_{\theta_{max}}(z|x) = \frac{p_{\theta_{max}}(x, z)}{\int dz p_{\theta_{max}}(x, z)}$$

この式の分母は先ほど説明したエビデンスの式の形になっています。元々は、潜在変数に関する事後分布を求めるには条件付き確率の定義にしたがって導出しますが、それにしたがって導出した場合、分母にはp(x)が出てきます。そしてp(x)は周辺化の式に書き直すことができるので上の式のようになります。

この事後分布を計算するのは、エビデンスの計算が困難なことからできない場合が多いです。そのような時に、変分推論のような近似手法を用いてこの問題を解決します。

Guide

変分推論では、近似分布q_φ(z)という分布を導入します。φは変分パラメータ、q_φ(z)は変分分布と呼ばれます。そして、Pyroでは変分分布はGuideという名前で扱われています。

Pyroでは、guide()という関数が用意されていて、これを使うことによって事後分布の近似分布をPyro側で作成してくれます。事後分布がmodel()という関数で定義されているとします。その場合、model()とguide()は同じ引数をもつ、という重要な制約があります。

また、model()においてpyro.sample()を使う際に、引数に”z_1″のようなサンプルの名前のようなものを渡しますが、guide()内でpyro.sample()の引数に渡す名前はmodelと同じものにしなければいけません。つまり以下のようになります。

def model():
  pyro.sample("z_1", ...)

というようにmodelでpyro.sampleが使われている場合、guide関数では以下のようになります。

def guide():
  pyro.sample("z_1", ...)

ELBO

変分ベイズでは、エビデンスを直接計算して最大化するのではなく、エビデンスの下界となっているELBO(Evidence Lower Bound)という値を最大化します。ELBOは以下のように表されます。

$$ELBO = \mathbb{E}_{q_{\phi}(z)}[logp_{\theta}(x, z) – logq_{\phi}(z)]$$

Pyroでは、期待値の中にある対数は計算できる前提です。また、Guide関数(近似分布)は、パラメトリックな分布を仮定しているので、モンテカルロ法によってELBOの推定値を計算することができます。

まとめ

本記事では、確率変分ベイズ法が何かということから始まり、モデルの学習方法、モデルを学習する際に最適化する値を説明していきました。次回は、これらの内容を踏まえ、チュートリアルのサンプルコードを読んでいきたいと思います。