Linear Beta Schedule and Alpha-Bar
Problem Statement
Build the linear noise schedule used by the original DDPM paper and derive the two quantities every later formula depends on: the per-step signal retention alpha_t and the cumulative signal retention alpha_bar_t.
Background
The forward diffusion process corrupts data one small step at a time:
The variances are the noise schedule. DDPM uses a linear schedule: values spaced evenly (endpoints included) from beta_start to beta_end, with the defaults and for .
From the betas we define
is the running product, not a running sum. It is what makes the forward process collapse into a single closed-form Gaussian, so getting it right is the foundation of everything else in diffusion.
Your Task
Implement:
def linear_schedule(T, beta_start=1e-4, beta_end=0.02):
Return a tuple (betas, alphas, alpha_bars) of three 1-D NumPy arrays, each of length T, using 0-based indexing (element i corresponds to timestep in the maths above).
Input Format
- T (int): number of diffusion steps, T >= 1.
- beta_start, beta_end (float): first and last beta. Both endpoints must appear in the array.
Output Format
A tuple of three NumPy arrays (betas, alphas, alpha_bars).
Sample
b, a, ab = linear_schedule(5, 0.1, 0.5)
print(np.round(b, 4).tolist())
print(np.round(a, 4).tolist())
print(np.round(ab, 4).tolist())
[0.1, 0.2, 0.3, 0.4, 0.5]
[0.9, 0.8, 0.7, 0.6, 0.5]
[0.9, 0.72, 0.504, 0.3024, 0.1512]
Betas are evenly spaced from 0.1 to 0.5, alphas are 1 - beta, and alpha_bars is their cumulative product, so it decays quickly toward zero.
Example
b, a, ab = linear_schedule(5, 0.1, 0.5) print(np.round(b, 4).tolist()) print(np.round(a, 4).tolist()) print(np.round(ab, 4).tolist())
[0.1, 0.2, 0.3, 0.4, 0.5] [0.9, 0.8, 0.7, 0.6, 0.5] [0.9, 0.72, 0.504, 0.3024, 0.1512]
np.linspace(0.1, 0.5, 5) gives betas [0.1, 0.2, 0.3, 0.4, 0.5], so alphas are [0.9, 0.8, 0.7, 0.6, 0.5]. The cumulative product runs 0.9, 0.9*0.8 = 0.72, 0.72*0.7 = 0.504, 0.504*0.6 = 0.3024, 0.3024*0.5 = 0.1512 -- the signal that survives to each step. Using a cumulative sum instead would give values above 1, which is impossible for a variance-preserving process.
Constraints
T >= 1; whenT == 1the array holdsbeta_startonly.betasmust include both endpoints (np.linspace, notnp.arange).alpha_barsis a cumulative product, not a cumulative sum.- Use
float(float64) arrays; do not round inside the function.