扩散模型的前向过程将干净图像 x0 逐步加噪,得到噪声图像 xt:
xt=αˉt⋅x0+1−αˉt⋅ϵ,ϵ∼N(0,I)其中:
- αˉt=∏s=1tαs=∏s=1t(1−βs) 是累积信噪比
- βt 是噪声调度表(本项目使用线性调度:β1=0.0001,βT=0.02)
- 当 t 增大时,αˉt→0,图像趋向纯噪声
直觉理解:前向过程是一个确定性的"加噪配方"。给定 x0 和时间步 t,可以一步跳到 xt,无需逐步模拟。
反向过程的目标是从噪声 xT∼N(0,I) 逐步恢复干净图像。核心问题是估计去噪函数:
x^0=D(xt,t)传统方法训练神经网络来学习 D;本项目的方法直接用数据统计量构造 D。
本项目使用 DDIM (Denoising Diffusion Implicit Models) 调度器进行采样。DDIM 的更新规则为:
xt−1=αˉt−1⋅x^0+1−αˉt−1⋅ϵ^t其中预测噪声 ϵ^t 由预测的 x^0 反推:
ϵ^t=1−αˉtxt−αˉt⋅x^0在代码中,这对应 BaseDenoiser.compute_noise_from_x0() 方法:
def compute_noise_from_x0(self, x_t, pred_x0, timestep):
alpha_prod = self.scheduler.alphas_cumprod[t]
beta_prod = 1 - alpha_prod
sqrt_alpha = torch.sqrt(alpha_prod)
sqrt_beta = torch.sqrt(beta_prod + 1e-8)
return (x_t - sqrt_alpha * pred_x0) / sqrt_beta
为什么用 DDIM 而不是 DDPM? DDIM 是确定性采样(无额外随机噪声),这使得不同方法在相同种子下可以公平对比。
给定噪声观测 xt,贝叶斯最优估计为后验均值:
D∗(xt,t)=E[x0∣xt]=∫p(xt∣x0)⋅p(x0)dx0∫x0⋅p(xt∣x0)⋅p(x0)dx0由于 p(xt∣x0)=N(xt;αˉtx0,(1−αˉt)I),展开后得到:
D∗(xt,t)=∑iexp(−2(1−αˉt)∥xt−αˉtx0(i)∥2)∑ix0(i)⋅exp(−2(1−αˉt)∥xt−αˉtx0(i)∥2)这就是 OptimalDenoiser 实现的公式——对数据集中所有图像做 softmax 加权平均。
如果假设数据分布为高斯 x0∼N(μ,Σ),则贝叶斯最优去噪器退化为线性形式:
DWiener(xt,t)=Lt⋅xt+Ht⋅μ其中:
- Lt=(1−αˉt)I+αˉtΣαˉtΣ⋅αˉt1
- Ht=I−Ltαˉt
通过对协方差矩阵 Σ 做 SVD 分解 Σ=UΛVH,可以高效计算收缩因子:
shrinki=(1−αˉt)+αˉtλiαˉtλiPCA Locality 方法的核心发现:扩散模型的去噪操作具有空间局部性——预测某个像素的值主要依赖于其邻域像素,而非全图。
这种局部性可以从数据协方差矩阵的结构中自然涌现。具体来说,Wiener 滤波矩阵 LtLtT 的非对角元素在远离对角线时迅速衰减,形成类似"局部感受野"的模式。
PCA Locality 方法将这种局部性显式地编码为二值掩码,用于修改最优去噪器中的距离度量,使其只关注局部像素。
本项目使用线性噪声调度:
# 在 BaseDenoiser.__init__ 中通过 DDIMScheduler 设置
DDIMScheduler(
beta_start=0.0001, # β₁
beta_end=0.02, # β_T
beta_schedule="linear",
prediction_type="epsilon", # 预测噪声 ε
)
时间步从 999(高噪声)到 0(低噪声),采样时使用 num_inference_steps(默认 10)个等间距时间步。