diff --git a/proeval/generator/core.py b/proeval/generator/core.py index 331ff01..5a8009e 100644 --- a/proeval/generator/core.py +++ b/proeval/generator/core.py @@ -405,6 +405,8 @@ def get_posterior_embedding( return posterior_mean.detach().cpu().numpy(), posterior_cov.detach().cpu().numpy() else: K_test_diag = torch.ones(phi_test_t.shape[0], device=device) + if kernel_type == "linear": + K_test_diag = torch.sum(phi_test_t ** 2, dim=1) v = torch.cholesky_solve(K_test_train.t(), L) posterior_var = K_test_diag - torch.sum(K_test_train * v.t(), dim=1) posterior_var = torch.clamp(posterior_var, min=1e-10) diff --git a/tests/test_bq_sampling.py b/tests/test_bq_sampling.py index 7783f2c..2aea093 100644 --- a/tests/test_bq_sampling.py +++ b/tests/test_bq_sampling.py @@ -48,6 +48,21 @@ def parameters(self): yield self._anchor +def test_linear_encoder_marginal_variance_matches_covariance(): + torch = pytest.importorskip("torch") + from proeval.generator.core import get_posterior_embedding + + phi = np.array([[0.0, 0.0], [0.2, -0.2], [1.0, -1.0]], dtype=np.float32) + args = ( + phi[[2]], np.array([1.0]), phi, 0.3, [2], + np.full(3, 0.5), _DummyLinearEncoder(torch), + ) + _, variance = get_posterior_embedding(*args) + _, covariance = get_posterior_embedding(*args, full_cov=True) + + np.testing.assert_allclose(variance, np.diag(covariance), atol=1e-6) + + def _run_active(kind, budget, n_init=0): features, labels, prior_mean, prior_cov = _synthetic_case() np.random.seed(7)