Probability: Feature request: Random variable (distribution object) as result of mathematical functions of random variables (distributions)

Created on 12 Nov 2020  Â·  4Comments  Â·  Source: tensorflow/probability

Simple example that should have been possible:
X ~ Uniform(a,b)
Y ~ Uniform(c,d)
X,Y are independent. Then:
Z = X + Y
has some trapezoidoid (🙃) distribution over (a+c,b+d).

I would like to be able to sample Z directly. I would also like to read probability densities, interval probabilities, etc. from the Z distribution object. If a,b,c,d are trainable variables, I would like to be able to optimize them for a Maximum Likelihood Objective obtained by querying the Z distribution object with batches of targets.

This is obviously a very simple example. Ideally, I would be able to define distributions by applying (almost) arbitrary functions to multiple distribution objects, and seamlessly use the resulting distribution objects as I would use the built-in distributions. Regardless of the number of nesting levels, everything would be trainable end-to-end, to the extent the constituent functions and distributions were trainable.

I must admit I do not know how _tfp.distribution_s are trained now (although I have magically succeeded both via samples and via log-density), so I understand there is a possibility that my wishes are unrealistic. I have done my best trying to find documentation, blogs and web questions on how to combine random variables like this, with no success. Mixtures and joint distributions combine distribution probabilities and the joint sequential distribution allows building a sort of chaining graph, but to my knowledge none of the distribution classes offer a way to apply math functions to random variables represented as distribution objects and treat the resulting random variable as a distribution object.

Here is a minimal example program based on the example, trying (naïvely?) to add the variables directly:

import tensorflow as tf
import tensorflow_probability as tfp

X = tfp.distributions.Uniform(2, 3)
Y = tfp.distributions.Uniform(-1,2)

Z = X+Y

And here is the console output:

Traceback (most recent call last):
  File ".\dist_sum_test.py", line 7, in <module>
    Z = X+Y
TypeError: unsupported operand type(s) for +: 'Uniform' and 'Uniform'

All 4 comments

If I understand you correctly, I think tfd.Deterministic could help you here. Does this example help?

import tensorflow_probability as tfp
import matplotlib.pyplot as plt


tfd = tfp.distributions

joint_dist = tfd.JointDistributionSequential(
    [
        tfd.Uniform(2.0, 3.0),  # X
        tfd.Uniform(-1.0, 2.0),  # Y
        lambda y, x: tfd.Deterministic(x + y),  # Z
    ]
)

x, y, z = joint_dist.sample(100_000)

plt.hist(z.numpy(), bins=50)
plt.show()

z

Ideally, I would be able to define distributions by applying (almost) arbitrary functions to multiple distribution objects, and seamlessly use the resulting distribution objects as I would use the built-in distributions.

For the case of invertible transformations, Bijectors do exactly this. E.g., tfb.Square(tfd.Uniform(0., 2.)) is the distribution on [0, 4] of the square of a Uniform(0., 2.) random variable.

In general it's not possible to compute exact densities for sums and other non-invertible transformations of random variables. For example, the density of a sum of random variables is the convolution of the component densities, which often has no closed form. I suppose we could register some special cases, like Uniform + Uniform = Triangular or Normal + Normal = Normal, analogous to the registry of KL divergences, although this would necessarily be pretty limited since there are only a few families where these sums are tractable.

If you just want to sample some function of random variables, and you don't care about their densities, then the Deterministic approach suggested by @jeffpollock9 is probably your best bet.

I could imagine using importance sampling + KDE to estimate the integrals
in question, or some kind of quadrature (which we don't currently have in
TFP).

If you have a forward generative routine like you propose, you could
accumulate a particle density as the generative process proceeds. Then you
can return samples paired with the sample log-prob, and perhaps use those
with some kind of KDE to approximate the local densities, or the fraction
of mass in some span.

Brian Patton | Software Engineer | [email protected]

On Thu, Nov 12, 2020 at 10:41 AM Dave Moore notifications@github.com
wrote:

Ideally, I would be able to define distributions by applying (almost)
arbitrary functions to multiple distribution objects, and seamlessly use
the resulting distribution objects as I would use the built-in
distributions.

For the case of invertible transformations, Bijectors do exactly this.
E.g., tfb.Square(tfd.Uniform(0., 2.)) is the distribution on [0, 4] of
the square of a Uniform(0., 2.) random variable.

In general it's not possible to compute exact densities for sums and other
non-invertible transformations of random variables. For example, the
density of a sum of random variables is the convolution of the component
densities, which often has no closed form. I suppose we could register some
special cases, like Uniform + Uniform = Triangular or Normal + Normal =
Normal, analogous to the registry of KL divergences
https://github.com/tensorflow/probability/blob/v0.11.1/tensorflow_probability/python/distributions/kullback_leibler.py#L150,
although this would necessarily be pretty limited since there are only a
few families where these sums are tractable.

If you just want to sample some function of random variables, and you
don't care about their densities, then the Deterministic approach
suggested by @jeffpollock9 https://github.com/jeffpollock9 is probably
your best bet.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/tensorflow/probability/issues/1157#issuecomment-726157362,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AFJFSIYF6VNE4BTYJX5DB2TSPP63HANCNFSM4TTIGJ5A
.

Thank you all. I have learned a lot from your answers, and from doing some experiments based upon them.

@davmre Suggests using Bijectors for invertible transformations. The example transforms only a single (although 2D) input variable, so does not obviously (at least not to me) transfer to the case of combining variables. Thanks (also!) for pointing out that I am, in a sense, asking for too much.

@jeffpollock9's suggestion of defining a graph of distributions by using JointDistributionSequential with Deterministic nodes for the connections works well for pure sampling. Thanks! Sadly (for me), there seems to be no way around supplying values for all subdistributions when querying log_prob.

@brianwa84 Thanks for a very interesting answer. I have not yet dug into all details of it. I did an experiment with a home-brewn KDE to see if that would solve any problems. It appears to me that while the KDE is differentiable, to have differentiability through the distributions, one would need to have differentiable sample methods, but that should be enough. A better KDE method with adaptive bandwidth etc. could then transform "any" differentiable sampling into a differentiable PDF.

I am not quite done with this, but I wanted to let you know I have read your replies. Thanks again!

Was this page helpful?
0 / 5 - 0 ratings