Fixed MCMC sampler.

This commit is contained in:
Ilias Bilionis 2015-08-04 01:18:32 -04:00
parent f60abf7262
commit d3730bb518
4 changed files with 61 additions and 18 deletions

View file

@ -684,6 +684,16 @@ class OptimizationHandlable(Indexable):
if self._has_fixes(): return g[self._fixes_] if self._has_fixes(): return g[self._fixes_]
return g return g
def _log_det_jacobian(self):
"""
Return the logarithm of the Jacobian needed for a proper change of
variables.
"""
J = np.ones(self.param_array.shape)
[np.put(J, i, c.jacobianfactor(self.param_array[i]))
for c, i in self.constraints.iteritems() if c != __fixed__]
return np.log(J).sum()
@property @property
def num_params(self): def num_params(self):
""" """

View file

@ -1 +1,2 @@
from hmc import HMC from hmc import HMC
from samplers import *

View file

@ -4,23 +4,18 @@
import numpy as np import numpy as np
from scipy import linalg, optimize from scipy import linalg, optimize
import Tango
import sys import sys
import re
import numdifftools as ndt
import pdb
import cPickle
class Metropolis_Hastings: class Metropolis_Hastings:
def __init__(self,model,cov=None): def __init__(self,model,cov=None):
"""Metropolis Hastings, with tunings according to Gelman et al. """ """Metropolis Hastings, with tunings according to Gelman et al. """
self.model = model self.model = model
current = self.model._get_params_transformed() current = self.model.optimizer_array
self.D = current.size self.D = current.size
self.chains = [] self.chains = []
if cov is None: if cov is None:
self.cov = model.Laplace_covariance() self.cov = np.eye(self.D)
else: else:
self.cov = cov self.cov = cov
self.scale = 2.4/np.sqrt(self.D) self.scale = 2.4/np.sqrt(self.D)
@ -31,20 +26,20 @@ class Metropolis_Hastings:
if start is None: if start is None:
self.model.randomize() self.model.randomize()
else: else:
self.model._set_params_transformed(start) self.model.optimizer_array = start
def sample(self, Ntotal=10000, Nburn=1000, Nthin=10, tune=True, tune_throughout=False, tune_interval=400):
current = self.model.optimizer_array
def sample(self, Ntotal, Nburn, Nthin, tune=True, tune_throughout=False, tune_interval=400): fcurrent = self.model.log_likelihood() + self.model.log_prior() + \
current = self.model._get_params_transformed() self.model._log_det_jacobian()
fcurrent = self.model.log_likelihood() + self.model.log_prior()
accepted = np.zeros(Ntotal,dtype=np.bool) accepted = np.zeros(Ntotal,dtype=np.bool)
for it in range(Ntotal): for it in range(Ntotal):
print "sample %d of %d\r"%(it,Ntotal), print "sample %d of %d\r"%(it,Ntotal),
sys.stdout.flush() sys.stdout.flush()
prop = np.random.multivariate_normal(current, self.cov*self.scale*self.scale) prop = np.random.multivariate_normal(current, self.cov*self.scale*self.scale)
self.model._set_params_transformed(prop) self.model.optimizer_array = prop
fprop = self.model.log_likelihood() + self.model.log_prior() fprop = self.model.log_likelihood() + self.model.log_prior() + \
self.model._log_det_jacobian()
if fprop>fcurrent:#sample accepted, going 'uphill' if fprop>fcurrent:#sample accepted, going 'uphill'
accepted[it] = True accepted[it] = True
@ -72,10 +67,11 @@ class Metropolis_Hastings:
def predict(self,function,args): def predict(self,function,args):
"""Make a prediction for the function, to which we will pass the additional arguments""" """Make a prediction for the function, to which we will pass the additional arguments"""
param = self.model._get_params() param = self.model.param_array
fs = [] fs = []
for p in self.chain: for p in self.chain:
self.model._set_params(p) self.model.param_array = p
fs.append(function(*args)) fs.append(function(*args))
self.model._set_params(param)# reset model to starting state # reset model to starting state
self.model.param_array = param
return fs return fs

View file

@ -0,0 +1,36 @@
"""
Test the regression we get with the new transformations.
Author:
Ilias Bilionis
Date:
3/8/2015
"""
import sys
import os
# Make sure we load the GP that is here
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import GPy
import matplotlib.pyplot as plt
import numpy as np
import triangle
if __name__ == '__main__':
m = GPy.examples.regression.olympic_marathon_men(optimize=True)
plt.show(block=True)
print m
mcmc = GPy.inference.mcmc.samplers.Metropolis_Hastings(m)
mcmc.sample(Ntotal=100000, Nburn=10000, Nthin=100, tune_interval=1000, tune_throughout=True)
samples = np.array(mcmc.chains[-1])
fig = triangle.corner(samples)
m.plot()
fig = plt.figure()
for i in xrange(samples.shape[1]):
ax = fig.add_subplot(samples.shape[1], 1, i + 1)
ax.plot(samples[:, i], linewidth=1.5)
plt.show(block=True)