Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Batch shape missing in TransformedPosterior #1623

Closed
roussel-ryan opened this issue Jan 9, 2023 · 4 comments
Closed

[Bug] Batch shape missing in TransformedPosterior #1623

roussel-ryan opened this issue Jan 9, 2023 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@roussel-ryan
Copy link
Contributor

roussel-ryan commented Jan 9, 2023

🐛 Bug

I'm getting an error when using Bilog, Power transformations (which return TransformedPosterior objects) with qNoisyExpectedHypervolumeImprovement. Works fine with transforms that return GPyTorchPosterior objects.

To reproduce

** Code snippet to reproduce **

import torch
from botorch.acquisition.multi_objective import qNoisyExpectedHypervolumeImprovement
from botorch.models import SingleTaskGP, ModelList
from botorch.fit import fit_gpytorch_mll
from botorch.utils import standardize
from gpytorch.mlls import ExactMarginalLogLikelihood
from botorch.models.transforms.outcome import Bilog, Standardize, Log

train_X = torch.rand(10, 2)
Y = 1 - torch.norm(train_X - 0.5, dim=-1, keepdim=True)
Y = Y + 0.1 * torch.randn_like(Y)  # add some noise
train_Y = standardize(Y)

standard_transform = Standardize(m=1)
bilog_transform = Bilog()

# try each transform
for transform in [standard_transform, bilog_transform]:
    gp = SingleTaskGP(train_X, train_Y, outcome_transform=transform)
    mll = ExactMarginalLogLikelihood(gp.likelihood, gp)
    fit_gpytorch_mll(mll)

    ml = ModelList(gp,gp)

    acq = qNoisyExpectedHypervolumeImprovement(
        model=ml,
        X_baseline=train_X,
        cache_root=False,
        ref_point=torch.zeros(2)
    )

    test_x = torch.rand(10,1,2)
    print(f"{transform}: {acq(test_x)}")

** Stack trace/error message **

Traceback (most recent call last):
  File "C:\Users\Ryan Roussel\AppData\Roaming\JetBrains\PyCharm2022.3\scratches\scratch_19.py", line 26, in <module>
    acq = qNoisyExpectedHypervolumeImprovement(
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\acquisition\multi_objective\monte_carlo.py", line 515, in __init__
    self._set_cell_bounds(num_new_points=X_baseline.shape[0])
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\acquisition\multi_objective\monte_carlo.py", line 572, in _set_cell_bounds
    self._set_sampler(q_in=num_new_points * n_w, posterior=posterior)
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\acquisition\cached_cholesky.py", line 159, in _set_sampler
    self.sampler._update_base_samples(
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\sampling\list_sampler.py", line 68, in _update_base_samples
    s._update_base_samples(posterior=p, base_sampler=bs)
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\sampling\normal.py", line 116, in _update_base_samples
    len(posterior.base_sample_shape) - len(posterior.batch_shape)
AttributeError: 'TransformedPosterior' object has no attribute 'batch_shape'

Expected Behavior

Successful evaluation of acquisition function

System information

Please complete the following information:

  • Botorch 0.8.1
  • GPyTorch 1.9.1
  • Pytorch 1.12.1
  • Windows

Additional context

Add any other context about the problem here.

@roussel-ryan roussel-ryan added the bug Something isn't working label Jan 9, 2023
@saitcakmak
Copy link
Contributor

This should be using the batch shape of the underlying posterior. I'll put up a fix in a bit.

@roussel-ryan
Copy link
Contributor Author

Great! There might be a related shape issue when using a ModuleListGP and a custom ListSampler, use this code to reproduce

import torch
from botorch.acquisition.multi_objective import qNoisyExpectedHypervolumeImprovement
from botorch.fit import fit_gpytorch_mll
from botorch.models import ModelList, SingleTaskGP
from botorch.models.transforms.input import Normalize
from botorch.models.transforms.outcome import Bilog, Log, Power, Standardize
from botorch.sampling import ListSampler, SobolQMCNormalSampler
from botorch.utils import standardize
from gpytorch.mlls import ExactMarginalLogLikelihood

train_X = torch.rand(10, 2)
Y = 1 - torch.norm(train_X - 0.5, dim=-1, keepdim=True)
Y = Y + 0.1 * torch.randn_like(Y)  # add some noise
train_Y = standardize(Y)

imput_normalize = Normalize(d=2)
standard_transform = Standardize(m=1)

# define ref point
ref = torch.zeros(2)

# try each transform
for transform in [standard_transform]:
    gp = SingleTaskGP(
        train_X, train_Y, input_transform=imput_normalize, outcome_transform=transform
    )
    mll = ExactMarginalLogLikelihood(gp.likelihood, gp)
    fit_gpytorch_mll(mll)

    ml = ModelList(gp, gp)

    sampler = ListSampler(
        *[
            SobolQMCNormalSampler(sample_shape=128)
            for _ in range(ml.num_outputs)
        ]
    )

    acq = qNoisyExpectedHypervolumeImprovement(
        model=ml,
        ref_point=ref,
        X_baseline=torch.tensor([]).reshape(0, 2),
        sampler=sampler,
        cache_root=False,
    )

    test_x = torch.rand(10, 1, 2)
    print(f"{transform}: {acq(test_x)}")

Traceback:

Traceback (most recent call last):
  File "C:\Users\Ryan Roussel\AppData\Roaming\JetBrains\PyCharm2022.3\scratches\scratch_19.py", line 44, in <module>
    acq = qNoisyExpectedHypervolumeImprovement(
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\acquisition\multi_objective\monte_carlo.py", line 515, in __init__
    self._set_cell_bounds(num_new_points=X_baseline.shape[0])
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\botorch\acquisition\multi_objective\monte_carlo.py", line 587, in _set_cell_bounds
    self.sampler.sample_shape
  File "C:\ProgramData\Miniconda3\envs\xopt\lib\site-packages\torch\nn\modules\module.py", line 1207, in __getattr__
    raise AttributeError("'{}' object has no attribute '{}'".format(
AttributeError: 'ListSampler' object has no attribute 'sample_shape'

I can open a separate issue if you'd like, but I didn't want to add to much to the issues queue

@saitcakmak
Copy link
Contributor

Nice edge case. I'll put up a fix for that as well

saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 9, 2023
…mples

Summary: See pytorch#1623. This is the only use case for `posterior.batch_shape`, so fixing it locally makes sense to me.

Differential Revision: D42421494

fbshipit-source-id: 613ab2aa822d53fda615b53979fba857c9b9c931
saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 9, 2023
Summary:
In some cases, we access sampler.sample_shape, which errors out with ListSampler. This adds a property that returns the sample shape of the underlying samplers.

See pytorch#1623 (comment)

Differential Revision: D42421646

fbshipit-source-id: 826f1d236bafab1fdf8b7e6debc328f2104cfa06
saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 9, 2023
…mples

Summary: See pytorch#1623. This is the only use case for `posterior.batch_shape`, so fixing it locally makes sense to me.

Differential Revision: D42421494

fbshipit-source-id: 76758b736e4769a7363f61a945c47fba436e3c79
@saitcakmak saitcakmak self-assigned this Jan 9, 2023
saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 9, 2023
Summary:
Pull Request resolved: pytorch#1624

In some cases, we access sampler.sample_shape, which errors out with ListSampler. This adds a property that returns the sample shape of the underlying samplers.

See pytorch#1623 (comment)

Differential Revision: D42421646

fbshipit-source-id: ce6053edab6ed9450d7c06f57defff556ae2a63f
saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 9, 2023
…mples (pytorch#1625)

Summary:
Pull Request resolved: pytorch#1625

See pytorch#1623. This is the only use case for `posterior.batch_shape`, so fixing it locally makes sense to me.

Differential Revision: D42421494

fbshipit-source-id: 6de08cf0aee948a29f8e128cbded850e2d507608
saitcakmak added a commit to saitcakmak/botorch that referenced this issue Jan 11, 2023
…mples (pytorch#1625)

Summary:
Pull Request resolved: pytorch#1625

See pytorch#1623. This is the only use case for `posterior.batch_shape`, so fixing it locally makes sense to me.

Reviewed By: Balandat

Differential Revision: D42421494

fbshipit-source-id: 2f6afc41c573419e9aa979f34036b7e30a6802d4
facebook-github-bot pushed a commit that referenced this issue Jan 11, 2023
Summary:
Pull Request resolved: #1624

In some cases, we access sampler.sample_shape, which errors out with ListSampler. This adds a property that returns the sample shape of the underlying samplers.

See #1623 (comment)

Reviewed By: Balandat

Differential Revision: D42421646

fbshipit-source-id: 5e1eddfdb04ecd2cedf8b721d30abd8e1f0c4579
facebook-github-bot pushed a commit that referenced this issue Jan 11, 2023
…mples (#1625)

Summary:
Pull Request resolved: #1625

See #1623. This is the only use case for `posterior.batch_shape`, so fixing it locally makes sense to me.

Reviewed By: Balandat

Differential Revision: D42421494

fbshipit-source-id: def6180343b363ddce01aede2bbc5892fb2cc99a
@saitcakmak
Copy link
Contributor

Closing this as both issues got fixed by the linked PRs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants