数学原理
整个diffusion model可以分为两部分,一个是前向扩散过程,另一个是逆扩散过程,通俗理解为:前向扩散过程不停的往图片上加服从高斯分布的噪声,加到使图片变得“面目全非”
在扩散过程中,每次往图片上加的噪声就是逆过程的标签
前向扩散过程 forward diffusion
大致的扩散模型如下

扩散过程简单来说就是不停的往图片里加噪声,把图片加的面目全非。那怎么加,加多少呢?
假设原始数据为 x0,噪声为 z(在有些资料中写作 ϵt) , 那么我们可以用下面的公式来表示扩散过程
xt=1−βtxt−1+βtzt
其中 zt∼N(0,I) 是一个纯01高斯分布的噪声
我们可以定义每一步的转移概率 q(xt∣xt−1) 为从上一时刻的数据点 xt−1 生成当前时刻的数据点 xt 的概率分布
q(xt∣xt−1)=N(xt;1−βtxt−1,βtI)
其中,βt 是第 t 步的噪声参数。通过这样的过程,xt 将逐渐接近标准正态分布 N(0,I), I 是单位矩阵,表示噪声的协方差矩阵为 βtI
理解转移概率 q
这个定义意味着在每一步中,我们以一定的比例 1−βt 保留上一时刻的数据,同时添加服从 N(0,βtI) 的噪声。这种逐步添加噪声的方式使得数据点 xt 在 t 增加时逐渐变得模糊,最终趋近于标准正态分布 N(0,I)。
噪声调度 β
在扩散过程中,我们需要一个噪声调度 β 来控制噪声的大小。在实际应用中,我们可以通过调整 β 来控制模型的平滑程度。通常情况下,我们会在开始时使用较小的 β 值,逐渐增大 β 值,以逐渐增加噪声的强度。
常用参数选择
在实际应用中,选择合适的βmin和βmax值是关键。通常,选择需要通过实验和调优来确定。例如,以下是一些常见的选择:
βmin:通常取一个非常小的值,如 10−4 或 10−5。
βmax:通常取一个较大的值,如 0.02 或 0.1。
其他常见参数 α
我们一般说 β 是噪声强度的参数,那么 α=1−β 就表示 保留原始数据的比例,这时候我们讨论的是相邻的关系,但是很多时候我们需要使用初始值作为参数,我们就会用到 α=∏(1−β) 这样获得的就是从初始值开始的累计衰减量
那么新公式就是:
xt=αtx0+1−αtϵ
而对于递归的扩散算法写法,我们应该写作:
xt=αtxt−1+1−αtϵ
其中 ϵ 表示服从标准正态分布的噪声,这个公式说明,正向传播的每一次加噪就是当前层的图像和高斯噪声的线性组合
逆向扩散过程 Denoise
逆向扩散过程是前向扩散过程的逆过程,即从扩散后的数据点 xT 逐渐恢复到原始数据点 x0。
由于正向的传播是随机过程,所以我们在做逆向传播的时候很难直接找到逆映射 q(xt−1∣xt) 所以我们更优的做法是用神经网络的方法来进行拟合。
逆向扩散过程的目标是学习一个逆映射 fT,将扩散后的数据点 xT 映射回原始数据点 x0。
pθ(xt−1∣xt)=N(xt−1;μθ(xt,t),σθ(xt,t))

初始噪声采样
xT∼N(0,I)
表示一开始是纯噪声进行采样
逐步去噪
从 t=T开始,到 t=1 结束,逐步生成中间状态 xt−1:
xt−1∼N(xt−1;μθ(xt,t),σθ(xt,t))
其中,μθ(xt,t) 和 σθ(xt,t) 分别是逆映射的均值和方差。这些参数是通过学习得到的,通常使用神经网络来拟合。
μθ(xt,t)=1−βt1(xt−1−βtβtϵθ(xt,t))
σθ(xt,t)=βt
其中 βt=∏i=1t(1−βi),ϵθ(xt,t) 是一个神经网络预测的噪声成分
最大似然估计 maixmum linklihood estimation
我们需要用神经网络来拟合我们需要的分布,而最大似然估计就是能通过样本结果估计模型参数的一种方法,我们的目标是最大化似然函数
argθmaxt=1∏Tpθ(xt−1∣xt)
由于这个累乘的值非常难以计算,所以我们可以将累乘运算变成 log 的累加运算
于是我们有 min−logpθ(x0)
这里我们会用到一点变分推理的变分下界公式 ELBO, 暂时不解释
但是在化简之后我们会得到一项
Eq(x1:T∣x0)[DKL(q(xT∣x0)∣∣pθ(xT)]+t=2∑TDKL(q(xt−1∣xt,x0)∣∣pθ(xt−1∣xt))−logpθ(x0∣x1)
在实际应用中我们会发现第二项是影响结果的重中之重,所以我们要仔细研究其变化率
这里的KL散度表示的是在概率分布空间中 q 和 p 之间的距离,我们一个个来进行分析,首先就是 q 函数, 即正向传播噪声概率计算公式的分布, 这里就要用到贝叶斯公式(注意这里的 p 是估计的 distribution)
贝叶斯公式变换
在从噪声生成初始图像的过程中,由于直接生成不具有方向性,所以我们需要引入一下初始图象作为参考条件,这样模型生成就会更加方向性,那么我们的反向传播函数就变成了 q(xt−1∣xt,x0), 这样之后,我们的目标应该是变成 q(xt∣xt−1) 的形式,这就是正向传播的有方向性的生成,概率比较好算:
q(xt−1∣xt,x0)=q(xt,x0)q(xt−1,xt,x0)=q(xt∣x0)q(x0)q(xt∣xt−1)q(xt−1∣x0)q(x0)
这样我们就有
q(xt−1∣xt,x0)=q(xt∣x0)q(xt∣xt−1)q(xt−1∣x0)
- q(xt∣xt−1) 是前向传播的生成概率
- q(xt−1∣x0) 一步跳跃式加噪声,符合 N(xt;αt−1x0,1−αˉt−1)
- q(xt∣x0) 一步加噪符合 N(xt;αtx0,1−αˉt)
以上三者都是确定的高斯分布,所以我们可以直接计算
q(xt−1∣xt,x0)=N(xt−1;1−αˉtαt(1−αˉt−1)xt+αt−1(1−αt)x0,1−αˉt(1−αt)(1−αˉt−1))I
为了简介起见,我们定义:
均值: $$\mu_q(x_t,t) = \frac{\sqrt{\alpha_t}(1-\bar\alpha_{t-1})x_t + \sqrt{\overline\alpha_{t-1}}(1-\alpha_t)x_0}{1-\bar\alpha_t}$$
方差:
Σq(t)=1−αˉt(1−αt)(1−αˉt−1)
之后我们会发现对于 Σq(t) 是一个固定的递推项计算结果,是一个常数,我们可以很容易求解
那么回到原来的 KL 散度,我们有公式
argθminDKL(q(xt−1∣xt,x0)∣∣pθ(xt−1∣xt))=argθmin2Σq2(t)1∣∣μθ−μq∣∣22
那么我们就要计算其中 ∣∣μθ−μq∣∣ 的值 也就是均值差
回看 μ 的表达式,有两个输入变量 xt 和 x0, 但是我们并不是在每一层都能看到 x0 的值,我们还是要使用公式进行替换
xt=αˉtx0+1−αˉtϵt
那么 x0=αˉtxt−1−αˉtϵt , μq=αt1(xt−1−αˉt1−αtϵt)
这里噪声 ϵt 表示的是从 x0 到 xt 的噪声预测,是通过神经网络学习的内容
我们训练的目标是最小化 的 θ
由于两个分布的 均值是一样的,区别是在 ϵt 上,所以说,我们通过带入 xt 的展开获得了
argθmin2σq2(t)1(1−αt)αt(1−αt)2[∣∣ϵt−ϵ^θ(xt,t)∣∣22]
采样过程 sampling
在每一步的运算过程中,我们需要对 xt−1 的输入进行采样
xt−1=αt1(xt−1−αt1−αtϵθ(xt,t))+σtz