Skip to content

Commit

Permalink
Print logp summary on bad energy error #3230 (#3234)
Browse files Browse the repository at this point in the history
  • Loading branch information
springcoil authored and aseyboldt committed Oct 25, 2018
1 parent b62fd53 commit 3cb4570
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
17 changes: 10 additions & 7 deletions pymc3/step_methods/hmc/base_hmc.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections import namedtuple

import numpy as np

import logging
from pymc3.model import modelcontext, Point
from pymc3.step_methods import arraystep
from pymc3.step_methods.hmc import integration
Expand All @@ -10,7 +10,7 @@
from .quadpotential import quad_potential, QuadPotentialDiagAdapt
from pymc3.step_methods import step_sizes
from pymc3.backends.report import SamplerWarning, WarningType

logger = logging.getLogger('pymc3')

HMCStepData = namedtuple(
"HMCStepData",
Expand Down Expand Up @@ -53,10 +53,10 @@ def __init__(self, vars=None, scaling=None, step_scale=0.25, is_cov=False,
`energy`, and `random` methods.
**theano_kwargs: passed to theano functions
"""
model = modelcontext(model)
self._model = modelcontext(model)

if vars is None:
vars = model.cont_vars
vars = self._model.cont_vars
vars = inputvars(vars)

super(BaseHMC, self).__init__(vars, blocked=blocked, model=model,
Expand Down Expand Up @@ -110,11 +110,14 @@ def astep(self, q0):
"""Perform a single HMC iteration."""
p0 = self.potential.random()
start = self.integrator.compute_state(q0, p0)

model = self._model

if not np.isfinite(start.energy):
check_test_point = model.check_test_point()
error_logp = check_test_point.loc[(np.abs(check_test_point) >= 1e20) | np.isnan(check_test_point)]
self.potential.raise_ok(self._logp_dlogp_func._ordering.vmap)
raise ValueError('Bad initial energy: %s. The model '
'might be misspecified.' % start.energy)
logger.error("Bad initial energy, check any log probabilities that are inf or -inf, nan or very small:\n{}".format(error_logp.to_string()))
raise ValueError('Bad initial energy')

adapt_step = self.tune and self.adapt_step_size
step_size = self.step_adapt.current(adapt_step)
Expand Down
14 changes: 13 additions & 1 deletion pymc3/tests/test_hmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
from . import models
from pymc3.step_methods.hmc.base_hmc import BaseHMC
import pymc3
import pytest
import logging
from pymc3.theanof import floatX

logger = logging.getLogger('pymc3')

def test_leapfrog_reversible():
n = 3
Expand Down Expand Up @@ -38,3 +40,13 @@ def test_nuts_tuning():

assert not step.tune
assert np.all(trace['step_size'][5:] == trace['step_size'][5])

def test_nuts_error_reporting(caplog):
model = pymc3.Model()
with caplog.at_level(logging.ERROR) and pytest.raises(ValueError):
with model:
pymc3.HalfNormal('a', sd=1, transform=None, testval=-1)
pymc3.HalfNormal('b', sd=1, transform=None)
trace = pymc3.sample(init='adapt_diag', chains=1)
assert "Bad initial energy, check any log probabilities that are inf or -inf: a -inf\nb" in caplog.text

0 comments on commit 3cb4570

Please sign in to comment.