Question about constant parameter block

218 views
Skip to first unread message

aeoleader

unread,
May 15, 2017, 10:12:49 PM5/15/17
to Ceres Solver
Hi,

I am trying to solve a statistical model based mesh registration problem using Ceres Solver. I have already constructed the statistical model and the mesh can be deformed by a 12-dimension vector, bParam. Before I go on solving the mesh registration problem, I checked the mesh deformation using bParam as constant variable (i calculated deformation matrix outside the autodiff cost function and passed it to my autodiff cost function as a member variable) and the result is good. Now I am trying to relax this by passing bParam as a parameter block to my autodiff cost function as a constant block using SetParameterBlockConstant() funciton and calculate the deformation matrix in the autodiff function. However, the result is strange as it seems that the function converges to a wrong place. 

The configuration of my minimizer is listed below:

Trust region strategy: dogleg_subspace

Linear solver: sparse_schur

Linear solver ordering: automatic

schur structure: 3, 3, 3



I have an interesting observation:

Before I move the calculation of deformation matrix using bParam into the autodiff function, the function converges to local minima in 3 iterations but after I move the calculation of deformation matrix into the autodiff function, it takes 35 iterations to converge to a wrong place. I hope this observation helps.


Thanks in advance for any help!

Sameer Agarwal

unread,
May 16, 2017, 12:14:21 AM5/16/17
to ceres-...@googlegroups.com
Comments inline.


On Mon, May 15, 2017 at 7:12 PM aeoleader <aeol...@gmail.com> wrote:
Hi,

I am trying to solve a statistical model based mesh registration problem using Ceres Solver. I have already constructed the statistical model and the mesh can be deformed by a 12-dimension vector, bParam. Before I go on solving the mesh registration problem, I checked the mesh deformation using bParam as constant variable (i calculated deformation matrix outside the autodiff cost function and passed it to my autodiff cost function as a member variable) and the result is good.

What do you mean result is group? you fixed bparam but let the vertices of your mesh evolve? and that resulted in a good final mesh?
 
Now I am trying to relax this by passing bParam as a parameter block to my autodiff cost function as a constant block using SetParameterBlockConstant() funciton and calculate the deformation matrix in the autodiff function.

So now bparam is a parameter block in the problem with the same values as above, but is marked constant ? and the solution is different?

that weird, are the starting costs and the gradient the same in both cases?

 
However, the result is strange as it seems that the function converges to a wrong place. 

The configuration of my minimizer is listed below:

Trust region strategy: dogleg_subspace

Linear solver: sparse_schur

why are you using sparse_schur?
 

Linear solver ordering: automatic

schur structure: 3, 3, 3



I have an interesting observation:

Before I move the calculation of deformation matrix using bParam into the autodiff function, the function converges to local minima in 3 iterations but after I move the calculation of deformation matrix into the autodiff function, it takes 35 iterations to converge to a wrong place. I hope this observation helps.

I think your cost function is buggy. Can you share the implementation.
Sameer



Thanks in advance for any help!

--
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/9376393c-13a8-42d2-9ab9-fa05d03439ff%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

aeoleader

unread,
May 16, 2017, 5:52:24 AM5/16/17
to Ceres Solver
Thank you for your reply!

I am implementing SCAPE, a low dimensional human body model, in which the shape space is encoded by a 12-dimension vector, bParam. And, yes, if you give a fixed bParam, you still need to solve a least square problem to get the vertices of the deformed mesh, since the transform matrices obtained from bParam are applied to edges of triangles in the mesh instead of vertices. It is indeed weird because the only thing that I changed is the place to compute the transform matrix S. I have verified that the S calculated in the cost function and the S computed outside are the same after I printed out them in the cost function. 

On Tuesday, May 16, 2017 at 12:14:21 PM UTC+8, Sameer Agarwal wrote:
Comments inline.


On Mon, May 15, 2017 at 7:12 PM aeoleader <aeol...@gmail.com> wrote:
Hi,

I am trying to solve a statistical model based mesh registration problem using Ceres Solver. I have already constructed the statistical model and the mesh can be deformed by a 12-dimension vector, bParam. Before I go on solving the mesh registration problem, I checked the mesh deformation using bParam as constant variable (i calculated deformation matrix outside the autodiff cost function and passed it to my autodiff cost function as a member variable) and the result is good.

What do you mean result is group? you fixed bparam but let the vertices of your mesh evolve? and that resulted in a good final mesh?
The result is good as the deformed mesh is the same as solving the same problem using linear method, LU decomposition to be specific. I originally used the Scipy implementation of the LU decomposition to solve the final position of each vertex, but now I not only want to solve the vertex position but also the parameter that deform the body mesh (bParam). So I need a powerful tool as Ceres Solver to solve multiple parameters at the same time.   
 
