49 using namespace Eigen;
83 "The provided likelihood model is not a variational dual Likelihood model.\n");
99 void CKLDualInferenceMethod::init()
105 "Square root of noise matrix W",
108 "the gradient of the variational expection wrt sigma2",
111 "the gradient of the variational expection wrt mu",
113 SG_ADD(&m_is_dual_valid,
"is_dual_valid",
114 "whether the lambda (m_W) is valid or not",
116 m_is_dual_valid=
false;
128 if (!m_is_dual_valid)
134 eigen_alpha=-eigen_alpha;
136 Map<VectorXd> eigen_sW(m_sW.
vector, m_sW.
vlen);
137 eigen_sW=eigen_W.array().sqrt().matrix();
144 eigen_V=eigen_L.triangularView<Upper>().adjoint().solve(eigen_sW.asDiagonal()*eigen_K*
CMath::sq(
m_scale));
148 eigen_s2=(eigen_K.diagonal().array()*
CMath::sq(
m_scale)-(eigen_V.array().pow(2).colwise().sum().transpose())).abs().matrix();
152 Map<VectorXd> eigen_mean(mean.
vector, mean.
vlen);
160 if (!m_is_dual_valid)
164 Map<VectorXd> eigen_mean(mean.
vector, mean.
vlen);
172 float64_t result=0.5*eigen_alpha.dot(eigen_mu-eigen_mean)+a;
173 result+=eigen_mean.
dot(eigen_alpha);
174 result-=eigen_L.diagonal().array().
log().sum();
182 "The length of gradients (%d) should the same as the length of parameters (%d)\n",
185 if (!m_is_dual_valid)
188 Map<VectorXd> eigen_gradient(gradient.
vector, gradient.
vlen);
194 Map<VectorXd> eigen_d_lambda(d_lambda.
vector, d_lambda.
vlen);
199 eigen_gradient=-eigen_mu-0.5*eigen_s2+eigen_d_lambda;
205 Map<VectorXd> eigen_alpha(alpha.
vector, alpha.
vlen);
210 Map<VectorXd> eigen_mean(mean.
vector, mean.
vlen);
215 Map<VectorXd> eigen_lab(lab.
vector, lab.
vlen);
222 MatrixXd eigen_t=eigen_L.triangularView<Upper>().adjoint().solve(MatrixXd::Identity(eigen_L.rows(),eigen_L.cols()));
224 for(
index_t idx=0; idx<eigen_t.rows(); idx++)
225 trace +=(eigen_t.col(idx).array().pow(2)).sum();
228 float64_t result=-a+eigen_L.diagonal().array().
log().sum();
230 result+=0.5*(-eigen_K.rows()+eigen_alpha.dot(eigen_mu-eigen_mean)+trace);
246 Map<VectorXd> eigen_sW(m_sW.
vector, m_sW.
vlen);
250 Map<VectorXd> eigen_dv(m_dv.
vector, m_dv.
vlen);
251 Map<VectorXd> eigen_df(m_df.
vector, m_df.
vlen);
255 MatrixXd eigen_U=eigen_L.triangularView<Upper>().adjoint().solve(MatrixXd(eigen_sW.asDiagonal()));
258 MatrixXd eigen_A=MatrixXd::Identity(len, len)-eigen_V.transpose()*eigen_U;
261 MatrixXd AdK=eigen_A*eigen_dK;
264 VectorXd z=AdK.diagonal()+(eigen_A.array()*AdK.array()).rowwise().sum().matrix()
265 -(eigen_A.transpose().array()*AdK.array()).colwise().sum().transpose().matrix();
267 float64_t result=eigen_alpha.dot(eigen_dK*(eigen_alpha/2.0-eigen_df))-z.dot(eigen_dv);
285 Map<VectorXd> eigen_W(W_tmp.
vector, W_tmp.
vlen);
288 Map<VectorXd> eigen_sW(sW_tmp.
vector, sW_tmp.
vlen);
289 eigen_sW=eigen_W.array().sqrt().matrix();
297 Map<VectorXd> eigen_alpha(alpha_tmp.
vector, alpha_tmp.
vlen);
298 eigen_alpha=-eigen_alpha;
301 Map<VectorXd> eigen_mean(mean.
vector, mean.
vlen);
303 Map<VectorXd> eigen_mu(mu_tmp.
vector, mu_tmp.
vlen);
307 MatrixXd eigen_V=eigen_L.triangularView<Upper>().adjoint().solve(eigen_sW.asDiagonal()*eigen_K*
CMath::sq(
m_scale));
309 Map<VectorXd> eigen_s2(s2_tmp.
vector, s2_tmp.
vlen);
310 eigen_s2=(eigen_K.diagonal().array()*
CMath::sq(
m_scale)-(eigen_V.array().pow(2).colwise().sum().transpose())).abs().matrix();
314 nlml_def=get_nlml_wrapper(alpha_tmp, mu_tmp, L_tmp);
316 if (nlml_new<=nlml_def)
350 float64_t CKLDualInferenceMethod::adjust_step(
void *obj,
378 obj_prt->lbfgs_precompute();
379 float64_t nlml=obj_prt->get_dual_objective_wrt_parameters();
381 SGVector<float64_t> sg_gradient(gradient, dim,
false);
382 Map<VectorXd> eigen_g(sg_gradient.vector, sg_gradient.vlen);
383 obj_prt->get_gradient_of_dual_objective_wrt_parameters(sg_gradient);
409 void * obj_prt =
static_cast<void *
>(
this);
413 CKLDualInferenceMethod::evaluate,
414 NULL, obj_prt, &lbfgs_param, CKLDualInferenceMethod::adjust_step);
float64_t m_orthantwise_c
static float64_t dot(const bool *v1, const bool *v2, int32_t n)
compute dot product between v1 and v2 (blas optimized)
virtual CDualVariationalGaussianLikelihood * get_dual_variational_likelihood() const
SGVector< float64_t > m_alpha
int32_t lbfgs(int32_t n, float64_t *x, float64_t *ptr_fx, lbfgs_evaluate_t proc_evaluate, lbfgs_progress_t proc_progress, void *instance, lbfgs_parameter_t *_param, lbfgs_adjust_step_t proc_adjust_step)
static SGMatrix< float64_t > get_choleksy(SGVector< float64_t > W, SGVector< float64_t > sW, SGMatrix< float64_t > kernel, float64_t scale)
virtual SGVector< float64_t > get_mu_dual_parameter() const =0
The class Labels models labels, i.e. class assignments of objects.
static const float64_t INFTY
infinity
virtual int32_t get_num_labels() const =0
static T sum(T *vec, int32_t len)
return sum(vec)
static SGMatrix< float64_t > get_inverse(SGMatrix< float64_t > L, SGMatrix< float64_t > kernel, SGVector< float64_t > sW, SGMatrix< float64_t > V, float64_t scale)
void log()
natural logarithm of vector elements
virtual bool dual_parameters_valid() const
TParameter * get_parameter(int32_t idx)
virtual SGVector< float64_t > get_dual_objective_value()=0
virtual SGVector< float64_t > get_mean_vector(const CFeatures *features) const =0
An abstract class of the mean function.
virtual float64_t adjust_step_wrt_dual_parameter(SGVector< float64_t > direction, const float64_t step) const
virtual void lbfgs_precompute()
virtual float64_t lbfgs_optimization()
SGMatrix< float64_t > m_Sigma
virtual void check_dual_inference(CLikelihoodModel *mod) const
The dual KL approximation inference method class.
virtual void update_chol()
SGMatrix< float64_t > m_L
void set_model(CLikelihoodModel *mod)
virtual void get_gradient_of_dual_objective_wrt_parameters(SGVector< float64_t > gradient)
virtual void update_approx_cov()
virtual SGVector< float64_t > get_alpha()
virtual float64_t get_derivative_related_cov(Eigen::MatrixXd eigen_dK)
virtual SGVector< float64_t > get_dual_first_derivative(const TParameter *param) const =0
virtual void update_deriv()
The KL approximation inference method class.
virtual SGVector< float64_t > get_variational_expection()
virtual void set_dual_parameters(SGVector< float64_t > lambda, const CLabels *lab)
The class Features is the base class of all feature objects.
SGVector< float64_t > m_mu
SGVector< float64_t > m_s2
Binary Labels for binary classification.
virtual void set_variational_distribution(SGVector< float64_t > mu, SGVector< float64_t > s2, const CLabels *lab)
virtual float64_t get_dual_objective_wrt_parameters()
virtual void update_alpha()
virtual float64_t get_negative_log_marginal_likelihood_helper()
virtual SGVector< float64_t > get_diagonal_vector()
virtual SGVector< float64_t > get_variational_first_derivative(const TParameter *param) const
virtual void set_model(CLikelihoodModel *mod)
virtual bool parameter_hash_changed()
Class that models dual variational likelihood.
The Likelihood model base class.
SGMatrix< float64_t > m_ktrtr
CLikelihoodModel * m_model
virtual ~CKLDualInferenceMethod()