MixtureSameFamily
DistributionMixtureSameFamily(mixture_distribution: Categorical, component_distribution: Distribution, validate_args: bool | None = None)Finite mixture model where all components share the same distribution family.
MixtureSameFamily combines:
- a mixture distribution — a
Categoricalover components that assigns mixing weight to component , - a component distribution — a single
Distributionwhose rightmost batch dimension has size (one set of parameters per component).
This encodes the generative process:
Sampling is non-reparameterised because drawing the discrete index creates a discontinuous path through the mixture weights. For differentiable training through mixture models consider the ELBO lower bound or use relaxed Categorical samples.
Parameters
mixture_distributionCategoricalCategorical distribution over components.
Its batch_shape must be compatible with the leading batch
dimensions of component_distribution.component_distributionDistributionNormal(loc=..., scale=...) with loc.shape[-1] == K.validate_argsbool | None= NoneTrue, validate parameter constraints at construction time.Attributes
mixture_distributionCategoricalcomponent_distributionDistributionNotes
Log-probability is computed via the log-sum-exp trick to avoid underflow when summing exponentially small terms:
Mean (law of total expectation):
Variance (law of total variance):
This decomposes into within-component variance (first term) and between-component variance (second term).
Examples
>>> import lucid
>>> from lucid.distributions import MixtureSameFamily, Categorical, Normal
>>> # 2-component Gaussian mixture
>>> mix = Categorical(probs=lucid.tensor([0.3, 0.7]))
>>> comp = Normal(
... loc=lucid.tensor([-2.0, 2.0]),
... scale=lucid.tensor([0.5, 1.0]),
... )
>>> dist = MixtureSameFamily(mix, comp)
>>> samples = dist.sample((200,))
>>> samples.shape
(200,)Methods (5)
__init__
→None__init__(mixture_distribution: Categorical, component_distribution: Distribution, validate_args: bool | None = None)Construct a mixture-of-experts distribution.
Parameters
mixture_distributionCategoricalK mixture components. Its
batch_shape must match the resulting mixture batch shape, and
event_shape must be empty.component_distributionDistributionK components, i.e. component_distribution.batch_shape
must end with K matching mixture_distribution._num_events.validate_argsbool | None= NoneTrue, validate parameter constraints at construction time.Raises
ValueErrormixture_distribution is not Categorical or if the
rightmost batch dim of component_distribution does not equal
K.mean
→Tensormean: TensorExpected value via the law of total expectation: .
Returns
TensorMean of the mixture, shape (*batch_shape, *event_shape).
variance
→Tensorvariance: TensorVariance via the law of total variance.
Decomposes as within-component variance plus between-component variance:
Returns
TensorVariance of the mixture, shape (*batch_shape, *event_shape).
sample
→Tensorsample(sample_shape: tuple[int, ...] = ())Draw samples from the mixture by ancestral sampling.
The procedure is:
- Draw component indices .
- Draw one sample per component for the full output shape.
- Gather the sample corresponding to the drawn component index.
Parameters
sample_shapetuple[int, ...]= ()Returns
TensorSamples of shape (*sample_shape, *batch_shape, *event_shape).
log_prob
→Tensorlog_prob(value: Tensor)Log-probability of the mixture evaluated at value.
Uses the numerically stable log-sum-exp identity:
Parameters
valueTensor(*batch_shape, *event_shape).Returns
TensorLog-density values of shape (*batch_shape,).