Now I am trying to relax this by passing bParam as a parameter block to my autodiff cost function as a constant block using SetParameterBlockConstant() funciton and calculate the deformation matrix in the autodiff function.

So now bparam is a parameter block in the problem with the same values as above, but is marked constant ? and the solution is different?
yes, bParam is a parameter block and I marked it constant after I add the residual blocks. Yes the solution is different.

that weird, are the starting costs and the gradient the same in both cases?
The starting gradients in both cases differs a little bit, one is  0.745 and the other is 0.747. The starting costs are 25.49245 and 19.3132. 

 
However, the result is strange as it seems that the function converges to a wrong place. 

The configuration of my minimizer is listed below:

Trust region strategy: dogleg_subspace

Linear solver: sparse_schur

why are you using sparse_schur?

I am using sparse_schur because the vertices are connected to a few other adjacent vertices and the system is indeed sparse after I add the residual block for each edge.  
 

Linear solver ordering: automatic

schur structure: 3, 3, 3



I have an interesting observation:

Before I move the calculation of deformation matrix using bParam into the autodiff function, the function converges to local minima in 3 iterations but after I move the calculation of deformation matrix into the autodiff function, it takes 35 iterations to converge to a wrong place. I hope this observation helps.

I think your cost function is buggy. Can you share the implementation.
The attachment is my implementation. 
Scape_error_term.h

William Rucklidge

unread,
May 16, 2017, 11:12:04 AM5/16/17
to ceres-...@googlegroups.com
That part where you've got a 13-element vector but you're only telling Ceres about 12 seems likely to cause problems: the parameter block Ceres passes into your function is not your original parameter block, and so will have only 12 values in it; attempting to read the 13th it going to give you junk. You can either have your cost function take in a 12-element vector and append the trailing 1 inside it, or have your cost function take in a 13-element vector and tell Ceres via a SubsetParameterization that the 13th element shouldn't be modified.

You've also got a translational ambiguity in your problem (for any solution (b, x1, x2) anything of the form (b, x1+T, x2+T) is equivalently good, so in principle your entire solution could drift off into space) but that's minor and easy to fix (hold one of x1 or x2 constant, or just parameterise your problem by their difference).

-wjr



To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/e695ce26-5197-4efb-8667-a956fbe2f12a%40googlegroups.com.

Xiangyu Li

unread,
May 16, 2017, 8:34:55 PM5/16/17
to ceres-...@googlegroups.com
Thank you for noticing that. 

I allocated 13 memory space for bParam  pointer before I give the control of pointer to the ceres solver and I preset it to 1 because I only want the ceres solver to change the first 12 elements. I also printed out bb and it gives me the expected answer. I have also verified that the S calculated inside the cost function and outside the function are the same by printing them all out.

--
You received this message because you are subscribed to a topic in the Google Groups "Ceres Solver" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ceres-solver/t1X1ZYl1Ajk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ceres-solver+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/CABsh3u4gTYUuGbgfmq9pbTC8avGt8qvOQ7grkj%3DOg%3DbTDHF%3DJQ%40mail.gmail.com.

aeoleader

unread,
May 16, 2017, 9:23:39 PM5/16/17
to Ceres Solver
As for the space shifting problem, I don't think it will cause problem if I add residual block for each edge because vertices are shared among edges, which means that if one edge shifts to a weird place the residual for another edge or multiple edges will increase, so the shifting is penalized by this. 

For setting one element of a vector constant part, I don't quite understand the internal mechanism of Ceres Solver regarding free variables. If you allocate more space for a pointer and only tell the Ceres Solver to take control of a subset of the vector, is it a viable approach? or am I stuck with using setsubsetparameterization method if I want to hold some of the parameters constant?

aeoleader

unread,
May 16, 2017, 10:32:47 PM5/16/17
to Ceres Solver
I changed the bParam size from 12 to 13 and it works. But I still unsure about how to set the 13th element constant using SubsetParameterization(), is it
std::vector<int> ind;
ind.push_back(13);
ceres
::SubsetParameterization* bSP = new ceres::SubsetParameterization(13, ind);
problem
->SetParameterization(bParam, bSP);




On Tuesday, May 16, 2017 at 11:12:04 PM UTC+8, wjr wrote:

Sameer Agarwal

unread,
May 17, 2017, 10:00:13 AM5/17/17
to Ceres Solver
parameters are indexed with zero based indexing, so you want to

std::vector<int> ind;
ind.push_back(13);
ceres
::SubsetParameterization* bSP = new ceres::SubsetParameterization(12, ind);


aeoleader

unread,
May 17, 2017, 9:27:09 PM5/17/17
to Ceres Solver
Really thank Sameer and and wjr for your help! 
Reply all
Reply to author
Forward
0 new messages