mirror of
https://github.com/SheffieldML/GPy.git
synced 2026-05-08 11:32:39 +02:00
more variational quadtrature code
This commit is contained in:
parent
9bfd569c7b
commit
30343f5e53
3 changed files with 21 additions and 23 deletions
|
|
@ -113,10 +113,8 @@ class Bernoulli(Likelihood):
|
||||||
.. Note:
|
.. Note:
|
||||||
Each y_i must be in {0, 1}
|
Each y_i must be in {0, 1}
|
||||||
"""
|
"""
|
||||||
assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape
|
|
||||||
#objective = (inv_link_f**y) * ((1.-inv_link_f)**(1.-y))
|
#objective = (inv_link_f**y) * ((1.-inv_link_f)**(1.-y))
|
||||||
objective = np.where(y, inv_link_f, 1.-inv_link_f)
|
return np.where(y, inv_link_f, 1.-inv_link_f)
|
||||||
return np.exp(np.sum(np.log(objective)))
|
|
||||||
|
|
||||||
def logpdf_link(self, inv_link_f, y, Y_metadata=None):
|
def logpdf_link(self, inv_link_f, y, Y_metadata=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -133,9 +131,7 @@ class Bernoulli(Likelihood):
|
||||||
:returns: log likelihood evaluated at points inverse link of f.
|
:returns: log likelihood evaluated at points inverse link of f.
|
||||||
:rtype: float
|
:rtype: float
|
||||||
"""
|
"""
|
||||||
assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape
|
|
||||||
#objective = y*np.log(inv_link_f) + (1.-y)*np.log(inv_link_f)
|
#objective = y*np.log(inv_link_f) + (1.-y)*np.log(inv_link_f)
|
||||||
state = np.seterr(divide='ignore')
|
|
||||||
p = np.where(y==1, inv_link_f, 1.-inv_link_f)
|
p = np.where(y==1, inv_link_f, 1.-inv_link_f)
|
||||||
return np.log(p)
|
return np.log(p)
|
||||||
|
|
||||||
|
|
@ -154,13 +150,10 @@ class Bernoulli(Likelihood):
|
||||||
:returns: gradient of log likelihood evaluated at points inverse link of f.
|
:returns: gradient of log likelihood evaluated at points inverse link of f.
|
||||||
:rtype: Nx1 array
|
:rtype: Nx1 array
|
||||||
"""
|
"""
|
||||||
assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape
|
|
||||||
#grad = (y/inv_link_f) - (1.-y)/(1-inv_link_f)
|
#grad = (y/inv_link_f) - (1.-y)/(1-inv_link_f)
|
||||||
state = np.seterr(divide='ignore')
|
#grad = np.where(y, 1./inv_link_f, -1./(1-inv_link_f))
|
||||||
# TODO check y \in {0, 1} or {-1, 1}
|
denom = np.where(y, inv_link_f, -(1-inv_link_f))
|
||||||
grad = np.where(y, 1./inv_link_f, -1./(1-inv_link_f))
|
return 1./denom
|
||||||
np.seterr(**state)
|
|
||||||
return grad
|
|
||||||
|
|
||||||
def d2logpdf_dlink2(self, inv_link_f, y, Y_metadata=None):
|
def d2logpdf_dlink2(self, inv_link_f, y, Y_metadata=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -183,13 +176,12 @@ class Bernoulli(Likelihood):
|
||||||
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
Will return diagonal of hessian, since every where else it is 0, as the likelihood factorizes over cases
|
||||||
(the distribution for y_i depends only on inverse link of f_i not on inverse link of f_(j!=i)
|
(the distribution for y_i depends only on inverse link of f_i not on inverse link of f_(j!=i)
|
||||||
"""
|
"""
|
||||||
assert np.atleast_1d(inv_link_f).shape == np.atleast_1d(y).shape
|
|
||||||
#d2logpdf_dlink2 = -y/(inv_link_f**2) - (1-y)/((1-inv_link_f)**2)
|
#d2logpdf_dlink2 = -y/(inv_link_f**2) - (1-y)/((1-inv_link_f)**2)
|
||||||
state = np.seterr(divide='ignore')
|
state = np.seterr(divide='ignore')
|
||||||
# TODO check y \in {0, 1} or {-1, 1}
|
# TODO check y \in {0, 1} or {-1, 1}
|
||||||
d2logpdf_dlink2 = np.where(y, -1./np.square(inv_link_f), -1./np.square(1.-inv_link_f))
|
#d2logpdf_dlink2 = np.where(y, -1./np.square(inv_link_f), -1./np.square(1.-inv_link_f))
|
||||||
np.seterr(**state)
|
arg = np.where(y, inv_link_f, 1.-inv_link_f)
|
||||||
return d2logpdf_dlink2
|
return -1./np.square(arg)
|
||||||
|
|
||||||
def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None):
|
def d3logpdf_dlink3(self, inv_link_f, y, Y_metadata=None):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -146,20 +146,26 @@ class Likelihood(Parameterized):
|
||||||
|
|
||||||
if gh_points is None:
|
if gh_points is None:
|
||||||
gh_x, gh_w = np.polynomial.hermite.hermgauss(20)
|
gh_x, gh_w = np.polynomial.hermite.hermgauss(20)
|
||||||
|
else:
|
||||||
|
gh_x, gh_w = gh_points
|
||||||
|
|
||||||
shape = m.shape
|
shape = m.shape
|
||||||
m,v,Y = m.flatten(), v.flatten(), Y.flatten()
|
m,v,Y = m.flatten(), v.flatten(), Y.flatten()
|
||||||
|
|
||||||
#make a grid of points
|
#make a grid of points
|
||||||
X = gh_x[None,:]*np.sqrt(2.*v[:,None]) + m[:,None]
|
X = gh_x[None,:]*np.sqrt(2.*v[:,None]) + m[:,None]
|
||||||
logp = self.logpdf(X,Y[:,None])
|
|
||||||
|
|
||||||
p = np.clip(p, 1e-9, 1.-1e-9) # for numerical stability
|
#evaluate the likelhood for the grid. First ax indexes the data (and mu, var) and the second indexes the grid.
|
||||||
N = stats.norm.pdf(X)
|
# broadcast needs to be handled carefully.
|
||||||
F = np.log(p).dot(self.gh_w)
|
logp = self.logpdf(X,Y[:,None])
|
||||||
NoverP = N/p
|
dlogp_dx = self.dlogpdf_df(X, Y[:,None])
|
||||||
dF_dm = (NoverP*self.Ysign[:,None]).dot(self.gh_w)
|
d2logp_dx2 = self.d2logpdf_df2(X, Y[:,None])
|
||||||
dF_dv = -0.5*(NoverP**2 + NoverP*X).dot(self.gh_w)
|
|
||||||
|
#average over the gird to get derivatives of the Gaussian's parameters
|
||||||
|
F = np.dot(logp, gh_w)
|
||||||
|
dF_dm = np.dot(dlogp_dx, gh_w)
|
||||||
|
dF_dv = np.dot(d2logp_dx2, gh_w)/2.
|
||||||
|
|
||||||
return F, dF_dm, dF_dv
|
return F, dF_dm, dF_dv
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -352,7 +352,7 @@ class TestNoiseModels(object):
|
||||||
print model
|
print model
|
||||||
#print model._get_params()
|
#print model._get_params()
|
||||||
np.testing.assert_almost_equal(
|
np.testing.assert_almost_equal(
|
||||||
model.pdf(f.copy(), Y.copy()),
|
model.pdf(f.copy(), Y.copy()).prod(),
|
||||||
np.exp(model.logpdf(f.copy(), Y.copy()).sum())
|
np.exp(model.logpdf(f.copy(), Y.copy()).sum())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue