diff --git a/GPy/core/parameterization/variational.py b/GPy/core/parameterization/variational.py index cd2ecf53..1dbd205b 100644 --- a/GPy/core/parameterization/variational.py +++ b/GPy/core/parameterization/variational.py @@ -36,91 +36,6 @@ class NormalPrior(VariationalPrior): variational_posterior.mean.gradient -= variational_posterior.mean variational_posterior.variance.gradient -= (1. - (1. / (variational_posterior.variance))) * 0.5 -class GmmNormalPrior(VariationalPrior): - def __init__(self, px_mu, px_var, pi, n_component, variational_pi, name="GMMNormalPrior", **kw): - super(GmmNormalPrior, self).__init__(name=name, **kw) - self.n_component = n_component - - self.px_mu = Param('mu_k', px_mu) - self.px_var = Param('var_k', px_var) - - # Make sure they sum to one - variational_pi = variational_pi / np.sum(variational_pi) - pi = pi / np.sum(pi) - - self.pi = pi # p(x) mixing coeffients - self.variational_pi = Param('variational_pi', variational_pi) # variational mixing coefficients - - self.check_all_weights() - - self.link_parameter(self.px_mu) - self.link_parameter(self.px_var) - self.link_parameter(self.variational_pi) - self.variational_pi.constrain_bounded(0.0, 1.0) - - self.stop = 5 - - def KL_divergence(self, variational_posterior): - # Lagrange multiplier maybe also needed here - - # var_mean = np.square(variational_posterior.mean).sum() - # var_S = (variational_posterior.variance - np.log(variational_posterior.variance)).sum() - # return 0.5 * (var_mean + var_S) - 0.5 * variational_posterior.input_dim * variational_posterior.num_data - - mu = variational_posterior.mean - S = variational_posterior.variance - pi = self.variational_pi - total_n = variational_posterior.input_dim * variational_posterior.num_data - - cita = np.zeros(4) - for i in range(self.n_component): - cita[0] += (pi[i] * np.log(self.px_var[i])).sum() - cita[1] += (pi[i] * S / self.px_var[i]).sum() - cita[2] += (pi[i] * np.square(mu - self.px_mu[i]) / self.px_var[i]).sum() - cita[3] += (pi[i] * np.log(self.pi / pi[i])).sum() - return 0.5 * (cita[0] - (np.log(S)).sum() + cita[1]) + 0.5 * (cita[2] - total_n) + cita[3] - - def update_gradients_KL(self, variational_posterior): - # import pdb; pdb.set_trace() # breakpoint 1 - # print("Updating Gradients") - # if self.stop<1: - # return - # self.stop-=1 - #dL: - #variational_posterior.mean.gradient -= variational_posterior.mean - #variational_posterior.variance.gradient -= (1. - (1. / (variational_posterior.variance))) * 0.5 - - - mu = variational_posterior.mean - S = variational_posterior.variance - pi = self.variational_pi - - cita_0 = np.zeros(mu.shape) - cita_1 = np.zeros(mu.shape) - cita_2 = np.zeros(mu.shape) - cita_3 = np.zeros(pi.shape) - for i in range(self.n_component): - cita_0 += pi.values[i] * (mu - self.px_mu.values[i]) / self.px_var.values[i] - cita_1 += (pi[i] / self.px_var[i]) - cita_2 += pi[i] * (S + np.square(mu - self.px_mu[i])) / np.square(self.px_var[i]) - self.px_mu[i].gradient += pi[i] * (mu - self.px_mu[i]) / self.px_var[i] - self.px_var[i].gradient += (pi[i] * (S + np.square(mu - self.px_mu[i])) / np.square(self.px_var[i]) - (pi[i] / self.px_var[i])) * 0.5 - cita_3[i] = (np.log(self.px_var[i]).sum() + (S / self.px_var[i]).sum()+ (np.square(mu - self.px_mu[i]) / self.px_var[i]).sum() )* (-0.5) + np.log(self.pi[i] / pi[i]) - 1 - # self.variational_pi[i].gradient += cita_3[i] - - variational_posterior.mean.gradient -= cita_0 - variational_posterior.variance.gradient += (1. / (S) - cita_1) * 0.5 - self.variational_pi.gradient +=cita_3 - - def check_weights(self, weights): - assert weights.min() >= 0.0 - assert weights.max() <= 1.0 - assert weights.sum() == 1.0 - - def check_all_weights(self): - self.check_weights(self.variational_pi) - self.check_weights(self.pi) - class SpikeAndSlabPrior(VariationalPrior): def __init__(self, pi=None, learnPi=False, variance = 1.0, group_spike=False, name='SpikeAndSlabPrior', **kw): super(SpikeAndSlabPrior, self).__init__(name=name, **kw)