stan icon indicating copy to clipboard operation
stan copied to clipboard

Log density with proportionality in ADVI drops more than constant

Open yao-yl opened this issue 6 years ago • 2 comments

Summary:

Log density with proportionality in ADVI drops more than constant

Description:

According to stan C++ guidance (https://github.com/stan-dev/stan/wiki/Model-Concept), the log probability of a stan model, with or without proportionality, can be calculated from

template <bool propto, bool jacobian_adjust_transforms, typename T>
T 
log_prob(std::vector<T>& params_r,
         std::vector<int>& params_i,
         std::ostream* msgs = 0) 
const;

But I find the difference between the exact and proportional log density in Stan ADVI code is not a constant.

Reproducible Steps:

In order to calculate both the exact log density and proportional log density in the unconstrained space, and to print their difference, add these lines before https://github.com/stan-dev/stan/blob/12f031565df6265356bdc4c6b191d8df619151f5/src/stan/variational/advi.hpp#L540

            double log_p_exact=0;
            double log_p_prop=0;
            log_p_exact = model_.template log_prob<false, true>(cont_params_);
            log_p_prop = model_.template log_prob<true, true>(cont_params_);
            std::stringstream ss;
            ss << "constant dropped="<<log_p_exact-log_p_prop<<"======";
            std::cout<<ss.str();

Then we can make cmdstan and run the bernoulli example:

examples/bernoulli/bernoulli variational algorithm=meanfield iter=1000 output_samples=30 data file=examples/bernoulli/bernoulli.data.R

Current Output:

We should expect the output being a constant for all posterior draws, which stands for the log constant term in densities. But it is not. For instance here is the first 6 lines of the output:

constant dropped==-5.24628 
constant dropped==-5.20678
constant dropped==-5.78415
constant dropped==-5.37678
constant dropped==-5.02283
constant dropped==-5.59698

I check that the exact log density ( model_.template log_prob<false, true> ) does return the log density plus jacobian.

Current Version:

v2.17.1

yao-yl avatar Apr 26 '18 02:04 yao-yl

Can you provide a minimal example? An easy way to do it is to just put it on a branch. (The breadcrumbs you left aren't enough.) Or just isolate it in a test.

Something looks off. Can you print the cont_params_ and the values for log_p_exact and log_p_prop? That would help a bit.

On Wed, Apr 25, 2018 at 10:04 PM, Yuling Yao [email protected] wrote:

Summary:

Log density with proportionality in ADVI drops more than constant Description:

According to stan C++ guidance (https://github.com/stan-dev/ stan/wiki/Model-Concept), the log probability of a stan model, with or without proportionality, can be calculated from

template <bool propto, bool jacobian_adjust_transforms, typename T> T log_prob(std::vector<T>& params_r, std::vector& params_i, std::ostream* msgs = 0) const;

But I find the difference between the exact and proportional log density in Stan ADVI code is not a constant. Reproducible Steps:

In order to calculate both the exact log density and proportional log density in the unconstrained space, and to print their difference, add these lines before https://github.com/stan-dev/stan/blob/12f031565df6265356bdc4c6b191d8 df619151f5/src/stan/variational/advi.hpp#L540

        double log_p_exact=0;
        double log_p_prop=0;
        log_p_exact = model_.template log_prob<false, true>(cont_params_);
        log_p_prop = model_.template log_prob<true, true>(cont_params_);
        std::stringstream ss;
        ss << "constant dropped="<<log_p_exact-log_p_prop<<"======";
        std::cout<<ss.str();

Then we can make cmdstan and run the bernoulli example:

examples/bernoulli/bernoulli variational algorithm=meanfield iter=1000 output_samples=30 data file=examples/bernoulli/bernoulli.data.R

Current Output:

We should expect the output being a constant for all posterior draws, which stands for the log constant term in densities. But it is not. For instance here is the first 6 lines of the output:

constant dropped==-5.24628 constant dropped==-5.20678 constant dropped==-5.78415 constant dropped==-5.37678 constant dropped==-5.02283 constant dropped==-5.59698

I check that the exact log density ( model_.template log_prob<false, true> ) does return the log density plus jacobian. Current Version:

v2.17.1

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/stan-dev/stan/issues/2518, or mute the thread https://github.com/notifications/unsubscribe-auth/AAZ_F2pz4yqLIVWm9a_1egPgVO-QxrYOks5tsSsbgaJpZM4TkaHA .

syclik avatar Apr 26 '18 04:04 syclik

The problem seems to be that there are calls from within ADVI that use double values, so all the constants get dropped. The reason to fix this is to make our interfaces uniform and to make these things usable on the outside. The reason not to is that it'll be slower if it's currently being called with double values.

bob-carpenter avatar Apr 26 '18 15:04 bob-carpenter