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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Issues with qKG.evaluate() #587

Closed
saitcakmak opened this issue Oct 26, 2020 · 6 comments
Closed

[Bug] Issues with qKG.evaluate() #587

saitcakmak opened this issue Oct 26, 2020 · 6 comments
Labels
bug Something isn't working

Comments

@saitcakmak
Copy link
Contributor

saitcakmak commented Oct 26, 2020

馃悰 Bug

i) This line raises an AttributeError with models that do not have an _input_batch_shape attribute. (#578 as an example)

batch_shape = acq_function.model._input_batch_shape

ii) Since it is a subclass of qKnowledgeGradient, qMultiFidelityKnowledgeGradient has evaluate method implemented. However, the current implementation ignores the project operator in the inner optimization, and may produce buggy output.

Expected Behavior

i) The batch shape could be inferred from model.train_inputs batch shape. My observation is _input_batch_shape = model.train_inputs[0].shape[:-2], but I am not sure if this is always true. If this is true, a simple try/except should do it.

ii) It should either raise a NotImplementedError, or be modified to accommodate the project operator.

@saitcakmak saitcakmak added the bug Something isn't working label Oct 26, 2020
@saitcakmak
Copy link
Contributor Author

To add to this, gen_one_shot_kg_initial_conditions ignores the project operator as well.

@Balandat
Copy link
Contributor

Thanks for raising this.

The batch shape could be inferred from model.train_inputs batch shape. My observation is _input_batch_shape = model.train_inputs[0].shape[:-2], but I am not sure if this is always true. If this is true, a simple try/except should do it.

I think rather than doing something ad-hoc in the initializer, the proper thing to do here is to add a batch_shape property to GPyTorchModel (or even Model), similar to num_outputs. Then we should be able to use that transparently everywhere.

It should either raise a NotImplementedError, or be modified to accommodate the project operator.

Good point. I think the most logical thing to do would be to somehow incorporate the projection operation as part of the value_function - that way we don't have to manually project the X whenever we need to evaluate the value function.

Let me see what I can come up with here.

Balandat added a commit to Balandat/botorch that referenced this issue Oct 29, 2020
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See pytorch#587 for more context.
Balandat added a commit to Balandat/botorch that referenced this issue Oct 29, 2020
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See pytorch#587 for more context.
@saitcakmak
Copy link
Contributor Author

I see that you put up #588 for the batch shape. For the project issue, I was thinking a wrapper like this may work:

class ProjectedValueFunction(AcquisitionFunction):
    def __init__(
            self,
            base_value_function: AcquisitionFunction,
            project: Callable[[Tensor], Tensor]
    ):
        self.base_value_function = base_value_function
        self.project = project

    def forward(self, X: Tensor) -> Tensor:
        return self.base_value_function(self.project(X))


def _get_value_function(
    model: Model,
    objective: Optional[Union[MCAcquisitionObjective, ScalarizedObjective]] = None,
    sampler: Optional[MCSampler] = None,
    project: Optional[Callable[[Tensor], Tensor]] = None,
) -> AcquisitionFunction:
    r"""Construct value function (i.e. inner acquisition function)."""
    if isinstance(objective, MCAcquisitionObjective):
        base_value_function = qSimpleRegret(
            model=model, sampler=sampler, objective=objective)
    else:
        base_value_function = PosteriorMean(model=model, objective=objective)
    if project is None:
        return base_value_function
    else:
        return ProjectedValueFunction(base_value_function, project)

@Balandat
Copy link
Contributor

Yeah this seems quite reasonable to me. @danielrjiang any thoughts?

@danielrjiang
Copy link
Contributor

Thanks @saitcakmak, seems pretty useful to me too.

@saitcakmak
Copy link
Contributor Author

Cool, I鈥檒l put up a PR soon.

Balandat added a commit to Balandat/botorch that referenced this issue Nov 19, 2020
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See pytorch#587 for more context.
Balandat added a commit to Balandat/botorch that referenced this issue Nov 19, 2020
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See pytorch#587 for more context.
Balandat added a commit to Balandat/botorch that referenced this issue Nov 24, 2020
Summary:
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See pytorch#587 for more context.

Pull Request resolved: pytorch#588

Differential Revision: D24622409

Pulled By: Balandat

fbshipit-source-id: 471a49eb0bdbb742b24a27b3a1bdd64efb7039bb
facebook-github-bot pushed a commit that referenced this issue Dec 8, 2020
Summary:
A consistent API like this will be useful and avoid ad-hoc inferring of batch shapes. See #587 for more context.

Pull Request resolved: #588

Reviewed By: qingfeng10

Differential Revision: D24622409

Pulled By: Balandat

fbshipit-source-id: 627c102cdf3f98637c30c96ef1766f907a951797
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
Development

Successfully merging a pull request may close this issue.

3 participants