Skip to content

Commit

Permalink
Merge 7cbbaf4 into 64f0b2c
Browse files Browse the repository at this point in the history
  • Loading branch information
sidravi1 committed May 22, 2019
2 parents 64f0b2c + 7cbbaf4 commit 4c1190d
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 35 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ env:
- FLOATX='float64' TESTCMD="--durations=10 --cov-append pymc3/tests/test_distributions_random.py pymc3/tests/test_shared.py pymc3/tests/test_smc.py pymc3/tests/test_sampling.py pymc3/tests/test_parallel_sampling.py pymc3/tests/test_dist_math.py pymc3/tests/test_distribution_defaults.py pymc3/tests/test_distributions_timeseries.py pymc3/tests/test_random.py"
- FLOATX='float64' TESTCMD="--durations=10 --cov-append pymc3/tests/test_examples.py pymc3/tests/test_posteriors.py pymc3/tests/test_gp.py"
- FLOATX='float64' TESTCMD="--durations=10 --cov-append pymc3/tests/test_variational_inference.py pymc3/tests/test_updates.py pymc3/tests/test_shape_handling.py"
- PYTHON_VERSION=3.5 FLOATX='float64' ENVNAME="py35_testenv" TESTCMD="--cov-append pymc3/tests/test_sampling.py pymc3/tests/test_model_graph.py"

script:
- . ./scripts/test.sh $TESTCMD
Expand Down
6 changes: 1 addition & 5 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,13 @@
- Fixed an issue in `model_graph` that caused construction of the graph of the model for rendering to hang: replaced a search over the powerset of the nodes with a breadth-first search over the nodes. Fix for #3458.
- Removed variable annotations from `model_graph` but left type hints (Fix for #3465). This means that we support `python>=3.5.4`.
- Default `target_accept`for `HamiltonianMC` is now 0.65, as suggested in Beskos et. al. 2010 and Neal 2001.
- Fixed bug in `draw_values` that lead to intermittent errors in python3.5. This happened with some deterministic nodes that were drawn but not added to `givens`.

### Deprecations

- `nuts_kwargs` and `step_kwargs` have been deprecated in favor of using the standard `kwargs` to pass optional step method arguments.
- `SGFS` and `CSG` have been removed (Fix for [#3353](https://github.com/pymc-devs/pymc3/issues/3353)). They have been moved to [pymc3-experimental](https://github.com/pymc-devs/pymc3-experimental).
- References to `live_plot` and corresponding notebooks have been removed.
- Function `approx_hessian` was removed, due to `numdifftools` becoming incompatible with current `scipy`. The function was already optional, only available to a user who installed `numdifftools` separately, and not hit on any common codepaths. [#3485](https://github.com/pymc-devs/pymc3/pull/3485).
- Deprecated `vars` parameter of `sample_posterior_predictive` in favor of `varnames`.
- References to `live_plot` and corresponding notebooks have been removed.
- Deprecated `vars` parameters of `sample_posterior_predictive` and `sample_prior_predictive` in favor of `var_names`. At least for the latter, this is more accurate, since the `vars` parameter actually took names.
- Function `approx_hessian` was removed, due to `numdifftools` becoming incompatible with current `scipy`. The function was already optional, only available to a user who installed `numdifftools` separately, and not hit on any common codepaths. [#3485](https://github.com/pymc-devs/pymc3/pull/3485).- Deprecated `vars` parameters of `sample_posterior_predictive` and `sample_prior_predictive` in favor of `var_names`. At least for the latter, this is more accurate, since the `vars` parameter actually took names.


## PyMC3 3.6 (Dec 21 2018)
Expand Down
17 changes: 2 additions & 15 deletions pymc3/distributions/distribution.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ def draw_values(params, point=None, size=None):
# nodes in the `params` list.
stack.extend([node for node in named_nodes_parents[next_]
if node is not None and
(node, size) not in drawn])
(node, size) not in drawn and
node not in params])

# the below makes sure the graph is evaluated in order
# test_distributions_random::TestDrawValues::test_draw_order fails without it
Expand All @@ -419,20 +420,6 @@ def draw_values(params, point=None, size=None):
evaluated[param_idx] = drawn[(param, size)]
else:
try: # might evaluate in a bad order,
# Sometimes _draw_value recurrently calls draw_values.
# This may set values for certain nodes in the drawn
# dictionary, but they don't get added to the givens
# dictionary. Here, we try to fix that.
if param in named_nodes_children:
for node in named_nodes_children[param]:
if (
node.name not in givens and
(node, size) in drawn
):
givens[node.name] = (
node,
drawn[(node, size)]
)
value = _draw_value(param,
point=point,
givens=givens.values(),
Expand Down
2 changes: 2 additions & 0 deletions pymc3/model_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ def make_graph(self):
'\tconda install -c conda-forge python-graphviz')
graph = graphviz.Digraph(self.model.name)
for shape, var_names in self.get_plates().items():
if isinstance(shape, SharedVariable):
shape = shape.eval()
label = ' x '.join(map('{:,d}'.format, shape))
if label:
# must be preceded by 'cluster' to get a box around it
Expand Down
43 changes: 38 additions & 5 deletions pymc3/tests/test_distributions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

from .helpers import SeededTest, select_by_precision
from ..vartypes import continuous_types
from ..model import Model, Point, Deterministic
from ..blocking import DictToVarBijection
from ..model import Model, Point, Potential, Deterministic
from ..blocking import DictToVarBijection, DictToArrayBijection, ArrayOrdering
from ..distributions import (
DensityDist, Categorical, Multinomial, VonMises, Dirichlet,
MvStudentT, MvNormal, MatrixNormal, ZeroInflatedPoisson,
Expand Down Expand Up @@ -471,9 +471,37 @@ def check_int_to_1(self, model, value, domain, paramdomains):
area = integrate_nd(pdfx, domain, value.dshape, value.dtype)
assert_almost_equal(area, 1, err_msg=str(pt))

def check_dlogp(self, model, value, domain, paramdomains):
try:
from numdifftools import Gradient
except ImportError:
return
if not model.cont_vars:
return

domains = paramdomains.copy()
domains['value'] = domain
bij = DictToArrayBijection(
ArrayOrdering(model.cont_vars), model.test_point)
dlogp = bij.mapf(model.fastdlogp(model.cont_vars))
logp = bij.mapf(model.fastlogp)

def wrapped_logp(x):
try:
return logp(x)
except:
return np.nan

ndlogp = Gradient(wrapped_logp)
for pt in product(domains, n_samples=100):
pt = Point(pt, model=model)
pt = bij.map(pt)
decimals = select_by_precision(float64=6, float32=4)
assert_almost_equal(dlogp(pt), ndlogp(pt), decimal=decimals, err_msg=str(pt))

def checkd(self, distfam, valuedomain, vardomains, checks=None, extra_args=None):
if checks is None:
checks = (self.check_int_to_1, )
checks = (self.check_int_to_1, self.check_dlogp)

if extra_args is None:
extra_args = {}
Expand Down Expand Up @@ -912,8 +940,7 @@ def test_wishart(self, n):
# This check compares the autodiff gradient to the numdiff gradient.
# However, due to the strict constraints of the wishart,
# it is impossible to numerically determine the gradient as a small
# pertubation breaks the symmetry. Thus disabling. Also, numdifftools was
# removed in June 2019, so an alternative would be needed.
# pertubation breaks the symmetry. Thus disabling.
#
# self.checkd(Wishart, PdMatrix(n), {'n': Domain([2, 3, 4, 2000]), 'V': PdMatrix(n)},
# checks=[self.check_dlogp])
Expand Down Expand Up @@ -1093,6 +1120,12 @@ def logp(x):
return -log(2 * .5) - abs(x - .5) / .5
self.checkd(DensityDist, R, {}, extra_args={'logp': logp})

def test_addpotential(self):
with Model() as model:
value = Normal('value', 1, 1)
Potential('value_squared', -value ** 2)
self.check_dlogp(model, value, R, {})

def test_get_tau_sigma(self):
sigma = np.array([2])
assert_almost_equal(continuous.get_tau_sigma(sigma=sigma), [1. / sigma**2, sigma])
Expand Down
4 changes: 4 additions & 0 deletions pymc3/tests/test_model_graph.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import numpy as np
import pymc3 as pm
import theano as th
from pymc3.model_graph import ModelGraph, model_to_graphviz

from .helpers import SeededTest
Expand All @@ -19,6 +20,9 @@ def radon_model():
np.tile(np.arange(counties, dtype=int), d),
np.arange(r)
))

floor_measure = th.shared(floor_measure)

with pm.Model() as model:
sigma_a = pm.HalfCauchy('sigma_a', 5)
gamma = pm.Normal('gamma', mu=0., sigma=1e5, shape=3)
Expand Down
2 changes: 1 addition & 1 deletion pymc3/tuning/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .starting import find_MAP
from .scaling import find_hessian, trace_cov, guess_scaling
from .scaling import approx_hessian, find_hessian, trace_cov, guess_scaling
36 changes: 35 additions & 1 deletion pymc3/tuning/scaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,41 @@
from ..theanof import hessian_diag, inputvars
from ..blocking import DictToArrayBijection, ArrayOrdering

__all__ = ['find_hessian', 'trace_cov', 'guess_scaling']
__all__ = ['approx_hessian', 'find_hessian', 'trace_cov', 'guess_scaling']


def approx_hessian(point, vars=None, model=None):
"""
Returns an approximation of the Hessian at the current chain location.
Parameters
----------
model : Model (optional if in `with` context)
point : dict
vars : list
Variables for which Hessian is to be calculated.
"""
from numdifftools import Jacobian

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

point = Point(point, model=model)

bij = DictToArrayBijection(ArrayOrdering(vars), point)
dlogp = bij.mapf(model.fastdlogp(vars))

def grad_logp(point):
return np.nan_to_num(dlogp(point))

'''
Find the jacobian of the gradient function at the current position
this should be the Hessian; invert it to find the approximate
covariance matrix.
'''
return -Jacobian(grad_logp)(bij.map(point))


def fixed_hessian(point, vars=None, model=None):
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Keras>=2.0.8
nbsphinx>=0.2.13
nose>=1.3.7
nose-parameterized==0.6.0
numdifftools>=0.9.20
numpy>=1.13.0
numpydoc==0.7.0
pycodestyle>=2.3.1
Expand Down
7 changes: 3 additions & 4 deletions scripts/create_testenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ command -v conda >/dev/null 2>&1 || {
exit 1;
}

ENVNAME="${ENVNAME:-testenv}" # if no ENVNAME is specified, use testenv
ENVNAME="testenv"
PYTHON_VERSION=${PYTHON_VERSION:-3.6} # if no python specified, use 3.6

if [ -z ${GLOBAL} ]
Expand All @@ -33,11 +33,10 @@ then
fi
source activate ${ENVNAME}
fi
pip install --upgrade pip

conda install --yes mkl-service
conda install --yes numpy scipy mkl-service
conda install --yes -c conda-forge python-graphviz

pip install --upgrade pip

# Install editable using the setup.py

Expand Down
2 changes: 0 additions & 2 deletions scripts/install_miniconda.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,3 @@ fi
export PATH="$INSTALL_FOLDER/bin:$PATH"
echo "Adding $INSTALL_FOLDER to PATH. Consider adding it in your .rc file as well."
conda update -q -y conda
# Uninstalling miniconda's numpy to avoid conflicting versions when creating the test env
pip uninstall -y numpy
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ def get_version():
package_data={'docs': ['*']},
include_package_data=True,
classifiers=classifiers,
python_requires=">=3.5.4",
install_requires=install_reqs,
extras_require={
"plots": ["arviz"],
Expand Down

0 comments on commit 4c1190d

Please sign in to comment.