Turn a cumulative-alpha schedule into the two quantities that actually describe "how hard is step t": the signal-to-noise ratio and its logarithm.
Under the closed form xt=αˉtx0+1−αˉtε, the signal power is αˉt and the noise power is 1−αˉt. Hence
SNR(t)=1−αˉtαˉt,λt=logSNR(t)
Two facts make this the right coordinate system for diffusion:
Implement:
def snr_and_logsnr(alpha_bars):
Return (snr, log_snr), two 1-D NumPy arrays the same length as alpha_bars.
A tuple (snr, log_snr) of NumPy arrays.
ab = np.array([0.9, 0.5, 0.1])
snr, ls = snr_and_logsnr(ab)
print(np.round(snr, 4).tolist())
print(np.round(ls, 4).tolist())
At αˉ=0.5 signal and noise power are equal, so SNR = 1.0 and log SNR = 0.0; at 0.9 the SNR is 9, and at 0.1 it is one ninth.
ab = np.array([0.9, 0.5, 0.1]) snr, ls = snr_and_logsnr(ab) print(np.round(snr, 4).tolist()) print(np.round(ls, 4).tolist())
[9.0, 1.0, 0.1111] [2.1972, 0.0, -2.1972]
0.9/(1-0.9) = 9, 0.5/0.5 = 1, 0.1/0.9 = 0.1111. Taking natural logs gives 2.1972, 0.0, -2.1972. The symmetry around alpha_bar = 0.5 is exact: log-SNR is an odd function of the signal fraction about that midpoint.
alpha_bars is in the open interval (0, 1), so no division by zero and no log(0).log_snr is the natural log.