def test_lower_bound(self): """ Test the Wishart VB lower bound """ # # By having the Wishart node as the only latent node, VB will give exact # results, thus the VB lower bound is the true marginal log likelihood. # Thus, check that they are equal. The true marginal likelihood is the # multivariate Student-t distribution. # np.random.seed(42) D = 3 n = (D-1) + np.random.uniform(0.1, 0.5) V = random.covariance(D) Lambda = Wishart(n, V) mu = np.random.randn(D) Y = Gaussian(mu, Lambda) y = np.random.randn(D) Y.observe(y) Lambda.update() L = Y.lower_bound_contribution() + Lambda.lower_bound_contribution() mu = mu nu = n + 1 - D Cov = V / nu self.assertAllClose(L, _student_logpdf(y, mu, Cov, nu)) pass
def test_moments(self): """ Test the moments of Wishart node """ np.random.seed(42) # Test prior moments D = 3 n = (D-1) + np.random.uniform(0.1,2) V = random.covariance(D) Lambda = Wishart(n, V) Lambda.update() u = Lambda.get_moments() self.assertAllClose(u[0], n*np.linalg.inv(V), msg='Mean incorrect') self.assertAllClose(u[1], (np.sum(special.digamma((n - np.arange(D))/2)) + D*np.log(2) - np.linalg.slogdet(V)[1]), msg='Log determinant incorrect') # Test posterior moments D = 3 n = (D-1) + np.random.uniform(0.1,2) V = random.covariance(D) Lambda = Wishart(n, V) mu = np.random.randn(D) Y = Gaussian(mu, Lambda) y = np.random.randn(D) Y.observe(y) Lambda.update() u = Lambda.get_moments() n = n + 1 V = V + np.outer(y-mu, y-mu) self.assertAllClose(u[0], n*np.linalg.inv(V), msg='Mean incorrect') self.assertAllClose(u[1], (np.sum(special.digamma((n - np.arange(D))/2)) + D*np.log(2) - np.linalg.slogdet(V)[1]), msg='Log determinant incorrect') pass
def test_gaussian_mixture_plot(): """ Test the gaussian_mixture plotting function. The code is from http://www.bayespy.org/examples/gmm.html """ np.random.seed(1) y0 = np.random.multivariate_normal([0, 0], [[1, 0], [0, 0.02]], size=50) y1 = np.random.multivariate_normal([0, 0], [[0.02, 0], [0, 1]], size=50) y2 = np.random.multivariate_normal([2, 2], [[1, -0.9], [-0.9, 1]], size=50) y3 = np.random.multivariate_normal([-2, -2], [[0.1, 0], [0, 0.1]], size=50) y = np.vstack([y0, y1, y2, y3]) bpplt.pyplot.plot(y[:, 0], y[:, 1], 'rx') N = 200 D = 2 K = 10 alpha = Dirichlet(1e-5 * np.ones(K), name='alpha') Z = Categorical(alpha, plates=(N, ), name='z') mu = Gaussian(np.zeros(D), 1e-5 * np.identity(D), plates=(K, ), name='mu') Lambda = Wishart(D, 1e-5 * np.identity(D), plates=(K, ), name='Lambda') Y = Mixture(Z, Gaussian, mu, Lambda, name='Y') Z.initialize_from_random() Q = VB(Y, mu, Lambda, Z, alpha) Y.observe(y) Q.update(repeat=1000) bpplt.gaussian_mixture_2d(Y, scale=2)
def test_message_to_parents(self): """ Check gradient passed to inputs parent node """ D = 3 X = Gaussian(np.random.randn(D), random.covariance(D)) V = Wishart(D + np.random.rand(), random.covariance(D)) Y = Gaussian(X, V) self.assert_moments( Y, lambda u: [u[0], u[1] + u[1].T] ) Y.observe(np.random.randn(D)) self.assert_message_to_parent(Y, X) #self.assert_message_to_parent(Y, V) pass
from bayespy.nodes import Dirichlet, Categorical from bayespy.nodes import Gaussian, Wishart from bayespy.nodes import Mixture from bayespy.inference import VB y0 = np.random.multivariate_normal([0, 0], [[2, 0], [0, 0.1]], size=50) y1 = np.random.multivariate_normal([0, 0], [[0.1, 0], [0, 2]], size=50) y2 = np.random.multivariate_normal([2, 2], [[2, -1.5], [-1.5, 2]], size=50) y3 = np.random.multivariate_normal([-2, -2], [[0.5, 0], [0, 0.5]], size=50) y = np.vstack([y0, y1, y2, y3]) N = 200 D = 2 K = 10 alpha = Dirichlet(1e-5*np.ones(K), name='alpha') Z = Categorical(alpha, plates=(N,),name='z') mu = Gaussian(np.zeros(D),1e-5*np.identity(D),plates=(K,),name='mu') Lambda = Wishart(D,1e-5*np.identity(D),plates=(K,),name='Lambda') Y = Mixture(Z, Gaussian, mu, Lambda, name='Y') Z.initialize_from_random() Q = VB(Y, mu, Lambda, Z, alpha) Y.observe(y) Q.update(repeat=1000) bpplt.gaussian_mixture_2d(Y, alpha=alpha, scale=2)
def test_message_to_child(self): """ Test the message to child of GaussianGammaISO node. """ # Simple test mu = np.array([1, 2, 3]) Lambda = np.identity(3) a = 2 b = 10 X_alpha = GaussianGammaISO(mu, Lambda, a, b) u = X_alpha._message_to_child() self.assertEqual(len(u), 4) tau = np.array(a / b) self.assertAllClose(u[0], tau[..., None] * mu) self.assertAllClose( u[1], (linalg.inv(Lambda) + tau[..., None, None] * linalg.outer(mu, mu))) self.assertAllClose(u[2], tau) self.assertAllClose(u[3], -np.log(b) + special.psi(a)) # Test with unknown parents mu = Gaussian(np.arange(3), 10 * np.identity(3)) Lambda = Wishart(10, np.identity(3)) a = 2 b = Gamma(3, 15) X_alpha = GaussianGammaISO(mu, Lambda, a, b) u = X_alpha._message_to_child() (mu, mumu) = mu._message_to_child() Cov_mu = mumu - linalg.outer(mu, mu) (Lambda, _) = Lambda._message_to_child() (b, _) = b._message_to_child() (tau, logtau) = Gamma( a, b + 0.5 * np.sum(Lambda * Cov_mu))._message_to_child() self.assertAllClose(u[0], tau[..., None] * mu) self.assertAllClose( u[1], (linalg.inv(Lambda) + tau[..., None, None] * linalg.outer(mu, mu))) self.assertAllClose(u[2], tau) self.assertAllClose(u[3], logtau) # Test with plates mu = Gaussian(np.reshape(np.arange(3 * 4), (4, 3)), 10 * np.identity(3), plates=(4, )) Lambda = Wishart(10, np.identity(3)) a = 2 b = Gamma(3, 15) X_alpha = GaussianGammaISO(mu, Lambda, a, b, plates=(4, )) u = X_alpha._message_to_child() (mu, mumu) = mu._message_to_child() Cov_mu = mumu - linalg.outer(mu, mu) (Lambda, _) = Lambda._message_to_child() (b, _) = b._message_to_child() (tau, logtau) = Gamma( a, b + 0.5 * np.sum(Lambda * Cov_mu, axis=(-1, -2)))._message_to_child() self.assertAllClose(u[0] * np.ones((4, 1)), np.ones((4, 1)) * tau[..., None] * mu) self.assertAllClose( u[1] * np.ones((4, 1, 1)), np.ones((4, 1, 1)) * (linalg.inv(Lambda) + tau[..., None, None] * linalg.outer(mu, mu))) self.assertAllClose(u[2] * np.ones(4), np.ones(4) * tau) self.assertAllClose(u[3] * np.ones(4), np.ones(4) * logtau) pass
def test_init(self): """ Test the creation of GaussianGammaISO node """ # Simple construction X_alpha = GaussianGammaISO([1, 2, 3], np.identity(3), 2, 10) self.assertEqual(X_alpha.plates, ()) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Plates X_alpha = GaussianGammaISO([1, 2, 3], np.identity(3), 2, 10, plates=(4, )) self.assertEqual(X_alpha.plates, (4, )) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Plates in mu X_alpha = GaussianGammaISO(np.ones((4, 3)), np.identity(3), 2, 10) self.assertEqual(X_alpha.plates, (4, )) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Plates in Lambda X_alpha = GaussianGammaISO(np.ones(3), np.ones((4, 3, 3)) * np.identity(3), 2, 10) self.assertEqual(X_alpha.plates, (4, )) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Plates in a X_alpha = GaussianGammaISO(np.ones(3), np.identity(3), np.ones(4), 10) self.assertEqual(X_alpha.plates, (4, )) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Plates in Lambda X_alpha = GaussianGammaISO(np.ones(3), np.identity(3), 2, np.ones(4)) self.assertEqual(X_alpha.plates, (4, )) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # Inconsistent plates self.assertRaises(ValueError, GaussianGammaISO, np.ones((4, 3)), np.identity(3), 2, 10, plates=()) # Inconsistent plates self.assertRaises(ValueError, GaussianGammaISO, np.ones((4, 3)), np.identity(3), 2, 10, plates=(5, )) # Unknown parameters mu = Gaussian(np.zeros(3), np.identity(3)) Lambda = Wishart(10, np.identity(3)) b = Gamma(1, 1) X_alpha = GaussianGammaISO(mu, Lambda, 2, b) self.assertEqual(X_alpha.plates, ()) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) # mu is Gaussian-gamma mu_tau = GaussianGammaISO(np.ones(3), np.identity(3), 5, 5) X_alpha = GaussianGammaISO(mu_tau, np.identity(3), 5, 5) self.assertEqual(X_alpha.plates, ()) self.assertEqual(X_alpha.dims, ((3, ), (3, 3), (), ())) pass
def test_message_to_child(self): """ Test the message to child of GaussianGamma node. """ # Simple test mu = np.array([1,2,3]) Lambda = np.identity(3) a = 2 b = 10 X_alpha = GaussianGamma(mu, Lambda, a, b) u = X_alpha._message_to_child() self.assertEqual(len(u), 4) tau = np.array(a/b) self.assertAllClose(u[0], tau[...,None] * mu) self.assertAllClose(u[1], (linalg.inv(Lambda) + tau[...,None,None] * linalg.outer(mu, mu))) self.assertAllClose(u[2], tau) self.assertAllClose(u[3], -np.log(b) + special.psi(a)) # Test with unknown parents mu = Gaussian(np.arange(3), 10*np.identity(3)) Lambda = Wishart(10, np.identity(3)) a = 2 b = Gamma(3, 15) X_alpha = GaussianGamma(mu, Lambda, a, b) u = X_alpha._message_to_child() (mu, mumu) = mu._message_to_child() Cov_mu = mumu - linalg.outer(mu, mu) (Lambda, _) = Lambda._message_to_child() (b, _) = b._message_to_child() (tau, logtau) = Gamma(a, b + 0.5*np.sum(Lambda*Cov_mu))._message_to_child() self.assertAllClose(u[0], tau[...,None] * mu) self.assertAllClose(u[1], (linalg.inv(Lambda) + tau[...,None,None] * linalg.outer(mu, mu))) self.assertAllClose(u[2], tau) self.assertAllClose(u[3], logtau) # Test with plates mu = Gaussian(np.reshape(np.arange(3*4), (4,3)), 10*np.identity(3), plates=(4,)) Lambda = Wishart(10, np.identity(3)) a = 2 b = Gamma(3, 15) X_alpha = GaussianGamma(mu, Lambda, a, b, plates=(4,)) u = X_alpha._message_to_child() (mu, mumu) = mu._message_to_child() Cov_mu = mumu - linalg.outer(mu, mu) (Lambda, _) = Lambda._message_to_child() (b, _) = b._message_to_child() (tau, logtau) = Gamma(a, b + 0.5*np.sum(Lambda*Cov_mu, axis=(-1,-2)))._message_to_child() self.assertAllClose(u[0] * np.ones((4,1)), np.ones((4,1)) * tau[...,None] * mu) self.assertAllClose(u[1] * np.ones((4,1,1)), np.ones((4,1,1)) * (linalg.inv(Lambda) + tau[...,None,None] * linalg.outer(mu, mu))) self.assertAllClose(u[2] * np.ones(4), np.ones(4) * tau) self.assertAllClose(u[3] * np.ones(4), np.ones(4) * logtau) pass
def test_messages(self): D = 2 M = 3 np.random.seed(42) def check(mu, Lambda, alpha, beta, ndim): X = GaussianGamma( mu, ( Lambda if isinstance(Lambda._moments, WishartMoments) else Lambda.as_wishart(ndim=ndim) ), alpha, beta, ndim=ndim ) self.assert_moments( X, postprocess=lambda u: [ u[0], u[1] + linalg.transpose(u[1], ndim=ndim), u[2], u[3] ], rtol=1e-5, atol=1e-6, eps=1e-8 ) X.observe( ( np.random.randn(*(X.plates + X.dims[0])), np.random.rand(*X.plates) ) ) self.assert_message_to_parent(X, mu) self.assert_message_to_parent( X, Lambda, postprocess=lambda m: [ m[0] + linalg.transpose(m[0], ndim=ndim), m[1], ] ) self.assert_message_to_parent(X, beta) check( Gaussian(np.random.randn(M, D), random.covariance(D), plates=(M,)), Wishart(D + np.random.rand(M), random.covariance(D), plates=(M,)), np.random.rand(M), Gamma(np.random.rand(M), np.random.rand(M), plates=(M,)), ndim=1 ) check( GaussianARD(np.random.randn(M, D), np.random.rand(M, D), ndim=0), Gamma(np.random.rand(M, D), np.random.rand(M, D)), np.random.rand(M, D), Gamma(np.random.rand(M, D), np.random.rand(M, D)), ndim=0 ) pass
current_step = -1 # In[ ]: # In[41]: action_space = {-1, 0, 1} # In[42]: observations # In[88]: Lambda = Wishart(2, [[1, 0], [0, 1]]) np.zeros(D) np.identity(D) # In[135]: #http://www.bayespy.org/user_api/generated/generated/bayespy.nodes.SwitchingGaussianMarkovChain.html#bayespy-nodes-switchinggaussianmarkovchain obs_nodes = {} action_nodes = {} O_D = int(np.prod(env.observation_space.shape) ) # will only work with low dimensions. Need filter if isinstance(env.action_space, gym.spaces.discrete.Discrete): A_D = env.action_space.n #mu = np.zeros(D) #lambda_ = 1e-5*np.identity(D)