#!/usr/bin/env python # coding: utf-8 #

Table of Contents

#
# # Stein discrepancyと最適化(SVGD) # ## 手法 # ### 目的 # KL divergenceの最小化 # # $\phi^*=\arg\min [ \partial_\epsilon KL(q_\epsilon // p) ]$ # # を行いたい # # Stein Operator $A_p$(後述)を使って勾配を # # $\nabla_\epsilon KL(q_\epsilon // p)|_{\epsilon=0}=-E_{x \sim q}[A_p \phi(x)]$ # # $ (x' = x + \phi(x) )$ # # としてこれを用いて計算する。 # ## Stein Operator # Stein operatorを # # $A_p \equiv f(x)\nabla_x \log p(x)+ \nabla_x f(x)$ # # と定義する以下のように導出される。 # 分布p(x)に対して # # $\lim_{|x| <- \infty} f(x)p(x)=0$ # # となるようなf(x)に対して恒等式(Stein identity) # # $E_{x \sim p}[ f(x)\nabla_x \log p(x)+ \nabla_x f(x) ]=0$ # # が成り立つ(部分積分から)。分布p(x)と近いq(x)に対してこれを # # $E_{x\sim q}[\nabla_x \log p(x)+ \nabla_x f(x)] \equiv E_{x\sim q}[A_p f(x)]$ # # $A_p f(x) \equiv \nabla_x \log p(x)+ \nabla_x f(x)$ # # と定義する(記号もあいまって共変微分のように見える)。また # # $E_{x \sim q}[A_p f(x)]=E_{x \sim q}[A_p f(x)]-E_{x \sim q}[A_q f(x)] =E_{x \sim q}[ f(x)(\nabla \log p(x) -\nabla \log q(x))]$ # # という関係式も成り立つ。 # ## Stein disrepancy # Stein Operator$A _p$を用いて # #  $\sqrt{S(p,q)} \equiv \max_{f \in F} E_{x\sim q} [A_p f(x)]$ # # とStein disrepancyを定義する。 # # これをどのように計算するのか # 関数f(x)を # # $f(x) = \sum_i \omega_i f_i(x)$ # # と展開すると # # $E_q[A_p f(x) ]= E_q[A_p \sum_i \omega_i f_i(x)]= \sum \omega_i \beta_i$ # # $\beta_i \equiv E_{x\sim q}[A_p f_i(x)]$ # # さらにカーネルを使って # # $f(x)=\sum_i \omega_i k(x,x_i)$ # # とかくと$ _H =\sum_{i,j} w_i v_j k(x_i,x_j)$という形に書けることから # # $E_{x \sim q}[A_p f(x)]=$ # # 添字iに関する和を有限個とすることができて(基底定理?) # # $A_p f(x)=\frac{1}{n}\sum_{i=0}^n [ f(x_i) k(x_i,x) \nabla_x \log p(x_i)+ \nabla_{x_i}k(x_i,x) ]$ # # となる。 # 結局$\phi^*=\arg\min [ \partial_\epsilon KL(q_\epsilon // p) ]$に対しては # # $\phi$がxの関数であるとしてparticle iに対し # # $x_i^{l+1} \leftarrow x_i^l + \epsilon_l \phi^*(x_i^l)$ # # $\phi^*(x)=\frac{1}{n}\sum_{j=0}^n [ k(x_j^l,x) \nabla_x \log p(x_j^l)+ \nabla_{x_j}k(x_j^l,x) ]$ # # という更新式を使う。$k(x_i,x_j)$はカーネルで行列を使って表すことができる(未知の値$k(x_i,x)$に対しては関数として実装する)。 # ## サンプリングの方法として(GANへの応用) # 論文 https://arxiv.org/abs/1611.01722 # ### Amortized SVGD # 乱数$\xi_i$に対し # $x_i=f_n(\xi_i) $ # であるとする更新式は # # $ \Delta x_i =E_{ x\sim \{x_i\} } [\nabla p(x) k(x,x_i) + \nabla_x k(x,x_i)]$ # # $x_i'=x_i+\epsilon \Delta x_i$ # # 関数$f(\eta;\xi_i)$のパラメータ(として)$\eta$があるとすると # # $\eta=\eta+\epsilon \sum_i \partial_\eta f_\eta (\xi_i)\Delta x_i$ # # としてfを更新していくのがSVGD # 特にKL divergence$KL(q_\eta//p)$に関して書き直すと # # $\nabla_\eta KL(q_\eta//p)=-E_{\xi \sim q_0}[\partial_\eta f(\eta ;\xi)(\nabla_x \log p(x) - \nabla_x \log q_\eta(x) ] $ # # となる。 # さらに$\bar{\Delta}x_i= \nabla_x \log p(x_i) - \nabla_x \log q_\eta(x_i) $ # # と書くと # # $\Delta x_i \simeq E_{x \sim q}[k(x,x_i) \nabla_x \log p(x)+ \nabla_{x}k(x,x_i) ] $ # $= E_{x \sim q}[k(x,x_i)( \nabla_x \log p(x)+ \nabla_{x} \log q(x)] $ # $= E_{x \sim q}[\bar{\Delta}x_i k(x,x_i]$ # # という近似的関係が成り立つ($\Delta x_i$は$\bar{\Delta} x_i$をカーネル重み付けしたもの # ### Amortized KSD # $\kappa_p(x,x')=\nabla_x \log p(x) \nabla_x \log p(x') k(x,x') +\nabla_x \log p(x) \nabla_x k(x,x') + \nabla_x \log p(x') \nabla_x k(x,x')+ # \nabla_x \nabla_x' k(x,x')$ # # これによって # $D^2(q//p)=E_{x,x'\sim q}[\kappa_p(x,x')]$ # # の最小化を行う。 # # ### Amortized MLE # $p(x|\theta)=\exp(-\phi(x,\theta)-\Phi(\theta)$ # という形の関数の最適化 # # $\xi_i \sim q_{\xi}, x_i=f_\eta(\xi_i)$ # として # # $\eta \leftarrow \epsilon \sum_i \partial_\eta f_\eta (\xi_i) \Delta x_i$ # # $\{x_{obs}\}$ を新たに引く # # $\theta \leftarrow \theta -E_{obs}[\nabla_\theta \phi(x,\theta)]+E_\eta[\nabla_\theta \phi(x,\theta)]$ # # を交互に繰り返す。 # # # GANの場合は # # $p(x|\theta) \propto \exp(-||x-D(E(x;\theta);\theta)||)$ # # ## 実装 # オリジナル実装はTheanoで書かれている。 # # - https://github.com/DartML/Stein-Variational-Gradient-Descent/tree/master/python # - https://github.com/DartML/Stein-Variational-Gradient-Descent/tree/master/python # # SteinGAN もベタコード # - https://github.com/DartML/Stein-Variational-Gradient-Descent/blob/master/python/bayesian_logistic_regression.py # - https://github.com/DartML/SteinGAN/tree/master/lib # - https://github.com/ChunyuanLI/SVGD/blob/master/demo_svgd.ipynb # Edward, tensorflowのoptimizerとして組み込めるかもしれません。確率分布pとその微分を使うのでEdwardやtf.distributionsを使う必要がありそうです。particle分のパラメータを複製するなどのアイデアがありえます。 # # - R package https://cran.r-project.org/web/packages/KSD/ # # - Julia 実装 # - https://github.com/krisrs1128/readings/tree/master/svgd # - https://github.com/jgorham/stein_discrepancy/tree/master/src/experiments kernelは決め打ちです。自動微分を使えば任意のkernelのgradientが計算できるかと思ったのですが、Juliaのautodiffは偏微分をやるのが難しそうだったので断念しました # # - Tensorflow # - https://github.com/xiangze/SVGD # ## Reference # - [Stein’s Method for Practical Machine Learning](https://www.cs.dartmouth.edu/~qliu/stein.html) ここに多くの論文がまとめられている # - [Probabilistic Learning and Inference Using Stein Discrepancy](https://www.cs.dartmouth.edu/~qliu/PDF/steinslides16.pdf) 概要スライド # - [Stein's Method](https://sites.google.com/site/steinsmethod/home) # - [機械学習論文読みメモ_14](https://qiita.com/festa78/items/1813377b59fd3685c119) # - http://chunyuan.li/ # - 論文 # - Stein Variational Gradient Descent: A General Purpose Bayesian Inference Algorithm [arxiv](https://arxiv.org/abs/1608.04471) # - LEARNING TO DRAW SAMPLES: WITH APPLICATION TO AMORTIZED MLE FOR GENERATIVE ADVERSARIAL LEARNING [pdf](https://arxiv.org/pdf/1611.01722.pdf) # - A Kernelized Stein Discrepancy for Goodness-of-fit Tests and Model Evaluation[arxiv](https://arxiv.org/abs/1602.03253) # In[ ]: