Compute the simple DDPM training loss of a toy linear denoiser on one batch.
xt=αˉtx0+1−αˉtϵ,ϵ^=xtW+Ttwt+b ℓi=D1d=1∑D(ϵ^i,d−ϵi,d)2,L=B1i=1∑BℓiHere x0 holds the clean samples of shape (B, ...), timesteps holds one integer timestep t per sample, noise holds the Gaussian noise ϵ with the shape of x0, and αˉt is alpha_bars at index t. The length of alpha_bars is T. Before the denoiser runs, every sample is flattened so that xt and ϵ have shape (B, D), where D is the product of all non-batch sizes. The matrix W is weight of shape (D, D), applied on the right as x_t @ weight, not transposed. The vector wt is time_weight of shape (D,) and b is bias of shape (D,).
Return a dict with two keys. The key "loss" holds L as a Python float, and the key "per_sample_loss" holds the values ℓi as a PyTorch tensor of shape (B,) with the dtype of x0.
Input: x0 = [[1.0,-1.0],[0.5,2.0]], timesteps = [0,3], noise = [[0.2,-0.4],[1.0,0.5]], alpha_bars = [0.9,0.7,0.4,0.1], weight = [[0.5,0.1],[-0.2,0.3]], time_weight = [1.0,-1.0], bias = [0.0,0.1]
Output: {"loss":0.214014,"per_sample_loss":[0.17454,0.253488]}
Explanation: The first sample sits at t = 0, so its time feature is 0 and only the linear map of x_t contributes. The second sample sits at t = 3 of T = 4, so the time feature 0.75 scales time_weight before the squared error is averaged over both features.
Input: x0 = [[[[1.0,0.0],[-1.0,0.5]]]], timesteps = [1], noise = [[[[0.3,-0.6],[0.9,0.0]]]], alpha_bars = [0.8,0.5], weight = [[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,0.0],[0.0,0.0,0.0,1.0]], time_weight = [0.2,0.2,0.2,0.2], bias = [0.0,0.0,0.0,0.0]
Output: {"loss":0.389296,"per_sample_loss":[0.389296]}
Input: x0 = [[3.0,-2.0,1.0]], timesteps = [2], noise = [[0.4,0.1,-0.7]], alpha_bars = [0.6,0.3,0.0], weight = [[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]], time_weight = [0.0,0.0,0.0], bias = [0.0,0.0,0.0]
Output: {"loss":0.0,"per_sample_loss":[0.0]}
Reshaping x0 and noise to (B, -1) turns any sample shape into flat feature vectors that the matrix product can use.
Turning the integer timesteps into a floating-point column of shape (B, 1) lets the time feature broadcast against time_weight.
Taking the mean along dimension 1 gives one error per sample, and calling item on a 0-d tensor gives a Python float.
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Compute the simple DDPM training loss of a toy linear denoiser on one batch.
xt=αˉtx0+1−αˉtϵ,ϵ^=xtW+Ttwt+b ℓi=D1d=1∑D(ϵ^i,d−ϵi,d)2,L=B1i=1∑BℓiHere x0 holds the clean samples of shape (B, ...), timesteps holds one integer timestep t per sample, noise holds the Gaussian noise ϵ with the shape of x0, and αˉt is alpha_bars at index t. The length of alpha_bars is T. Before the denoiser runs, every sample is flattened so that xt and ϵ have shape (B, D), where D is the product of all non-batch sizes. The matrix W is weight of shape (D, D), applied on the right as x_t @ weight, not transposed. The vector wt is time_weight of shape (D,) and b is bias of shape (D,).
Return a dict with two keys. The key "loss" holds L as a Python float, and the key "per_sample_loss" holds the values ℓi as a PyTorch tensor of shape (B,) with the dtype of x0.
Input: x0 = [[1.0,-1.0],[0.5,2.0]], timesteps = [0,3], noise = [[0.2,-0.4],[1.0,0.5]], alpha_bars = [0.9,0.7,0.4,0.1], weight = [[0.5,0.1],[-0.2,0.3]], time_weight = [1.0,-1.0], bias = [0.0,0.1]
Output: {"loss":0.214014,"per_sample_loss":[0.17454,0.253488]}
Explanation: The first sample sits at t = 0, so its time feature is 0 and only the linear map of x_t contributes. The second sample sits at t = 3 of T = 4, so the time feature 0.75 scales time_weight before the squared error is averaged over both features.
Input: x0 = [[[[1.0,0.0],[-1.0,0.5]]]], timesteps = [1], noise = [[[[0.3,-0.6],[0.9,0.0]]]], alpha_bars = [0.8,0.5], weight = [[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,0.0],[0.0,0.0,0.0,1.0]], time_weight = [0.2,0.2,0.2,0.2], bias = [0.0,0.0,0.0,0.0]
Output: {"loss":0.389296,"per_sample_loss":[0.389296]}
Input: x0 = [[3.0,-2.0,1.0]], timesteps = [2], noise = [[0.4,0.1,-0.7]], alpha_bars = [0.6,0.3,0.0], weight = [[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]], time_weight = [0.0,0.0,0.0], bias = [0.0,0.0,0.0]
Output: {"loss":0.0,"per_sample_loss":[0.0]}
Reshaping x0 and noise to (B, -1) turns any sample shape into flat feature vectors that the matrix product can use.
Turning the integer timesteps into a floating-point column of shape (B, 1) lets the time feature broadcast against time_weight.
Taking the mean along dimension 1 gives one error per sample, and calling item on a 0-d tensor gives a Python float.
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array
Accepts: array