ContinuousBernoulli
DistributionContinuousBernoulli(probs: Tensor | float | None = None, logits: Tensor | float | None = None, validate_args: bool | None = None)Continuous Bernoulli distribution on .
A continuous relaxation of the lucid.distributions.Bernoulli
distribution introduced by Loaiza-Ganem & Cunningham (2019) to fix the
well-known bias incurred by VAE decoders that use a Bernoulli
likelihood on real-valued image pixels in . Unlike the
naive "Bernoulli on [0,1]" likelihood, the Continuous Bernoulli has a
proper normalising constant and yields unbiased ELBO gradients.
Parameters
probsTensor or float= Nonelogits.logitsTensor or float= Noneprobs.validate_argsbool= NoneTrue, validate parameter constraints at construction time.Notes
Probability density on :
where the normalising constant is
Mean (closed form):
Important properties:
- Support: (continuous, not just ).
- Reduces to at .
- At or the density concentrates near 0 or 1 respectively.
- Reparameterisable via inverse CDF.
The Continuous Bernoulli is the correct likelihood for decoders that output a value in (e.g. MNIST pixel intensities) when the model is to remain a valid probabilistic model. Using a plain Bernoulli on continuous data produces an improper density and a systematically biased ELBO.
Examples
>>> import lucid
>>> from lucid.distributions import ContinuousBernoulli
>>> d = ContinuousBernoulli(probs=0.7)
>>> d.rsample((4,))
Tensor([...])
>>> d.log_prob(lucid.tensor(0.5))
Tensor(...)Methods (5)
__init__
→None__init__(probs: Tensor | float | None = None, logits: Tensor | float | None = None, validate_args: bool | None = None)Initialise a Continuous Bernoulli distribution.
Parameters
probsTensor | float | None= Nonelogits.logitsTensor | float | None= Noneprobs.validate_argsbool | None= NoneTrue, validate parameter constraints at construction time.mean
→Tensormean: Tensorp / (2p−1) + 1 / (2 atanh(1−2p)); ½ when p = ½.
variance
→Tensorvariance: TensorE[X²] − E[X]²; E[X²] computed via the same normaliser trick.
rsample
→Tensorrsample(sample_shape: tuple[int, ...] = ())Reparameterised sample via the closed-form icdf.
log_prob
→Tensorlog_prob(value: Tensor)x · l − softplus(l) + log C(p).