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

Bounds for search space #364

Closed
Kaltxi opened this issue Mar 19, 2023 · 5 comments
Closed

Bounds for search space #364

Kaltxi opened this issue Mar 19, 2023 · 5 comments
Labels

Comments

@Kaltxi
Copy link

Kaltxi commented Mar 19, 2023

Hello! First of all, thanks for your work, really like the library!

I have optimization problems of arbitrary functions which could have many minima, but only the ones in a particular part of the variable space are of interest. Currently the best approach I could find was to evaluate the function to std::numerical_limits::max() when inputs are outside the bounds, which certainly made the results better. Is this the idiomatic way? If not, is there a better approach or maybe plans to add bounds as parameters to the optimizer?

@zoq
Copy link
Member

zoq commented Mar 20, 2023

Hello, depending on the optimizer it's possible to set the bounds, see https://ensmallen.org/docs.html#pso for an example. What optimizer are you using?

@rcurtin
Copy link
Member

rcurtin commented Mar 20, 2023

@zoq is right, there are some techniques that specifically support constrained optimization. If you still want to use a differentiable optimizer like SGD or L-BFGS or something that doesn't specifically have supports for constraints, I would suggest a "soft" constraint instead of simply evaluating to DBL_MAX (or similar); think, e.g., adding some constant multiplied by how far you are from the edge of the bounds. So for a one-dimensional problem, if you want something in [0, 1], maybe add, say, 1000 * (std::min(x[0], x[0] - 1)) or something like this if x[0] is not in [0, 1]. Just an idea.

@Kaltxi
Copy link
Author

Kaltxi commented Apr 5, 2023

@zoq Sorry for late reply! I was using DE. PSO for me has a strange bug of not terminating even due to maxIterations - it just goes on and on; I've looked at the ensmallen code, and it looks like it should work...

@rcurtin thanks for the soft constraint idea, not sure if it is useful for non-differentiable optimizers, my testing for DE seems to yield the same results as with DBL_MAX:

auto outOfBoundsLoss(const arma::mat& coordinates,
                     const arma::mat& lower,
                     const arma::mat& upper) -> std::optional<double> {
  constexpr double PENALTY = 1000.0;
  std::optional<double> loss{};

  for (int i = 0; i < coordinates.size(); ++i) {
    if (coordinates[i] < lower[i]) {
      loss = PENALTY * (lower[i] - coordinates[i]) + loss.value_or(0.0);
    } else if (coordinates[i] > upper[i]) {
      loss = PENALTY * (coordinates[i] - upper[i]) + loss.value_or(0.0);
    }
  }

  return loss;
}

auto ObjectiveType::Evaluate(const arma::mat coordinates) -> double {
  const auto outOfBounds =
      outOfBoundsLoss(aberrations, {-100, -10'000}, {100, 10'000});

  if (outOfBounds.has_value()) {
    return outOfBounds.value();
  }

  // In-bounds calculations
}

@Kaltxi
Copy link
Author

Kaltxi commented Apr 5, 2023

Ok, there is no problem with maxIterations, I was counting evaluations, not iterations... But bounds for PSO do not work, I still need to use the loss-bounding function. It kinda makes sense, even in documentation it is written that bounds are only for the initial population.

Also, a better approach with the above code would be not to return the out-of-bounds loss, but instead add it as penalty, otherwise algorithm can optimize out-of-bounds and converge to one of the bounds:

auto ObjectiveType::Evaluate(const arma::mat coordinates) -> double {
  const auto penalty =
      outOfBoundsLoss(aberrations, {-100, -10'000}, {100, 10'000});

  // In-bounds calculations
  // result = ...

  return result + penalty.value_or(0.0);
}

@mlpack-bot
Copy link

mlpack-bot bot commented May 5, 2023

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions! 👍

@mlpack-bot mlpack-bot bot added the s: stale label May 5, 2023
@mlpack-bot mlpack-bot bot closed this as completed May 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants