Skip to content

Custom distribution's random method fails if it depends on transformed RVs #2900

Closed
@lucianopaz

Description

@lucianopaz

Description of your problem

When trying to define a custom Continuous distribution which depends on random variables that are automatically transformed to *_log__ or *_logodds__ inside a Model, pymc3.draw_values fails.

Please provide a minimal, self-contained, and reproducible example.

Provided in the following gist

The example that I show uses a custom normally distributed variable c that depends on the variables a and b, which are automatically transformed.

Please provide the full traceback.

bar.c.random() failed with the following traceback
Traceback (most recent call last):
  File "test_pymc3_custom_distribution.py", line 39, in <module>
    bar.c.random()
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 41, in __call__
    return getattr(self.obj, self.method_name)(*args, **kwargs)
  File "test_pymc3_custom_distribution.py", line 16, in random
    a, b = pm.distributions.draw_values([self.a, self.b], point=point)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 218, in draw_values
    givens[name] = (node, _draw_value(node, point=point))
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 285, in _draw_value
    func = _compile_theano_function(param, variables)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/memoize.py", line 20, in memoizer
    cache[key] = obj(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 247, in _compile_theano_function
    allow_input_downcast=True)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 317, in function
    output_keys=output_keys)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 486, in pfunc
    output_keys=output_keys)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 1839, in orig_function
    name=name)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 1487, in __init__
    accept_inplace)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 181, in std_fgraph
    update_mapping=update_mapping)
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/fg.py", line 175, in __init__
    self.__import_r__(output, reason="init")
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/fg.py", line 356, in __import_r__
    raise MissingInputError("Undeclared input", variable=variable)
MissingInputError: Undeclared input

Testing pm.distributions.draw_values([c])
pm.distributions.draw_values([bar.c]) failed with the following traceback
Traceback (most recent call last):
  File "test_pymc3_custom_distribution.py", line 49, in <module>
    pm.distributions.draw_values([bar.c])
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 221, in draw_values
    values.append(_draw_value(param, point=point, givens=givens.values()))
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 279, in _draw_value
    return param.random(point=point, size=None)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/model.py", line 41, in __call__
    return getattr(self.obj, self.method_name)(*args, **kwargs)
  File "test_pymc3_custom_distribution.py", line 16, in random
    a, b = pm.distributions.draw_values([self.a, self.b], point=point)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 218, in draw_values
    givens[name] = (node, _draw_value(node, point=point))
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 285, in _draw_value
    func = _compile_theano_function(param, variables)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/memoize.py", line 20, in memoizer
    cache[key] = obj(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pymc3/distributions/distribution.py", line 247, in _compile_theano_function
    allow_input_downcast=True)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function.py", line 317, in function
    output_keys=output_keys)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/pfunc.py", line 486, in pfunc
    output_keys=output_keys)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 1839, in orig_function
    name=name)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 1487, in __init__
    accept_inplace)
  File "/usr/local/lib/python2.7/dist-packages/theano/compile/function_module.py", line 181, in std_fgraph
    update_mapping=update_mapping)
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/fg.py", line 175, in __init__
    self.__import_r__(output, reason="init")
  File "/usr/local/lib/python2.7/dist-packages/theano/gof/fg.py", line 356, in __import_r__
    raise MissingInputError("Undeclared input", variable=variable)
MissingInputError: Undeclared input

Please provide any additional information below.

After taking a closer look at what happens when draw_values is called inside of Foo.random, it appears that in the call draw_values([self.a, self.b]), the random methods of both self.a and self.b never get called because the named nodes Bar_a_log__ and Bar_b_logodds__ are found first. This means that a drawn value of a will try to use a value drawn from Bar_a_log__ and Bar_b_logodds__ as a given. When the call, to _draw_value([Bar_a_log__]) happens, this variable has its random attribute set to None, and it is then interpreted as a theano function with no input given to it.

Versions and main components

  • PyMC3 Version: 3.3
  • Theano Version: 1.0.1
  • Python Version: Both 2.7.12 and 3.5.2
  • Operating system: Ubuntu 16.04
  • How did you install PyMC3: pip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions