From 2e57d536c229c7cb52b3dc40dc79e8892c892087 Mon Sep 17 00:00:00 2001 From: Ricardo Vieira Date: Mon, 17 Jul 2023 11:02:27 +0200 Subject: [PATCH] Bump PyTensor dependency to 2.13 --- conda-envs/environment-dev.yml | 2 +- conda-envs/environment-docs.yml | 2 +- conda-envs/environment-test.yml | 2 +- conda-envs/windows-environment-dev.yml | 2 +- conda-envs/windows-environment-test.yml | 2 +- pymc/distributions/distribution.py | 8 +++--- pymc/logprob/mixture.py | 3 ++- pymc/math.py | 29 +++------------------ requirements-dev.txt | 2 +- requirements.txt | 2 +- tests/distributions/test_dist_math.py | 2 +- tests/test_math.py | 34 ------------------------- 12 files changed, 16 insertions(+), 74 deletions(-) diff --git a/conda-envs/environment-dev.yml b/conda-envs/environment-dev.yml index 66595e81820..5b6b98c936e 100644 --- a/conda-envs/environment-dev.yml +++ b/conda-envs/environment-dev.yml @@ -14,7 +14,7 @@ dependencies: - numpy>=1.15.0 - pandas>=0.24.0 - pip -- pytensor>=2.12.0,<2.13 +- pytensor>=2.13.0,<2.14 - python-graphviz - networkx - scipy>=1.4.1 diff --git a/conda-envs/environment-docs.yml b/conda-envs/environment-docs.yml index b1c2b4ee7f5..87a6bf315bb 100644 --- a/conda-envs/environment-docs.yml +++ b/conda-envs/environment-docs.yml @@ -12,7 +12,7 @@ dependencies: - numpy>=1.15.0 - pandas>=0.24.0 - pip -- pytensor>=2.12.0,<2.13 +- pytensor>=2.13.0,<2.14 - python-graphviz - scipy>=1.4.1 - typing-extensions>=3.7.4 diff --git a/conda-envs/environment-test.yml b/conda-envs/environment-test.yml index 4ce5e06a6df..0dd7f8efc79 100644 --- a/conda-envs/environment-test.yml +++ b/conda-envs/environment-test.yml @@ -17,7 +17,7 @@ dependencies: - numpy>=1.15.0 - pandas>=0.24.0 - pip -- pytensor>=2.12.0,<2.13 +- pytensor>=2.13.0,<2.14 - python-graphviz - networkx - scipy>=1.4.1 diff --git a/conda-envs/windows-environment-dev.yml b/conda-envs/windows-environment-dev.yml index 86d1830d709..bf64ee8f4dd 100644 --- a/conda-envs/windows-environment-dev.yml +++ b/conda-envs/windows-environment-dev.yml @@ -14,7 +14,7 @@ dependencies: - numpy>=1.15.0 - pandas>=0.24.0 - pip -- pytensor>=2.12.0,<2.13 +- pytensor>=2.13.0,<2.14 - python-graphviz - networkx - scipy>=1.4.1 diff --git a/conda-envs/windows-environment-test.yml b/conda-envs/windows-environment-test.yml index 15953058364..a41f130b60d 100644 --- a/conda-envs/windows-environment-test.yml +++ b/conda-envs/windows-environment-test.yml @@ -17,7 +17,7 @@ dependencies: - numpy>=1.15.0 - pandas>=0.24.0 - pip -- pytensor>=2.12.0,<2.13 +- pytensor>=2.13.0,<2.14 - python-graphviz - networkx - scipy>=1.4.1 diff --git a/pymc/distributions/distribution.py b/pymc/distributions/distribution.py index 5c74080ace1..930d4976a50 100644 --- a/pymc/distributions/distribution.py +++ b/pymc/distributions/distribution.py @@ -34,6 +34,7 @@ from pytensor.tensor.random.op import RandomVariable from pytensor.tensor.random.rewriting import local_subtensor_rv_lift from pytensor.tensor.random.utils import normalize_size_param +from pytensor.tensor.rewriting.shape import ShapeFeature from pytensor.tensor.var import TensorVariable from typing_extensions import TypeAlias @@ -1229,15 +1230,12 @@ def create_partial_observed_rv( can_rewrite = True if can_rewrite: - # Rewrite doesn't work with boolean masks. Should be fixed after https://github.com/pymc-devs/pytensor/pull/329 - mask, antimask = mask.nonzero(), antimask.nonzero() - masked_rv = rv[mask] - fgraph = FunctionGraph(outputs=[masked_rv], clone=False) + fgraph = FunctionGraph(outputs=[masked_rv], clone=False, features=[ShapeFeature()]) [unobserved_rv] = local_subtensor_rv_lift.transform(fgraph, fgraph.outputs[0].owner) antimasked_rv = rv[antimask] - fgraph = FunctionGraph(outputs=[antimasked_rv], clone=False) + fgraph = FunctionGraph(outputs=[antimasked_rv], clone=False, features=[ShapeFeature()]) [observed_rv] = local_subtensor_rv_lift.transform(fgraph, fgraph.outputs[0].owner) # Make a clone of the observedRV, with a distinct rng so that observed and diff --git a/pymc/logprob/mixture.py b/pymc/logprob/mixture.py index 267670a835e..8a38928f329 100644 --- a/pymc/logprob/mixture.py +++ b/pymc/logprob/mixture.py @@ -52,6 +52,7 @@ local_rv_size_lift, local_subtensor_rv_lift, ) +from pytensor.tensor.rewriting.shape import ShapeFeature from pytensor.tensor.shape import shape_tuple from pytensor.tensor.subtensor import ( AdvancedSubtensor, @@ -205,7 +206,7 @@ def expand_indices( def rv_pull_down(x: TensorVariable, dont_touch_vars=None) -> TensorVariable: """Pull a ``RandomVariable`` ``Op`` down through a graph, when possible.""" - fgraph = FunctionGraph(outputs=dont_touch_vars or [], clone=False) + fgraph = FunctionGraph(outputs=dont_touch_vars or [], clone=False, features=[ShapeFeature()]) return pre_greedy_node_rewriter( fgraph, diff --git a/pymc/math.py b/pymc/math.py index 2f8520b0ecc..0cb86095ee4 100644 --- a/pymc/math.py +++ b/pymc/math.py @@ -75,13 +75,14 @@ where, zeros_like, ) +from pytensor.tensor.special import log_softmax, softmax try: from pytensor.tensor.basic import extract_diag except ImportError: from pytensor.tensor.nlinalg import extract_diag -from pytensor.tensor.nlinalg import det, matrix_dot, matrix_inverse, trace +from pytensor.tensor.nlinalg import matrix_inverse from scipy.linalg import block_diag as scipy_block_diag from pymc.pytensorf import floatX, ix_, largest_common_dtype @@ -267,31 +268,7 @@ def logdiffexp_numpy(a, b): return a + log1mexp_numpy(b - a, negative_input=True) -def invlogit(x, eps=None): - """The inverse of the logit function, 1 / (1 + exp(-x)).""" - if eps is not None: - warnings.warn( - "pymc.math.invlogit no longer supports the ``eps`` argument and it will be ignored.", - FutureWarning, - stacklevel=2, - ) - return pt.sigmoid(x) - - -def softmax(x, axis=None): - # Ignore vector case UserWarning issued by PyTensor. This can be removed once PyTensor - # drops that warning - with warnings.catch_warnings(): - warnings.simplefilter("ignore", UserWarning) - return pt.special.softmax(x, axis=axis) - - -def log_softmax(x, axis=None): - # Ignore vector case UserWarning issued by PyTensor. This can be removed once PyTensor - # drops that warning - with warnings.catch_warnings(): - warnings.simplefilter("ignore", UserWarning) - return pt.special.log_softmax(x, axis=axis) +invlogit = sigmoid def logbern(log_p): diff --git a/requirements-dev.txt b/requirements-dev.txt index 6032958e14e..713c09ceeb2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -18,7 +18,7 @@ numpydoc pandas>=0.24.0 polyagamma pre-commit>=2.8.0 -pytensor>=2.12.0,<2.13 +pytensor>=2.13.0,<2.14 pytest-cov>=2.5 pytest>=3.0 scipy>=1.4.1 diff --git a/requirements.txt b/requirements.txt index 82d327e62a3..41c350234e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,6 @@ cloudpickle fastprogress>=0.2.0 numpy>=1.15.0 pandas>=0.24.0 -pytensor>=2.12.0,<2.13 +pytensor>=2.13.0,<2.14 scipy>=1.4.1 typing-extensions>=3.7.4 diff --git a/tests/distributions/test_dist_math.py b/tests/distributions/test_dist_math.py index f0b6d8f87f7..2ccab76b1f1 100644 --- a/tests/distributions/test_dist_math.py +++ b/tests/distributions/test_dist_math.py @@ -224,7 +224,7 @@ def check_vals(fn1, fn2, *args): def test_multigamma(): - x = pt.vector("x") + x = pt.vector("x", shape=(1,)) p = pt.scalar("p") xvals = [np.array([v], dtype=config.floatX) for v in [0.1, 2, 5, 10, 50, 100]] diff --git a/tests/test_math.py b/tests/test_math.py index c5aed9246cf..ff9c8708c00 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -262,37 +262,3 @@ def test_expand_packed_triangular(): assert np.all(expand_upper.eval({packed: upper_packed}) == upper) assert np.all(expand_diag_lower.eval({packed: lower_packed}) == floatX(np.diag(vals))) assert np.all(expand_diag_upper.eval({packed: upper_packed}) == floatX(np.diag(vals))) - - -def test_invlogit_deprecation_warning(): - with pytest.warns( - FutureWarning, - match="pymc.math.invlogit no longer supports the", - ): - res = invlogit(np.array(-750.0), 1e-5).eval() - - with warnings.catch_warnings(): - warnings.simplefilter("error") - res_zero_eps = invlogit(np.array(-750.0)).eval() - - assert np.isclose(res, res_zero_eps) - - -@pytest.mark.parametrize( - "pytensor_function, pymc_wrapper", - [ - (pt.special.softmax, softmax), - (pt.special.log_softmax, log_softmax), - ], -) -def test_softmax_logsoftmax_no_warnings(pytensor_function, pymc_wrapper): - """Test that wrappers for pytensor functions do not issue Warnings""" - - vector = pt.vector("vector") - with pytest.warns(Warning) as record: - pytensor_function(vector) - assert {w.category for w in record.list} == {UserWarning, FutureWarning} - - with warnings.catch_warnings(): - warnings.simplefilter("error") - pymc_wrapper(vector)