bayesian
Edward

Edwardでの変分推論、MCMCの切り替え

More than 1 year has passed since last update.

Edwardでは変分ベイズによる推論(KLqp等)、MCMCによる推論(HMC,SGHMC等)をそれぞれ使うことができるが、近似用の変数を定義する必要がありpymc,stanに比べ煩雑なところがある。

以下のように書くと変数isEmpiricalを使って切り替えて結果を比較しやすい。

状態空間モデルでの例( Edward、PyStan、PyMC3で状態空間モデルを実装してみた

を参考にさせていただきました)

def genempirical(T):

return Empirical(tf.Variable(tf.zeros(T)))

def genq():
return Normal(loc=tf.Variable(tf.random_normal([])), scale=tf.nn.softplus(tf.Variable(tf.random_normal([]))))

def statespace(N,T,isEmpirical=False):
muZero = Normal(loc=0.0, scale=1.0)
sigmaW = InverseGamma(concentration=1.0, rate=1.0)

mu = [0]*N
mu[0] = Normal(loc=muZero, scale=sigmaW)
for n in range(1, N):
mu[n] = Normal(loc=mu[n-1], scale=sigmaW)

sigmaV = InverseGamma(concentration=1.0, rate=1.0)
y_pre = Normal(loc=tf.stack(mu), scale=sigmaV)
if(isEmpicical):
qmuZero = Empirical(tf.Variable(tf.zeros(T)))
qsigmaW = Empirical(tf.Variable(tf.zeros(T)))
qmu = [Empirical(tf.Variable(tf.zeros(T))) for n in range(N)]
qsigmaV = Empirical(tf.Variable(tf.zeros(T)))
else:
qmuZero = genq()
qsigmaW = genq()
qmu = [ genq() for n in range(N) ]
qsigmaV = genq()

latent_vars = {m: qm for m, qm in zip(mu, qmu)}
latent_vars[muZero] =qmuZero
latent_vars[sigmaW]= qsigmaW
latent_vars[sigmaV] = qsigmaV

return y_pre, latent_vars, qmu

MCMC, 変分ベイズそれぞれ

def nile_st_SGHMC(y,N,T):

y_pre,latent_vars,qmu=nile_st(N,T,True)
return ed.SGHMC(latent_vars, data={y_pre: y}) ,qmu

def nile_st_vb(y,N,T):
y_pre,latent_vars,qmu=nile_st(N,T,False)
return ed.KLqp(latent_vars, data={y_pre: y}) ,qmu

と書いて推論の実行

T=1000

inference,qmu=nile_st_vb(y,N,T)

サンプリング

python

qmu_sample=np.array([ _qmu.sample(1000).eval() for _qmu in qmu])

をすることができる。

が、時系列モデルのような階層的なモデルでの推論結果はまだ(version 1.3.5)安定していないようなのでお勧めできない。

関連する質問