Debiased Estimator of the ELBO Weighting
Problem Statement
The variational bound decomposes into per-timestep KL terms. Given per-step eps-losses and their SNRs, compute the true ELBO-weighted total loss and compare it to the "simple" (unweighted) DDPM loss, reporting the ratio.
Background
The negative log-likelihood bound weights the eps-loss at each interior timestep by half the drop in SNR:
with SNR_{-1} taken as SNR_0 (so the first term has weight 0). The ELBO loss is sum_t w_t * eps_loss_t; the simple loss is sum_t eps_loss_t. Report both and their ratio (ELBO / simple).
Your Task
Implement:
def elbo_vs_simple(eps_loss, snr):
- eps_loss[t], snr[t]: aligned per-timestep lists.
Return a dict with "elbo", "simple", "ratio", each rounded to 4 decimals. If simple == 0, ratio is 0.0.
Input Format
- eps_loss: list of T non-negative losses.
- snr: list of T SNRs (decreasing).
Output Format
- A dict of three floats.
Sample
print(elbo_vs_simple([1.0, 1.0, 1.0], [8.0, 4.0, 2.0]))
Output:
{'elbo': 3.0, 'simple': 3.0, 'ratio': 1.0}
Example
print(elbo_vs_simple([1.0, 1.0, 1.0], [8.0, 4.0, 2.0]))
{'elbo': 3.0, 'simple': 3.0, 'ratio': 1.0}- Initialize the previous SNR to the first value, , to handle the boundary condition where the weight for the first timestep is zero.
- At , calculate the weight as , contributing to the ELBO sum.
- At , update the previous SNR to and compute , adding to the ELBO sum.
- At , update the previous SNR to and compute , adding to the ELBO sum, resulting in a total ELBO of .
- Compute the simple loss as the sum of all -losses: , and determine the ratio as .
- The final output is
{'elbo': 3.0, 'simple': 3.0, 'ratio': 1.0}
Constraints
len(eps_loss) == len(snr) == T,1 <= T <= 100000.w_t = 0.5*(SNR_{t-1} - SNR_t)withSNR_{-1} = SNR_0(first weight 0).elbo = sum w_t*eps_loss_t,simple = sum eps_loss_t; round all to 4 decimals.