FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add delayed rejection metropolis hastings class by dawsoneliasen · Pull Request #136 · bangerth/SampleFlow · GitHub

Add delayed rejection metropolis hastings class - #136

Merged
bangerth merged 1 commit into
bangerth:masterfrom
dawsoneliasen:add-dram-producer
Dec 10, 2020
Merged

bangerth merged 1 commit into
bangerth:masterfrom
dawsoneliasen:add-dram-producer

Conversation

dawsoneliasen commented Sep 1, 2020 •
edited
Loading

Copy link
Copy Markdown
Contributor

This PR adds a new producer for delayed rejection metropolis hastings sampling.

Comment thread include/sampleflow/producers/dram.h Outdated
Comment thread include/sampleflow/producers/dram.h Outdated
dawsoneliasen marked this pull request as ready for review September 9, 2020 16:03

bangerth left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Close. I think it would be useful to also have a test that samples from either a uniform or a Gaussian distribution, and computes the mean and standard deviation to make sure we're at least in the ballpark of what one would analytically expect.

* @param[in] log_likelihood A function object that, when called
* with a sample $x$, returns $\log(\pi(x))$, i.e., the natural
* logarithm of the likelihood function evaluated at the sample.
* @param[in] perturb A function object that, when given a sample

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I think you should update the description of this parameter for the DR case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@bangerth Would you please elaborate? Are you referring to log_likelihood or perturb? I'm not sure what needs to be changed about the description.

dawsoneliasen commented Sep 19, 2020 •
edited
Loading

Copy link
Copy Markdown
Contributor Author

Close. I think it would be useful to also have a test that samples from either a uniform or a Gaussian distribution, and computes the mean and standard deviation to make sure we're at least in the ballpark of what one would analytically expect.

@bangerth Good idea, I copied the metropolis_hasting_producer_04 test which gets a mean value of about 2, but when executed with the new class, the mean value is 1. Is this be a sign that something is going wrong? The test was pushed to this branch so you can take a look at what is happening exactly.

Copy link
Copy Markdown
Owner

It may be a problem. Knowing that the mean value should be 2 is really only a statement about having a very large number of samples. What happens if you look a many more samples?



// Always move to the right when trying to find a new trial sample.
std::pair<SampleType,double> perturb (const SampleType &x, const std::vector<SampleType> y)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Suggested change
std::pair<SampleType,double> perturb (const SampleType &x, const std::vector<SampleType> y)
std::pair<SampleType,double> perturb (const SampleType &x, const std::vector<SampleType> &y)

// probabilities. We're moving the sample to the right, so that ratio
// is actually infinity, but we can lie about it for the purposes of
// this test.
return {x+1, 1.};

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm not sure this is right. The fact that the function lies about what the ratio of probabilities are, makes it probably so that it doesn't quite lead to correct results. It may be better to sample from something like a Gaussian, and compute the mean of that.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Or you can leave the test as is and just go with it. Returning a ratio of 1 means that the delayed rejection simply always accepts the very first sample. That's not wrong, and in some sense just checks a specific part of the algorithm. So maybe it does make sense to just keep the test.

@@ -0,0 +1 @@
Mean value = 1.00056

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes, that looks wrong :-(

Comment on lines +140 to +141
if ((trial_log_likelihood - std::log(proposal_distribution_ratio) > current_log_likelihood) ||
acceptance_ratio >= uniform_distribution(rng))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@bangerth see this commit. I tried with max_delays=0 just like you said and observed different results from the vanilla MH. I went through the vanilla MH to see what could possibly be different and this was missing. I thought that including this likelihood check was redundant but I guess I was wrong (let's talk about this more next week). With this included, the max_delays=0 DRMH produces samples with a mean of 1.99.

However, when I increase the number of delay stages to 5, the resulting mean is 1.69. This makes me very suspicous that there is something wrong with the delayed rejection process. What are your thoughts?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

As for different results: You have to count how many times you evaluate the rng. It produces a reproducible sequence of random numbers, but if you use the rng a different number of times per loop iteration, then at the top of the next iteration you will of course get a different result.

// this is multiplied to the current acceptance_ratio
double prev_acceptance_ratio = 1.0;
// Delayed rejection loop
for (int delay_stage = 0; delay_stage <= max_delays; ++delay_stage)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

delay_stage is inherently a non-negative. It should be unsigned int.

Comment on lines +140 to +157
double u = uniform_distribution(rng);
assert(acceptance_ratio > 1 == acceptance_ratio >= u);
if (acceptance_ratio > 1 || acceptance_ratio >= u)
accepted_sample = true;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@bangerth This assert passes just fine, but with this setup (using a variable u), the mean value converges to 1 instead of 2. Simply removing the variable u and calling uniform_distribution() inside the conditional results in a mean of 2.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@bangerth Any thoughts on this? Why would the assignment of a variable affect the random values?

Copy link
Copy Markdown
Owner

Need to run make indent.

Copy link
Copy Markdown
Owner

Oh, you already beat me to it :-) So just squash things into fewer commits.

Copy link
Copy Markdown
Contributor Author

@bangerth Sorry, I'm having trouble squashing this branch. I thought I just needed to do:

git rebase master
git reset

But both of these commands just output "Current branch add-dram-producer is up to date."

bangerth commented Dec 9, 2020

Copy link
Copy Markdown
Owner

For squashing, you need an "interactive" rebase. So do

  git rebase -i master

No reset should be necessary, but you'll find that

  git push origin

will fail. Read the error message and try to understand why you get it. Then ignore it by saying

  git push -f origin

Copy link
Copy Markdown
Contributor Author

@bangerth perfect, thank you!

remove separate function for log likelihood of rejected point

update variable names

combine loops, add documentation

rename

fix ifndef

fix bugs

add test for DRMH

use a different iterator for inner loop

add test output

fix indentation

use a better variable name for inner loop

always do at least one stage

use prefix increment

add note about max_delays==0

move the n_samples to the last parameter

update test to reflect changes to sample signature

add another test

fix indentation

do not name ignored argument

finish sentence

use 0.5 for likelihood

create another test

multiply by acceptance ratio of previous sample

more than one delayed rejection

more than one delayed rejection

finish implementing test

fix likelihood and perturb

make variables const

create output file

include likelihood check

add assert for testing

emulate regular MH

update test case

add shortcut back in

add seed option

fix style
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL