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

Optimization return code is misleading #2197

Open
sakrejda opened this issue Dec 30, 2016 · 16 comments
Open

Optimization return code is misleading #2197

sakrejda opened this issue Dec 30, 2016 · 16 comments

Comments

@sakrejda
Copy link
Contributor

Summary:

In do_bfgs_optimize, the return code is still positive even if the algorithm stops because it reaches max iterations. That leads stan to return stan::servicse::error_codes::OK even though the algorithm did not meet stopping criteria. I don't think this is necessarily wrong but it is misleading.

Description:

The return code (ret below) will be positive even if the algorithm terminates because it reaches max iterations. I don't think Stan should treat that the same as meeting convergence diagnostics. Relevant snippet from do_bfgs.hpp:

        if (ret >= 0) {
          info("Optimization terminated normally: ");
          return_code = stan::services::error_codes::OK;
        } else {
          info("Optimization terminated with error: ");
          return_code = stan::services::error_codes::SOFTWARE;
        }
info("  " + bfgs.get_code_string(ret));

Reproducible Steps:

It's pretty clear from the code. Did not try to make an example. Probably a model like the following would do it.

parameters {
  real x;
}
model {
  target += log(x);
}

Current Output:

The message that the algorithm terminated because it reached max iterations is only written on a side-channel ("info"), the Stan return value is still stan::services::error_codes::OK

Expected Output:

Terminating because the algorithm runs out of iterations should give some return value other than "OK"

Current Version:

v2.14.0

@sakrejda
Copy link
Contributor Author

I guess the return for running out of iterations should either be DATAERR (misspecified model) or CONFIG (not enough iterations).

@bob-carpenter
Copy link
Contributor

bob-carpenter commented Dec 30, 2016 via email

@sakrejda
Copy link
Contributor Author

I do think it would make sense to have our own error codes and be more specific for each algorithm but currently it sounds as though we're limiting ourselves: https://github.com/stan-dev/stan/blob/develop/src/stan/services/error_codes.hpp, not sure who made the decision.

@syclik
Copy link
Member

syclik commented Dec 30, 2016 via email

@sakrejda
Copy link
Contributor Author

@syclik I'd rather not make this small issue about re-designing how Stan does return codes, just fixing this one problem. I made a separate issue for a re-design:

@syclik
Copy link
Member

syclik commented Dec 30, 2016

Ok. In that case, just submit a pull request for the else branch in the original post. Remember, the way this is currently working is that the return code is what's actually returned from int main(), so it is literally the return code from the program in CmdStan.

Honestly, I'm looking at the sysexits page that's linked there and software is the closest things that matches. It seems like the correct behavior: 0 for success, non 0 for failure.

What are you suggesting happens for this issue?

@syclik
Copy link
Member

syclik commented Dec 30, 2016

I'm looking at the original post again. I think you're suggesting that the algorithm failed if it completed all its iterations. I'm not sure that constitutes a failure. The algorithm actually did what it was supposed to do.

@sakrejda
Copy link
Contributor Author

I am suggesting that "OK" as a return code for completing all the iterations is misleading but I guess you're right that what exactly it should return is debatable. It should return something other than "OK", so by necessity a failing (non-zero) return code. If you think it's better to just leave this as-is that's fine, you can close the issue.

@syclik
Copy link
Member

syclik commented Dec 30, 2016

I'd like to know how you're proposing to change this. I don't actually understand what you're suggesting with this issue. What constitutes a success and a failure is debatable, so if you have an idea of where that line should be, please be clear about it and we can adjust accordingly.

@sakrejda
Copy link
Contributor Author

Trying to be clearer here, I'm suggesting changing from:

        if (ret >= 0) {
          info("Optimization terminated normally: ");
          return_code = stan::services::error_codes::OK;
        } else {
          info("Optimization terminated with error: ");
          return_code = stan::services::error_codes::SOFTWARE;
        }

to

        if (ret < 0 || ret == 40) {    // LSFAIL or MAXIT returns
          info("Optimization not completed: ");
          return_code = stan::services::error_codes::SOFTWARE; 
        } else {
          info("Optimization terminated normally: ");
          return_code = stan::services::error_codes::OK;
        }

The argument for this change is that this gets used as a return code in CmdStan and somebody who runs a CmdStan program probably expects "OK"/0 to mean that the local optimum was achieved.

When using CmdStan optimization as an optimization sub-step in some bigger algorithm it might make sense to treat MAXIT as a success but that's a corner case and should be treated as such.

@bgoodri
Copy link
Contributor

bgoodri commented Dec 30, 2016 via email

@sakrejda
Copy link
Contributor Author

Stan should return the same error codes as in the original LBFGS fortran code.

That's out of left field. Why should CmdStan be stuck with return codes from some other fortran code? Could you explain what you mean?

@bgoodri
Copy link
Contributor

bgoodri commented Dec 30, 2016 via email

@sakrejda
Copy link
Contributor Author

sakrejda commented Dec 30, 2016 via email

@syclik
Copy link
Member

syclik commented Jan 2, 2017

@bgoodri, what do you mean? What particular implementation are you talking about? Can you point me to the doc?

@bgoodri
Copy link
Contributor

bgoodri commented Jan 2, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants