Skip to content

Commit

Permalink
fix chebyshev scalariztaion
Browse files Browse the repository at this point in the history
Summary: See pytorch#1614

Differential Revision: D42373368

fbshipit-source-id: 0a1417d8865c943851430866df4f9369d0e21bf0
  • Loading branch information
sdaulton authored and facebook-github-bot committed Jan 5, 2023
1 parent b730a5f commit 90997db
Showing 1 changed file with 8 additions and 5 deletions.
13 changes: 8 additions & 5 deletions botorch/utils/multi_objective/scalarization.py
Expand Up @@ -32,13 +32,15 @@ def get_chebyshev_scalarization(
Augmented Chebyshev scalarization:
objective(y) = min(w * y) + alpha * sum(w * y)
Outcomes are first normalized to [0,1] for maximization (or [-1,0] for minimization)
Outcomes are multiplied by -1, then normalized to [0,1] for maximization (or [-1,0] for minimization)
and then an augmented Chebyshev scalarization is applied.
Since typically the augmented chebyshev scalarization is minimized, we multiply the resulting quantity by -1.
Note: this assumes maximization of the augmented Chebyshev scalarization.
Minimizing/Maximizing an objective is supported by passing a negative/positive
weight for that objective. To make all w * y's have positive sign
such that they are comparable when computing min(w * y), outcomes of minimization
such that they are comparable when computing max(w * y), outcomes of minimization
objectives are shifted from [0,1] to [-1,0].
See [Knowles2005]_ for details.
Expand All @@ -61,6 +63,7 @@ def get_chebyshev_scalarization(
>>> weights = torch.tensor([0.75, -0.25])
>>> transform = get_aug_chebyshev_scalarization(weights, Y)
"""
Y = -Y
if weights.shape != Y.shape[-1:]:
raise BotorchTensorDimensionError(
"weights must be an `m`-dim tensor where Y is `... x m`."
Expand All @@ -71,7 +74,7 @@ def get_chebyshev_scalarization(

def chebyshev_obj(Y: Tensor, X: Optional[Tensor] = None) -> Tensor:
product = weights * Y
return product.min(dim=-1).values + alpha * product.sum(dim=-1)
return product.max(dim=-1).values + alpha * product.sum(dim=-1)

if Y.shape[-2] == 0:
# If there are no observations, we do not need to normalize the objectives
Expand All @@ -90,10 +93,10 @@ def chebyshev_obj(Y: Tensor, X: Optional[Tensor] = None) -> Tensor:

def obj(Y: Tensor, X: Optional[Tensor] = None) -> Tensor:
# scale to [0,1]
Y_normalized = normalize(Y, bounds=Y_bounds)
Y_normalized = normalize(-Y, bounds=Y_bounds)
# If minimizing an objective, convert Y_normalized values to [-1,0],
# such that min(w*y) makes sense, we want all w*y's to be positive
Y_normalized[..., minimize] = Y_normalized[..., minimize] - 1
return chebyshev_obj(Y=Y_normalized)
return -chebyshev_obj(Y=Y_normalized)

return obj

0 comments on commit 90997db

Please sign in to comment.