-
Notifications
You must be signed in to change notification settings - Fork 1
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
Derivative of Network Loglikelihood for brlen optimization #49
Comments
One tricky thing: There can be displayed trees for which the current branch we want to optimize is inactive. There is even some more CLV saving potential in this (to be explored if later enough runtime gets spent in CLV updates again): If we can safely skip a tree, then we don't need to update its CLVs after virtual rerooting. |
I made a mistake in the partition loglikelihood formulas above. New image coming soon. |
Do we really need the correct derivative of phylogenetic network likelihood? It is apparently pretty ugly: https://en.wikipedia.org/wiki/Product_rule#Product_of_more_than_two_factors |
Or maybe we can still do something here? I need to dig into how the Math is done for derivative of tree likelihood. After all, there is a product involved there, too (the product over per-site likelihoods ... plus, also a product over partitions). |
Whichever trick is used for trees there should also work for the networks. Because with the approach I used here, I get into the same problem if there is only a single displayed tree. There has to be some further trick involved! |
Okay... now I understand the text in Alexeys thesis (https://cme.h-its.org/exelixis/pubs/dissAlexey.pdf, page 26).
My problem was that I thought it only gives L'(b) and L''(b) |
My confusion originated from this: For trees, we end up getting and using these:
But what the trick with the sumtable actually gives us are fast computations of (with respect to branch b):
Instead of directly reusing the final result ((loglL(T))' and (loglL(T))'') from the trees case, I need to plug these faster-computed tree persite likelihoods and their derivatives into the network loglikelihood and loglikelihood derivative formulas. |
Wait... do I really need the fully computed displayed tree loglikelihoods here? For LikelihoodModel.BEST, we can do without explicitly computing them. Because there we essentially have one tree per partition... --> Looks like there is no way around actually inserting the displayed tree persite loglikelihoods (and their derivatives) into the formulas for the networks case. Thus, another drawing will follow soon here. :-) |
Okay, found a counterexample (for x > 0):
----> max{f', g'} / max{f, g} != max{f'/f, g'/g} ---> Thus, no matter which likelihood model (out of AVERAGE and BEST) we are using, as soon as we have more than one displayed tree, we cannot profit from going down to the persite-level. |
This makes it clear that for networks, we need to compute all three of logL(T|P), (logL(T|P))', (logL(T|P))'' with help of the sumtable. The only question remains whether it makes sense to go down to a per-site level in case the network has only one displayed tree. Special treatment for the single-tree case has led to numerical quirks when computing network loglikelihood before (there, while mathematically the same, the different operations (like, adding a log(exp()) around it or not) led to a slight numerical difference that confused BIC). |
Damn the Newton Raphson in pll-modules is awful, also the second network loglikelihood derivative is such a high number that it does not fit into a double. Luckily, what Newton-Raphson actually needs is just the quotient of first and second derivative, as well as the sign of the second derivative... I'll just switch to implementing vanilla Newton-Raphson myself, using https://www.cup.uni-muenchen.de/ch/compchem/geom/nr.html and Alexis lecture slides ... |
Or no wait, maybe I can adapt the pll_modules implementation to directly take the quotient as argument... |
I tried this (passing the quotient and trimming too large and too small values before passing them to the pll-modules NR implementation), but it made NR never find a better branch length. Switching to writing my own NR implementation now. |
Mhm. It also happens with my own NR implementation... maybe the derivatives are still wrong? |
I checked how Newton-Raphson decides on the next branch length to propose: It essentially subtracts first_logl_derivative/second_logl_derivative from the previous branch length. With these values I get for network first and second logl derivative (computed on a network with 0 reticulations), NR cannot work: Starting with network logl: -771.9593909 Network partition likelihood derivatives for partition 0: Network partition likelihood derivatives for partition 1: Network loglikelihood derivatives: Maybe something is wrong with my network loglikelihood derivative formula? |
I also printed the loglikelihood and its derivatives for the single displayed tree of the network: For partition 0: For partition 1: |
From looking at these numbers, I infer that something must have gone wrong when computing partition_logl_prime and partition_logl_prime_prime. |
Formulas I used (same here for LikelihoodModel.AVERAGE and LikelihoodModel.BEST, as there is only 1 displayed tree with tree_prob 1.0):
Of course, in this case partition_logl_prime should be the same as tree_logl_prime. And partition_logl_prime_prime should be the same as tree_logl_prime_prime. The question is: Why isn't this the case? |
I got it now: My mistake was that I derived the log. Instead, one should see it as a function g. Example: Partition loglh, 2 displayed trees, LikelihoodModel.AVERAGE: Now, think as if we already have tree loglikelihoods. Instead of logl, we write g, which gives us: g(P) = g(T_1|P) * p(T_1) + g(T_2|P) * p(T_2) And then, we easily see how to derive it: ---> We can compute the partition loglikelihood derivatives out of the displayed tree loglikelihood derivatives. |
Mhm. But if I follow this, then the network loglikeihood derivative is simply the sum of the partition loglikelihood derivatives... I tried this as well, but this als didn't work out with Newton Raphson. |
It looks much better now though. Now the error is "Exceeded maximum number of iterations" and the proposed branch lengths appear at least somewhat reasonable... |
But if this is the correct network loglikelihood derivatives definition now (-> sum of partition loglikelihood derivatives, computed out of displayed tree loglikelihood derivatives), then we don't even need to compute tree_logl out of the sumtable anymore... I'm still leaving it in as optional, as this allows for BRENT with sumtable combination. |
OK it looks like I got Newton-Raphson Branch-Length optimization for networks to work. It is lots of dark voodoo though!!! |
Posting the correct maths for network loglikelihood derivatives here soon. (I'm still on vacation, after all) |
Mhmm... no. Now NR only works for zero-reticulation networks. The network loglikelihood derivatives are still wrong if there is more than one displayed tree. |
Could still be a bug instead of a mistake in the formulas now. It looks like I am currently not getting all the sumtables, as soon has we have reticulations in the network. -> EDIT: Nope, the number of sumtables was fine. There simply were some displayed trees where the branch is inactive... |
Looks like I got Newton Raphson to also work with reticulations now!!! 🎉 It really is dark voodoo though... 👻 |
Mhm, but it nearly never converges if we have reticulations present... maybe the network loglikelihood derivative formulas are still wrong. :-( |
I think I got it now. I still had some exp and log calls that were wrongly placed in the network partition logl derivatives. But I cannot test it now, as it is time to go to sleep first. |
Okay. Here is my plan, sticking with network loglikelihood derivatives, as the code I have so far uses them (meaning, I just have to fix the partition loglikelihood derivatives and the tree likelihood derivatives in my code): ... damn, I am really bad at being on vacation/ not working on weekends. :-( |
Now it works 😎 But if we have LikelihoodModel.BEST, then Newton Raphson is MUCH faster than Brent_reroot! :-) I am still doing some minor code optimizations (e.g., no need to precompute pmatrix diagonal more than once for each set of displayed trees), then I can post some speedups. |
Okay, now also for LikelihoodModel.AVERAGE, Newton Raphson is nearly twice as fast as Brent_reroot. I changed the code such that pmatrix derivatives are only precomputed once per partition and then shared among the displayed trees. |
great stuff
…On 29.03.21 03:13, Sarah Lutteropp wrote:
Okay, now also for LikelihoodModel.AVERAGE, Newton Raphson is nearly
twice as fast as Brent_reroot. I changed the code such that pmatrix
derivatives are only precomputed once and then shared among the
displayed trees.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#49 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGXB6RI7SFTE3FJSYPQCRTTF7H5DANCNFSM4ZE656PA>.
--
Alexandros (Alexis) Stamatakis
Research Group Leader, Heidelberg Institute for Theoretical Studies
Full Professor, Dept. of Informatics, Karlsruhe Institute of Technology
www.exelixis-lab.org
|
(from #43)
Luckily, given the derivatives of displayed tree loglikelihoods, the derivative of the network loglikelihood is easy to compute (little mistake in the image, but not relevant here - the displayed tree loglikelihoods of course depend on the partition, also on brlens, model parameters, etc):
(EDIT: THIS IS WRONG, SEE LATER COMMENT)
Thus the main challenge here is to understand these sumtables used for tree loglh derivatives in pll_modules, being especially careful about how this works with virtual rerooting. And then I need to do this for the displayed trees displayed by the network and voilà, then we can switch from Brent brlen-opt to Newton-Raphson brlen-opt! :-)
The text was updated successfully, but these errors were encountered: