-
Notifications
You must be signed in to change notification settings - Fork 81
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
obj$report() Output #190
Comments
Try |
In summary: The cpp reads:
Perhaps there some sort of post parameter manipulations that optim() performs? |
I also found that "For the final converged parameters Report(LLF) != return(LLF)" If I want to calculate AIC, which LLF should I use in this case and why? Moreover, how can I get the sub-components of LLF(LLF = LLF1 + LLF2 + ...) after the model is converged? If I use REPORT on these sub-components in cpp, their sum report(LLF1) + report(LLF2)+ ... = report(LLF) is different from opt$objective. I would be appreciated if someone can answer the two question. Haikun |
Hello, The Where the theme through all of these posts comes is understanding what the link is between This can be seen if a cpp file:
R file
The question then comes, which is the correct value for the LLF? If the obj$report() value is incorrect, then are all reported vectors also incorrect for the optimized value? If the obj$report() value is correct, though, then what does the likelihood value that the optimizer spits out mean? What is the logic behind the obj$report() vector? Is it placed at the wrong spot? Is it not logical to try to report on the LLF value? Or if there is, is there a more TMB compatible way to report on all the added parts of the LLF, like was remarked above? Sorry for all the questions, but this seems like a key point of understanding in the optimization procedure of TMB, and is essential for its usefulness as a program. Thank you so much! Nathaniel |
Hi, one more comment. This disparity of values seems even more strange because if one sets a REPORT() macro for the parameters, then the parameter values in the output of obj$report() matches to the values of opt$par. This means that there is something specific about reporting on the LLF which makes the REPORT() macro confused. I have been looking at the source code on this page but I can't seem to figure out why the REPORT() would be incorrect for the objective function value but correct for all of the other variables it reports on. Please can you help shed some light on this confusion, Thanks in advance, Nathaniel |
I think the value you are reporting is the joint log-likelihood of parameters and random effects, whereas the value given by obj$fn is the marginal log-likelihood of the parameters. |
@Njoselson |
@kaskr @calbertsen However the initial issue that caused me to open this question was: if there were no random effects specified, what would cause the reported likelihood components not to equal the In the initial comment: Why is the
I think @HaikunXu also mentioned a problem like this, and @tylerjoedonaldson . Are there any other factors that would be added to the REPORT, but excluded from the Nathaniel |
It might help to provide a small example (without random effects) where opt$objective, obj$fn(opt$par), and obj$report(obj$env$last.par.best) does not give the same function value? |
I will see if I can do that. The model I am working on right now is very large, so I will see if the problem is reproduced on a smaller example. Thank you so much @calbertsen |
Thanks so much for keeping up with this thread, I know it must be frustrating. @calbertsen , I haven’t been able to come up with a small example where the obj$report()LLF doesn’t match the opt$objective value after optimization. Nevertheless, when we optimize our code we run into exactly this problem. Is there any other feature of the objective function which will be integrated out after optimization, the way Random Effects are? Also, I notice that none of the TMB examples calculate the objective function by calculating values of LLF1, ... , LLFn and then adding them at the end of the program. Instead all components of the objective function are added as they are calculated with multiple lines: Is there a reason this method would be preferred? I ask because it seems that @HaikunXu also had a problem when breaking the LLF into sub components for reporting. I understand that this is a rather cryptic discussion without specific code, but any help is highly valued. Thanks! |
I am getting the same issue where Here is a MWE. It requires the
Generate data and fit model:
Now, diagnostics:
It is clear that the nll values returned are different depending whether you call fn(), or get the report() value. I believe that the
Now you see, even though the parameters can be found from the wrapper, evaluating the fn() at the found parameters leads to an invalid value. Yet, if you query the fitted means and compute them in |
The difference is most likely a result of parameter dependent branching: if (mu1[i] <= 0) mu1[i] = 0.01; See https://github.com/kaskr/adcomp/wiki/Things-you-should-NOT-do-in-TMB and #112 . If you really want branching on the tape (not recommended as it is not differentiable) here's the equivalent using conditional expressions: mu1[i] = CppAD::CondExpLe(mu1[i], Type(0), Type(0.01), mu1[i]); |
Thanks, can't believe I forget about that. Implementing a smoothed version of the if statement has fixed the issue. However, I am still confused why the obtained values from |
I am unsure if this is the same issue, but what about trying to calculate obj$fn(par) or obj$fn() twice after optimisation or Making AD function? Indeed, I have observed in some cases that the first value of obj$fn() was not the same as the second one (which was generally the same as the ones afterwards). I have no idea why. |
Hello,
Putting REPORT() vectors in the c++ code works easily when running a once off calculation with MakeADFun(). Then the values of these variables at the point they were reported can be accessed with obj$report().
However, I am unclear how the REPORT() vectors work during and after the optimization. I thought that they updated with each additional recalculation of the objective function, corresponding to the updated parameter values. This doesn't seem to be the case however.
The value of the reported LLF value after running MakeADFun, corresponds with the initial value of the optimization. However, if the report vector would update after every iteration, then the reported value should be the same as the final converged value of the optimization, however they are very far from each other. This would indicate that the other values which are reported on also don't correspond to the optimized iteration.
Is there a different way of getting the optimized run's output? I know you can get the optimized parameters with opt$par, but how do you the values of reported variables at the optimum?
Thanks so much!
Nathaniel
The text was updated successfully, but these errors were encountered: