Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Unexpected TypeError when inverting scipy-based function #7401

Open
Spiruel opened this issue Jul 5, 2024 · 2 comments
Open

BUG: Unexpected TypeError when inverting scipy-based function #7401

Spiruel opened this issue Jul 5, 2024 · 2 comments
Labels
bug needs info Additional information required

Comments

@Spiruel
Copy link

Spiruel commented Jul 5, 2024

Describe the issue:

I am adding parameters into a model in an attempt to perform bayesian inversion. I am getting a typeerror when introducing variables, which is unexpected behaviour.

Reproduceable code example:

import numpy as np
import pymc as pm
import pytensor.tensor as pt
from pytensor.graph import Op, Apply
import arviz as az
import prosail

# Define the new model function with additional parameters
def my_model(n, cab, car, cbrown, cw, cm, lai, tto, tts, x):
    reflectance = prosail.run_prosail(n=n, cab=cab, car=car, cbrown=cbrown, cw=cw, cm=cm, lai=lai, tto=10., tts=30., lidfa=-1.0, hspot=0.01, psi=0., prospect_version="D", factor='SDR', rsoil=.5, psoil=.5)
    return reflectance

def my_loglike(n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data):
    for param in (n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data):
        if not isinstance(param, (float, np.ndarray)):
            raise TypeError(f"Invalid input type to loglike: {type(param)}")
    model = my_model(n, cab, car, cbrown, cw, cm, lai, tto, tts, x)
    return -0.5 * ((data - model) / sigma) ** 2 - np.log(np.sqrt(2 * np.pi)) - np.log(sigma)

class LogLike(Op):
    def make_node(self, n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data) -> Apply:
        n = pt.as_tensor(n)
        cab = pt.as_tensor(cab)
        car = pt.as_tensor(car)
        cbrown = pt.as_tensor(cbrown)
        cw = pt.as_tensor(cw)
        cm = pt.as_tensor(cm)
        lai = pt.as_tensor(lai)
        tto = pt.as_tensor(tto)
        tts = pt.as_tensor(tts)
        sigma = pt.as_tensor(sigma)
        x = pt.as_tensor(x)
        data = pt.as_tensor(data)

        inputs = [n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data]
        outputs = [data.type()]

        return Apply(self, inputs, outputs)

    def perform(self, node: Apply, inputs: list[np.ndarray], outputs: list[list[None]]) -> None:
        n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data = inputs
        loglike_eval = my_loglike(n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data)
        outputs[0][0] = np.asarray(loglike_eval)

def custom_dist_loglike(data, n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x):
    return loglike_op(n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, data)

N = 2101
sigma = 1.0
x = np.linspace(0.0, 9.0, N)

# True parameter values for testing
ntrue = 0.4
cabtrue = 0.1
cartrue = 0.2
cbrowntrue = 0.3
cwtrue = 0.05
cmtrue = 0.07
laitrue = 3.0
ttotrue = 0.15
ttstrue = 0.25

truemodel = my_model(ntrue, cabtrue, cartrue, cbrowntrue, cwtrue, cmtrue, laitrue, ttotrue, ttstrue, x)

rng = np.random.default_rng(716743)
data = sigma * rng.normal(size=N) + truemodel

loglike_op = LogLike()

test_out = loglike_op(ntrue, cabtrue, cartrue, cbrowntrue, cwtrue, cmtrue, laitrue, ttotrue, ttstrue, sigma, x, data)

with pm.Model() as no_grad_model:

    n = pm.Uniform("n", lower=-1.0, upper=5.0, initval=ntrue)
    cab = pm.Uniform("cab", lower=-5, upper=60, initval=cabtrue)
    car = pm.Uniform("car", lower=-5, upper=20, initval=cartrue)
    cbrown = pm.Uniform("cbrown", lower=0, upper=2, initval=cbrowntrue)
    cw = pm.Uniform("cw", lower=-10.0, upper=10, initval=cwtrue)
    cm = pm.Uniform("cm", lower=0, upper=0.2, initval=cmtrue)
    lai = pm.Uniform("lai", lower=0.5, upper=5.0, initval=laitrue)
    tto = pm.Uniform("tto", lower=0.0, upper=20.0, initval=ttotrue)
    tts = pm.Uniform("tts", lower=0, upper=60.0, initval=ttstrue)

    likelihood = pm.CustomDist(
        "likelihood", n, cab, car, cbrown, cw, cm, lai, tto, tts, sigma, x, observed=data, logp=custom_dist_loglike
    )

import warnings
with warnings.catch_warnings():
    warnings.simplefilter("ignore")

    with no_grad_model:
        idata_no_grad = pm.sample(100000, step=pm.DEMetropolisZ())

Error message:

TypeError: No matching definition for argument type(s) float64, array(float64, 0d, C), float64, float64
Apply node that caused the error: LogLike(Composite{((i2 * sigmoid(i0)) - (i1 - sigmoid(i0)))}.0, Composite{((i2 * sigmoid(i0)) + (i3 * (i1 - sigmoid(i0))))}.0, Composite{((i2 * sigmoid(i0)) + (i3 * (i1 - sigmoid(i0))))}.0, Composite{(i1 * sigmoid(i0))}.0, Composite{((i2 * sigmoid(i0)) + (i3 * (i1 - sigmoid(i0))))}.0, Composite{(i1 * sigmoid(i0))}.0, Composite{((i2 * sigmoid(i0)) + (i3 * (i1 - sigmoid(i0))))}.0, Composite{(i1 * sigmoid(i0))}.0, Composite{(i1 * sigmoid(i0))}.0, 1.0, [0.0000000 ... 00000e+00], likelihood{[-0.589307 ... .02688868]})
Toposort index: 9
Inputs types: [TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float64, shape=()), TensorType(float32, shape=()), TensorType(float64, shape=(2101,)), TensorType(float64, shape=(2101,))]
Inputs shapes: [(), (), (), (), (), (), (), (), (), (), (2101,), (2101,)]
Inputs strides: [(), (), (), (), (), (), (), (), (), (), (8,), (8,)]
Inputs values: [array(0.4), array(0.1), array(0.2), array(0.3), array(0.05), array(0.07), array(3.), array(0.15), array(0.25), array(1., dtype=float32), 'not shown', 'not shown']
Inputs type_num: [12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12]
Outputs clients: [['output']]

PyMC version information:

'5.12.0'

Context for the issue:

No response

@Spiruel Spiruel added the bug label Jul 5, 2024
Copy link

welcome bot commented Jul 5, 2024

Welcome Banner]
🎉 Welcome to PyMC! 🎉 We're really excited to have your input into the project! 💖

If you haven't done so already, please make sure you check out our Contributing Guidelines and Code of Conduct.

@ricardoV94
Copy link
Member

ricardoV94 commented Jul 5, 2024

The error seems to happen inside your Loglike code? Doesn't look like a PyMC or PyTensor error

@ricardoV94 ricardoV94 added the needs info Additional information required label Jul 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug needs info Additional information required
Projects
None yet
Development

No branches or pull requests

2 participants