PBI

class torchjd.scalarization.PBI(theta, weights, reference=None)[source]

Scalarizer that combines the input tensor of values using the Penalty-based Boundary Intersection (PBI) scalarization, proposed in MOEA/D: A Multiobjective Evolutionary Algorithm Based on Decomposition.

It decomposes the values, relative to a reference point, into a component along a preference direction and a component perpendicular to it, and penalizes the latter:

\[d_1 = (L - z^*)^\top \hat w, \qquad d_2 = \lVert (L - z^*) - d_1 \hat w \rVert, \qquad d_1 + \theta\, d_2,\]

where:

  • \(L_i\) is the \(i\)-th input value (the \(i\)-th objective);

  • \(z^*\) is the reference (ideal) point (the reference parameter);

  • \(\hat w = w / \lVert w \rVert\) is the normalized preference direction (the weights parameter);

  • \(d_1\) is the distance along the preference direction and \(d_2\) is the distance to it;

  • \(\theta\) is the penalty coefficient applied to \(d_2\) (the theta parameter).

Parameters:
  • theta (float) – The penalty coefficient \(\theta\) applied to the perpendicular distance. Must be non-negative. A value of 0 reduces PBI to the projection onto the preference direction. The paper uses 5 in its experiments; there is no single best value, and the paper notes that a too large or too small value worsens the result.

  • weights (Tensor) – The preference vector \(w\), giving the direction along which the values are decomposed. Its values should be non-negative. It must have the same shape as the values passed at call time. To approximate the whole Pareto front rather than a single trade-off, it should be re-sampled from a Dirichlet distribution and reassigned before every call, e.g. for m objectives pbi.weights = torch.distributions.Dirichlet(torch.ones(m)).sample().

  • reference (Tensor | None) – The reference (ideal) point \(z^*\) subtracted from the values. It should be a lower bound on the values. If None, the origin is used, which assumes non-negative values. If provided, it must have the same shape as the values passed at call time.

Note

\(d_2\) is a Euclidean norm, whose gradient is undefined when the values lie exactly on the preference direction (\(d_2 = 0\)). To keep the gradient finite there, a small constant is added under the square root; this shifts the result by at most around \(10^{-6}\) at that point and is negligible elsewhere.

__call__(values, /)[source]

Computes the scalar value from the input tensor of values and applies all registered hooks.

Parameters:

values (Tensor) – The tensor of values to scalarize. May be of any shape.

Return type:

Tensor