Is it safe to call Problem::Evaluate() inside iteration callback?

1,050 views
Skip to first unread message

Hannes Ovrén

unread,
Jul 5, 2016, 8:35:12 AM7/5/16
to Ceres Solver
Hi!

The following applies to version 1.11.0.

I want to use an iteration callback to follow and analyze the behavior of my optimization problem.
Specifically, I really want the current residual vector.
Looking at past posts, it was suggested to use Problem::Evaluate() to do this.
Therefore, my callback does the following:

std::vector<double> residuals;
ceres
::Problem::EvaluateOptions eval_opt;
eval_opt
.num_threads = 1;
problem_
->GetResidualBlocks(&eval_opt.residual_blocks);
problem_
->Evaluate(eval_opt, NULL, &residuals, NULL, NULL);

This however causes my application to segfault when writing to the jacobian matrix at dense_jacobian_writer.h:97.
What happens is that the jacobian matrix is smaller than expected.
In my test case, the dense_jacobian matrix has size 30x255 but gets accessed as dense_jacobian.block(0, 480, 2, 1) which is clearly out of bounds for the columns.

I think this happens because the size of the jacobian is created using the reduced/preprocessed problem, but the calling code uses the full parameter set.

1. Is this a bug or me doing something wrong? I.e. is it safe to call Problem::Evaluate() from within an iteration callback? E.g. thread safety, since the offending code seems to lie within an OMP block.

2. Is there another way for me to extract the residuals? I couldn't find any obvious way to get the effective parameter blocks from the Problem instance to avoid the problem mentioned above.

Regards,

Hannes Ovrén

Sameer Agarwal

unread,
Jul 5, 2016, 8:39:53 AM7/5/16
to Ceres Solver

No, you cannot call problem:evaluate from an iteration callback.

What are you trying to do with the residuals?

Sameer


--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/c3f2d600-c90c-464c-aea0-dcaca83964c0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hannes Ovrén

unread,
Jul 5, 2016, 9:20:06 AM7/5/16
to Ceres Solver
On Tuesday, July 5, 2016 at 2:39:53 PM UTC+2, Sameer Agarwal wrote:

No, you cannot call problem:evaluate from an iteration callback.


Ok, that explains the problem :)
Then what is the best approach to calculate/get the current residual vector?
 

What are you trying to do with the residuals?


They are only for visualization at this point. I have multiple types of residuals and I want to see the behavior over time.
Later I might want to use them for a custom termination condition.

Sameer Agarwal

unread,
Jul 5, 2016, 10:32:09 AM7/5/16
to ceres-...@googlegroups.com
On Tue, Jul 5, 2016 at 6:20 AM Hannes Ovrén <kig...@gmail.com> wrote:
On Tuesday, July 5, 2016 at 2:39:53 PM UTC+2, Sameer Agarwal wrote:

No, you cannot call problem:evaluate from an iteration callback.


Ok, that explains the problem :)
Then what is the best approach to calculate/get the current residual vector?

Right now there isn't one. In part because during the solve, the problem object gets modified to account for constant parameter blocks and inactive residual blocks. So we don't actually evaluate the full problem either.  So it would be some work to return all the residuals back to you as part of IterationSummary.

Sameer

Hannes Ovrén

unread,
Jul 5, 2016, 10:42:08 AM7/5/16
to Ceres Solver
Ok, I see.
I guess I just have to run the cost functions explicitly (without involving ceres) in the callback then.

I was confused, because in a previous message to this list (https://groups.google.com/forum/#!topic/ceres-solver/d7BhJdCCz9c) it sounded like my approach would work.
Maybe it would be a good idea to add a line in the documentation of either/both IterationCallback and Problem::Evaluate() that mentions this, since I guess I won't be the last person to ask about it.

Thanks for the quick help!

/Hannes

Sameer Agarwal

unread,
Jul 5, 2016, 10:58:59 AM7/5/16
to Ceres Solver
Calling Problem::Evaluate to get residuals is the right thing to do except when the problem is being solved. 
Sameer


Adam Hartshorne

unread,
May 8, 2017, 5:46:47 PM5/8/17
to Ceres Solver
I presume the ability to evaluate elements of the cost function at the end of each iteration is still not possible?

I presume instead one could conduct a bit of a hack and set the maximum number of iterations of the solver to 1, then have an external loop to ceres which calls the solver x times, with the output first evaluated using the method available, before being feed back in as the input to the next iteration?

Sameer Agarwal

unread,
May 8, 2017, 5:49:27 PM5/8/17
to ceres-...@googlegroups.com
On Mon, May 8, 2017 at 2:46 PM Adam Hartshorne <adam.ha...@gmail.com> wrote:
I presume the ability to evaluate elements of the cost function at the end of each iteration is still not possible?

nope. But I would like to understand what you are trying to do that requires this?
 
I presume instead one could conduct a bit of a hack and set the maximum number of iterations of the solver to 1, then have an external loop to ceres which calls the solver x times, with the output first evaluated using the method available, before being feed back in as the input to the next iteration?

That is likely not a great idea either because you will be resetting the trust region loop to its initial radius every time. So it won't have a chance to resize. In particularly if the first iteration fails to make progress, doing this sort of loop will never make progress.

Sameer


 

Adam Hartshorne

unread,
May 8, 2017, 6:42:56 PM5/8/17
to Ceres Solver
As with the original poster, I have a number of different cost functions which together form the overall function which I am trying to optimize. I would like to visualize how they are altering at the end of each iteration as it will allow me to link how the changes in the costs functions (that operate in non-euclidean domains) affect some 3D objects.

Obviously I can take these measures at the start and end of the optimization, but ideally it would be nice to be able to slow it down and see what it happening step by step as I alter some of the parameters in each of the cost functions.

Sameer Agarwal

unread,
May 8, 2017, 6:53:34 PM5/8/17
to Ceres Solver
Adam,
You can work around the limitations of calling Problem::Evaluate and just evaluate each cost function on your own. which would work.
Sameer


Adam Hartshorne

unread,
May 9, 2017, 3:36:47 PM5/9/17
to Ceres Solver
Thanks for the info.

Rabah Abdul Khalek

unread,
May 22, 2019, 6:29:43 AM5/22/19
to Ceres Solver
It would be great if summary.cost provides a vector of values corresponding to each Residualblock instead of their sum, that can be accessed from IterationCallback.

Keir Mierle

unread,
Jul 8, 2019, 4:50:58 PM7/8/19
to ceres-...@googlegroups.com
Hi Rabah,

The problem is that Ceres doesn't actually evaluate all the residuals due to constant parameters as Sameer alluded to. It's possible that Ceres could be extended to do this, but likely ~doubling the computation time per iteration (since we would trigger a full evaluation of the entire problem).

This isn't the first time this has been asked about; if someone wants to think about what a clean design for this might look like, we're happy to discuss it. Key challenges are to have zero impact on performance when the feature is not enabled, and to support a variety of use cases like this one.

Cheers,
Keir

Reply all
Reply to author
Forward
0 new messages