Skip to content

Commit ee06209

Browse files
esantorellafacebook-github-bot
authored andcommitted
Delete references to deprecated DeterministicPosterior and DeterministicSampler (#2391)
Summary: ## Motivation Delete references to deprecated DeterministicPosterior and DeterministicSampler, replacing `DeterministicPosterior` with `EnsemblePosterior` where appropriate. These were deprecated before 0.9.0, so now that we are past 0.11.0, they can be reaped. Pull Request resolved: #2391 Test Plan: Replaced `DeterministicPosterior` with `EnsemblePosterior` in tests ## Related PRs #1636 Reviewed By: Balandat Differential Revision: D59057165 Pulled By: esantorella fbshipit-source-id: 70a8405d0e75d414a685192808e8c0b18a6aca92
1 parent 32bdfda commit ee06209

File tree

10 files changed

+24
-208
lines changed

10 files changed

+24
-208
lines changed

botorch/posteriors/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
from botorch.posteriors.deterministic import DeterministicPosterior
87
from botorch.posteriors.fully_bayesian import (
98
FullyBayesianPosterior,
109
GaussianMixturePosterior,
@@ -18,7 +17,6 @@
1817
from botorch.posteriors.transformed import TransformedPosterior
1918

2019
__all__ = [
21-
"DeterministicPosterior",
2220
"GaussianMixturePosterior",
2321
"FullyBayesianPosterior",
2422
"GPyTorchPosterior",

botorch/posteriors/deterministic.py

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3,89 +3,3 @@
33
#
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
6-
7-
r"""
8-
Deterministic (degenerate) posteriors. Used in conjunction with deterministic
9-
models.
10-
"""
11-
12-
from __future__ import annotations
13-
14-
from typing import Optional
15-
from warnings import warn
16-
17-
import torch
18-
from botorch.posteriors.posterior import Posterior
19-
from torch import Tensor
20-
21-
22-
class DeterministicPosterior(Posterior):
23-
r"""Deterministic posterior.
24-
25-
[DEPRECATED] Use `EnsemblePosterior` instead.
26-
"""
27-
28-
def __init__(self, values: Tensor) -> None:
29-
r"""
30-
Args:
31-
values: Values of the samples produced by this posterior.
32-
"""
33-
warn(
34-
"`DeterministicPosterior` is marked for deprecation, consider using "
35-
"`EnsemblePosterior`.",
36-
DeprecationWarning,
37-
)
38-
self.values = values
39-
40-
@property
41-
def device(self) -> torch.device:
42-
r"""The torch device of the posterior."""
43-
return self.values.device
44-
45-
@property
46-
def dtype(self) -> torch.dtype:
47-
r"""The torch dtype of the posterior."""
48-
return self.values.dtype
49-
50-
def _extended_shape(
51-
self, sample_shape: torch.Size = torch.Size() # noqa: B008
52-
) -> torch.Size:
53-
r"""Returns the shape of the samples produced by the posterior with
54-
the given `sample_shape`.
55-
"""
56-
return sample_shape + self.values.shape
57-
58-
@property
59-
def mean(self) -> Tensor:
60-
r"""The mean of the posterior as a `(b) x n x m`-dim Tensor."""
61-
return self.values
62-
63-
@property
64-
def variance(self) -> Tensor:
65-
r"""The variance of the posterior as a `(b) x n x m`-dim Tensor.
66-
67-
As this is a deterministic posterior, this is a tensor of zeros.
68-
"""
69-
return torch.zeros_like(self.values)
70-
71-
def rsample(
72-
self,
73-
sample_shape: Optional[torch.Size] = None,
74-
) -> Tensor:
75-
r"""Sample from the posterior (with gradients).
76-
77-
For the deterministic posterior, this just returns the values expanded
78-
to the requested shape.
79-
80-
Args:
81-
sample_shape: A `torch.Size` object specifying the sample shape. To
82-
draw `n` samples, set to `torch.Size([n])`. To draw `b` batches
83-
of `n` samples each, set to `torch.Size([b, n])`.
84-
85-
Returns:
86-
Samples from the posterior, a tensor of shape
87-
`self._extended_shape(sample_shape=sample_shape)`.
88-
"""
89-
if sample_shape is None:
90-
sample_shape = torch.Size([1])
91-
return self.values.expand(self._extended_shape(sample_shape))

botorch/sampling/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
# LICENSE file in the root directory of this source tree.
66

77
from botorch.sampling.base import MCSampler
8-
from botorch.sampling.deterministic import DeterministicSampler
98
from botorch.sampling.get_sampler import get_sampler
109
from botorch.sampling.list_sampler import ListSampler
1110
from botorch.sampling.normal import IIDNormalSampler, SobolQMCNormalSampler
@@ -20,7 +19,6 @@
2019

2120

2221
__all__ = [
23-
"DeterministicSampler",
2422
"ForkedRNGSampler",
2523
"get_sampler",
2624
"IIDNormalSampler",

botorch/sampling/deterministic.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,3 @@
33
#
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
6-
7-
r"""
8-
A dummy sampler for use with deterministic models.
9-
"""
10-
11-
from __future__ import annotations
12-
13-
from botorch.posteriors.deterministic import DeterministicPosterior
14-
from botorch.sampling.stochastic_samplers import StochasticSampler
15-
16-
17-
class DeterministicSampler(StochasticSampler):
18-
r"""A sampler that simply calls `posterior.rsample`, intended to be used with
19-
`DeterministicModel` & `DeterministicPosterior`.
20-
21-
[DEPRECATED] - Use `IndexSampler` in conjunction with `EnsemblePosterior`
22-
instead of `DeterministicSampler` with `DeterministicPosterior`.
23-
24-
This is effectively signals that `StochasticSampler` is safe to use with
25-
deterministic models since their output is deterministic by definition.
26-
"""
27-
28-
def _update_base_samples(
29-
self, posterior: DeterministicPosterior, base_sampler: DeterministicSampler
30-
) -> None:
31-
r"""This is a no-op since there are no base samples to update.
32-
33-
Args:
34-
posterior: The posterior for which the base samples are constructed.
35-
base_sampler: The base sampler to retrieve the base samples from.
36-
"""
37-
return

botorch/sampling/get_sampler.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,13 @@
99

1010
import torch
1111
from botorch.logging import logger
12-
from botorch.posteriors.deterministic import DeterministicPosterior
1312
from botorch.posteriors.ensemble import EnsemblePosterior
1413
from botorch.posteriors.gpytorch import GPyTorchPosterior
1514
from botorch.posteriors.posterior import Posterior
1615
from botorch.posteriors.posterior_list import PosteriorList
1716
from botorch.posteriors.torch import TorchPosterior
1817
from botorch.posteriors.transformed import TransformedPosterior
1918
from botorch.sampling.base import MCSampler
20-
from botorch.sampling.deterministic import DeterministicSampler
2119
from botorch.sampling.index_sampler import IndexSampler
2220
from botorch.sampling.list_sampler import ListSampler
2321
from botorch.sampling.normal import (
@@ -119,16 +117,6 @@ def _get_sampler_list(
119117
return ListSampler(*samplers)
120118

121119

122-
@GetSampler.register(DeterministicPosterior)
123-
def _get_sampler_deterministic(
124-
posterior: DeterministicPosterior,
125-
sample_shape: torch.Size,
126-
seed: Optional[int] = None,
127-
) -> MCSampler:
128-
r"""Get the dummy `DeterministicSampler` for the `DeterministicPosterior`."""
129-
return DeterministicSampler(sample_shape=sample_shape, seed=seed)
130-
131-
132120
@GetSampler.register(EnsemblePosterior)
133121
def _get_sampler_ensemble(
134122
posterior: EnsemblePosterior,

test/models/test_model.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from botorch.exceptions.errors import InputDataError
1111
from botorch.models.deterministic import GenericDeterministicModel
1212
from botorch.models.model import Model, ModelDict, ModelList
13-
from botorch.posteriors.deterministic import DeterministicPosterior
13+
from botorch.posteriors.ensemble import EnsemblePosterior
1414
from botorch.posteriors.posterior_list import PosteriorList
1515
from botorch.utils.datasets import SupervisedDataset
1616
from botorch.utils.testing import BotorchTestCase, MockModel, MockPosterior
@@ -35,7 +35,10 @@ def evaluate(self, Y):
3535

3636
def forward(self, posterior):
3737
return PosteriorList(
38-
*[DeterministicPosterior(2 * p.mean + 1) for p in posterior.posteriors]
38+
*[
39+
EnsemblePosterior(2 * p.mean.unsqueeze(0) + 1)
40+
for p in posterior.posteriors
41+
]
3942
)
4043

4144

test/posteriors/test_deterministic.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,3 @@
33
#
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
6-
7-
import itertools
8-
9-
from warnings import catch_warnings
10-
11-
import torch
12-
from botorch.posteriors.deterministic import DeterministicPosterior
13-
from botorch.utils.testing import BotorchTestCase
14-
15-
16-
class TestDeterministicPosterior(BotorchTestCase):
17-
def test_DeterministicPosterior(self):
18-
for shape, dtype in itertools.product(
19-
((3, 2), (2, 3, 1)), (torch.float, torch.double)
20-
):
21-
values = torch.randn(*shape, device=self.device, dtype=dtype)
22-
p = DeterministicPosterior(values)
23-
with catch_warnings(record=True) as ws:
24-
p = DeterministicPosterior(values)
25-
self.assertTrue(
26-
any("marked for deprecation" in str(w.message) for w in ws)
27-
)
28-
self.assertEqual(p.device.type, self.device.type)
29-
self.assertEqual(p.dtype, dtype)
30-
self.assertEqual(p._extended_shape(), values.shape)
31-
with self.assertRaises(NotImplementedError):
32-
p.base_sample_shape
33-
self.assertTrue(torch.equal(p.mean, values))
34-
self.assertTrue(torch.equal(p.variance, torch.zeros_like(values)))
35-
# test sampling
36-
samples = p.rsample()
37-
self.assertTrue(torch.equal(samples, values.unsqueeze(0)))
38-
samples = p.rsample(torch.Size([2]))
39-
self.assertTrue(torch.equal(samples, values.expand(2, *values.shape)))

test/posteriors/test_posterior.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import torch
1111
from botorch.posteriors import GPyTorchPosterior, Posterior, PosteriorList
12-
from botorch.posteriors.deterministic import DeterministicPosterior
12+
from botorch.posteriors.ensemble import EnsemblePosterior
1313
from botorch.utils.testing import BotorchTestCase
1414
from gpytorch.distributions import MultivariateNormal
1515
from linear_operator.operators import to_linear_operator
@@ -57,7 +57,7 @@ def _make_gpytorch_posterior(self, shape, dtype):
5757

5858
def _make_deterministic_posterior(self, shape, dtype):
5959
mean = torch.rand(*shape, 1, dtype=dtype, device=self.device)
60-
return DeterministicPosterior(values=mean)
60+
return EnsemblePosterior(values=mean.unsqueeze(0))
6161

6262
def test_posterior_list(self):
6363
for dtype, use_deterministic in product(

test/sampling/test_deterministic.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,3 @@
33
#
44
# This source code is licensed under the MIT license found in the
55
# LICENSE file in the root directory of this source tree.
6-
7-
import torch
8-
from botorch.sampling.deterministic import DeterministicSampler
9-
from botorch.utils.testing import BotorchTestCase, MockPosterior
10-
11-
12-
class TestDeterministicSampler(BotorchTestCase):
13-
def test_deterministic_sampler(self):
14-
# Basic usage.
15-
samples = torch.rand(1, 2)
16-
posterior = MockPosterior(samples=samples)
17-
sampler = DeterministicSampler(sample_shape=torch.Size([2]))
18-
self.assertTrue(torch.equal(samples.repeat(2, 1, 1), sampler(posterior)))
19-
20-
# Test _update_base_samples.
21-
sampler._update_base_samples(
22-
posterior=posterior,
23-
base_sampler=sampler,
24-
)

test/sampling/test_get_sampler.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
# LICENSE file in the root directory of this source tree.
66

77
import torch
8-
from botorch.posteriors.deterministic import DeterministicPosterior
98
from botorch.posteriors.gpytorch import GPyTorchPosterior
109
from botorch.posteriors.posterior_list import PosteriorList
1110
from botorch.posteriors.torch import TorchPosterior
1211
from botorch.posteriors.transformed import TransformedPosterior
1312
from botorch.sampling.get_sampler import get_sampler
1413
from botorch.sampling.list_sampler import ListSampler
1514
from botorch.sampling.normal import IIDNormalSampler, SobolQMCNormalSampler
16-
from botorch.sampling.stochastic_samplers import StochasticSampler
1715
from botorch.utils.testing import BotorchTestCase
1816
from gpytorch.distributions import MultivariateNormal
1917
from torch.distributions.gamma import Gamma
@@ -22,40 +20,42 @@
2220
class TestGetSampler(BotorchTestCase):
2321
def test_get_sampler(self):
2422
# Basic usage w/ gpytorch posterior.
25-
posterior = GPyTorchPosterior(
23+
mvn_posterior = GPyTorchPosterior(
2624
distribution=MultivariateNormal(torch.rand(2), torch.eye(2))
2725
)
26+
seed = 2
27+
n_samples = 10
2828
sampler = get_sampler(
29-
posterior=posterior, sample_shape=torch.Size([10]), seed=2
29+
posterior=mvn_posterior, sample_shape=torch.Size([n_samples]), seed=seed
3030
)
3131
self.assertIsInstance(sampler, SobolQMCNormalSampler)
32-
self.assertEqual(sampler.seed, 2)
33-
self.assertEqual(sampler.sample_shape, torch.Size([10]))
32+
self.assertEqual(sampler.seed, seed)
33+
self.assertEqual(sampler.sample_shape, torch.Size([n_samples]))
3434

3535
# Fallback to IID sampler.
36-
posterior = GPyTorchPosterior(
36+
big_mvn_posterior = GPyTorchPosterior(
3737
distribution=MultivariateNormal(torch.rand(22000), torch.eye(22000))
3838
)
39-
sampler = get_sampler(posterior=posterior, sample_shape=torch.Size([10]))
39+
sampler = get_sampler(
40+
posterior=big_mvn_posterior, sample_shape=torch.Size([n_samples])
41+
)
4042
self.assertIsInstance(sampler, IIDNormalSampler)
41-
self.assertEqual(sampler.sample_shape, torch.Size([10]))
43+
self.assertEqual(sampler.sample_shape, torch.Size([n_samples]))
4244

4345
# Transformed posterior.
4446
tf_post = TransformedPosterior(
45-
posterior=posterior, sample_transform=lambda X: X
47+
posterior=big_mvn_posterior, sample_transform=lambda X: X
4648
)
47-
sampler = get_sampler(posterior=tf_post, sample_shape=torch.Size([10]))
49+
sampler = get_sampler(posterior=tf_post, sample_shape=torch.Size([n_samples]))
4850
self.assertIsInstance(sampler, IIDNormalSampler)
49-
self.assertEqual(sampler.sample_shape, torch.Size([10]))
51+
self.assertEqual(sampler.sample_shape, torch.Size([n_samples]))
5052

51-
# PosteriorList with transformed & deterministic.
52-
post_list = PosteriorList(
53-
tf_post, DeterministicPosterior(values=torch.rand(1, 2))
54-
)
53+
# PosteriorList with transformed & original
54+
post_list = PosteriorList(tf_post, mvn_posterior)
5555
sampler = get_sampler(posterior=post_list, sample_shape=torch.Size([5]))
5656
self.assertIsInstance(sampler, ListSampler)
5757
self.assertIsInstance(sampler.samplers[0], IIDNormalSampler)
58-
self.assertIsInstance(sampler.samplers[1], StochasticSampler)
58+
self.assertIsInstance(sampler.samplers[1], SobolQMCNormalSampler)
5959
for s in sampler.samplers:
6060
self.assertEqual(s.sample_shape, torch.Size([5]))
6161

0 commit comments

Comments
 (0)