Distribution
Distribution(batch_shape: tuple[int, ...] = (), event_shape: tuple[int, ...] = (), validate_args: bool | None = None)Abstract base for a probability distribution.
A distribution encodes a probability measure over a measurable space
and exposes a standard interface for sampling, evaluating
log-probabilities, and computing closed-form moments. Every concrete
distribution in lucid.distributions inherits from this class.
Subclasses set:
arg_constraints— dict of param-name →Constraint, used byvalidate_argsand to spell out the parameter domain.support—Constraintfor the random variable.has_rsample—Truefor reparameterisable families.batch_shape,event_shape.
Either rsample or sample (or both) must be overridden.
Parameters
batch_shapetuple[int, ...]= ()(), for a vector parameter of length n
it is (n,). Default is ().event_shapetuple[int, ...]= ()event_shape = (). Multivariate
distributions such as lucid.distributions.Dirichlet
have a non-empty event_shape. Default is ().validate_argsbool or None= NoneTrue, the parameters are checked against
arg_constraints at construction, and the value given to
log_prob, cdf and icdf is checked before it
is scored; a violation raises ValueError. None takes
the default, which is on and is changed for every distribution by
set_default_validate_args. Default is None.Attributes
arg_constraintsdict[str, Constraint]lucid.distributions.constraints.Constraint it must
satisfy. Populated by each concrete subclass.supportConstraint or NoneNone means
unconstrained. A family whose support depends on its parameters
(Uniform, Binomial) answers it as a property.has_rsampleboolTrue when the distribution implements
rsample — i.e., when the reparameterisation trick
(Kingma & Welling, 2013) is available and gradients flow through
sampled values.has_enumerate_supportboolTrue for finite discrete distributions that can enumerate
every possible outcome, enabling exact marginalisation.Notes
Shape semantics
Every tensor returned by sample or rsample has shape
where + denotes tuple concatenation. log_prob returns a
tensor of shape sample_shape + batch_shape, having reduced over
event_shape.
Reparameterisation
When has_rsample = True the sampler can be written as a
deterministic transformation of a fixed-distribution noise variable
:
This allows gradients to be estimated with low variance via the pathwise derivative, which is the backbone of the VAE objective (ELBO) and stochastic computation graphs in general.
Validation
With validation on, log_prob and cdf refuse a value
outside support, and every scorer refuses a value whose shape
does not end in event_shape or does not broadcast with
batch_shape + event_shape. icdf takes a probability, so
it refuses a value outside instead. That last check is
a deliberate difference from the reference framework, which does not
validate an icdf argument and answers nan there. A family whose
support is None has declared nothing to check a value
against, and its log_prob / cdf values are not checked. A
subclass gets all of this by defining the scorer: it does not call the
checks itself.
Examples
>>> import lucid.distributions as dist
>>> d = dist.Normal(loc=0.0, scale=1.0)
>>> d.batch_shape
()
>>> d.event_shape
()
>>> x = d.rsample((100,)) # shape (100,)
>>> x.shape
(100,)Used by 19
- lucid.distributions
- lucid.distributions._kl_cross
- lucid.distributions.bernoulli
- lucid.distributions.categorical
- lucid.distributions.continuous_extra
- lucid.distributions.discrete
- lucid.distributions.exponential
- lucid.distributions.extra
- lucid.distributions.independent
- lucid.distributions.kl
- lucid.distributions.matrix
- lucid.distributions.mixture
… 7 more
Constructors
1__init__
→None__init__(batch_shape: tuple[int, ...] = (), event_shape: tuple[int, ...] = (), validate_args: bool | None = None)Initialise batch/event shapes and optionally validate parameters.
Parameters
batch_shapetuple[int, ...]= ()event_shapetuple[int, ...]= ()validate_argsbool or None= NoneTrue, _validate_params is called immediately so
that out-of-constraint constructor arguments raise
ValueError at construction time rather than silently
producing NaN values later.Properties
7Shape of the batch of independent (but not identically parameterised) distributions.
Returns
tuple[int, ...]A tuple of integers. () for a single scalar distribution.
Shape of a single observation drawn from the distribution.
Returns
tuple[int, ...]() for univariate distributions. Non-empty for
multivariate distributions such as
lucid.distributions.Dirichlet.
Expected value of the distribution.
Returns
TensorA tensor of shape batch_shape. Raises
NotImplementedError if the distribution has no
closed-form mean (e.g. lucid.distributions.Cauchy).
Most likely value of the distribution (the argmax of the density).
Returns
TensorA tensor of shape batch_shape. Raises
NotImplementedError if not implemented by the
concrete subclass.
Standard deviation of the distribution.
Computed as . Concrete
subclasses may override this for numerical efficiency; the default
implementation delegates to variance.
Returns
TensorA tensor of shape batch_shape.
The set the random variable takes values in.
A family declares it as a class attribute, or as a property when it
depends on the parameters. None — this default — means no
value is refused.
Returns
Constraint or NoneThe support, or None when it is unconstrained.
Variance of the distribution.
Returns
TensorA tensor of shape batch_shape. The variance is the
second central moment, .
Raises NotImplementedError if not provided by the
concrete subclass.
Static methods
1Turn argument validation on or off for every distribution.
Applies at once to every distribution built without an explicit
validate_args — those read this default whenever they score or
are constructed — whether built before the call or after. One given
validate_args=True or False keeps its own setting.
Validation is on by default.
Parameters
valueboolRaises
TypeErrorvalue is not a bool.Examples
>>> import lucid.distributions as dist
>>> dist.Distribution.set_default_validate_args(False)
>>> dist.Normal(0.0, -1.0).scale # not refused
tensor(-1.)
>>> dist.Distribution.set_default_validate_args(True)Instance methods
8Cumulative distribution function (CDF) evaluated at value.
Returns the probability that a random variable drawn
from this distribution is less than or equal to value:
Parameters
valueTensorReturns
TensorValues in with the same shape as
broadcast(value, batch_shape).
Raises
ValueErrorNotImplementedErrorShannon differential (or discrete) entropy.
Defined as
for a continuous distribution and similarly for discrete ones. Measured in nats (natural logarithm base).
Returns
TensorA tensor of shape batch_shape. Raises
NotImplementedError if not implemented by the
concrete subclass.
Notes
Entropy quantifies the average amount of "surprise" or uncertainty in a single draw. Higher entropy means the distribution is more spread out / less predictable.
Return a tensor containing all values supported by a discrete distribution.
The result enumerates over dimension 0, so the shape of the result is
(cardinality,) + batch_shape + event_shape when expand=True, or
(cardinality,) + (1,) * len(batch_shape) + event_shape when
expand=False (where event_shape = () for univariate
distributions).
Parameters
expandbool= Truebatch_shape. Default is True.Returns
TensorTensor iterating over dimension 0.
Raises
NotImplementedErrorhas_enumerate_support = False).Inverse CDF (quantile function / percent-point function).
Given a probability returns the smallest such that :
The quantile function is particularly useful for inverse-CDF (Smirnov transform) sampling: if then .
Parameters
valueTensorReturns
TensorQuantiles with the same shape as
broadcast(value, batch_shape).
Raises
ValueErrorvalue is outside or
its shape does not fit the distribution. The reference
framework does not check an icdf argument; refusing one
that is not a probability is a deliberate difference.NotImplementedErrorLog-probability (log-density) evaluated at value.
For a continuous distribution with density this returns . For a discrete distribution with probability mass function this returns .
Working in log-space is numerically preferable to evaluating the density directly: products of probabilities become sums of log-probabilities, avoiding underflow for long sequences.
Parameters
valueTensorbatch_shape + event_shape.Returns
TensorLog-probability tensor of shape
broadcast(value.shape, batch_shape + event_shape)[:-len(event_shape)].
In the scalar / univariate case this simplifies to
broadcast(value.shape, batch_shape).
Raises
ValueErrorvalue is outside support or
its shape does not fit the distribution.NotImplementedErrorProbability density (or mass) at value.
Computed as via log_prob. For
numerical stability prefer working with log_prob directly;
use this method only when the raw density value is needed.
Parameters
valueTensorReturns
TensorNon-negative density or probability-mass values.
Reparameterised sample — gradients flow through the noise.
Unlike sample, rsample expresses the stochastic node as
a deterministic transformation of a parameter-free noise variable:
This factorisation allows the gradient to be estimated cheaply via the pathwise (re-parameterisation) estimator, which has much lower variance than the REINFORCE estimator.
Concrete distributions must override either this or sample.
Only distributions that admit a differentiable sampler set
has_rsample = True.
Parameters
sample_shapetuple[int, ...]= ()sample_shape + batch_shape + event_shape.Returns
TensorA tensor attached to the autograd graph through the distribution parameters.
Raises
NotImplementedErrorhas_rsample = False). Use sample
instead in that case.Draw independent, identically distributed samples.
The default implementation calls rsample and detaches the
result from the autograd graph, so gradients do not flow through
the returned tensor. Discrete distributions that cannot be
reparameterised must override this method directly instead.
Parameters
sample_shapetuple[int, ...]= ()sample_shape + batch_shape + event_shape.
Default is (), which returns a single sample with shape
batch_shape + event_shape.Returns
TensorA detached tensor (no gradient) of shape
sample_shape + batch_shape + event_shape.