diffusion model(一)DDPM技术小结 (denoising diffusion probabilistic)

2023-11-05

系列阅读

1 从直觉上理解DDPM

在详细推到公式之前,我们先从直觉上理解一下什么是扩散

对于常规的生成模型,如GAN,VAE,它直接从噪声数据生成图像,我们不妨记噪声数据为 z z z,其生成的图片为 x x x

对于常规的生成模型

学习一个解码函数(即我们需要学习的模型) p p p,实现 p ( z ) = x p(z)=x p(z)=x
z ⟶ p x (1) z \stackrel{p} \longrightarrow x \tag{1} zpx(1)
常规方法只需要一次预测即能实现噪声到目标的映射,虽然速度快,但是效果不稳定。

常规生成模型的训练过程(以VAE为例)
x ⟶ q z ⟶ p x ^ (2) x \stackrel{q} \longrightarrow z \stackrel{p} \longrightarrow \widehat{x} \tag{2} xqzpx (2)
对于diffusion model

它将噪声到目标的过程进行了多步拆解。不妨假设一共有 T + 1 T+1 T+1个时间步,第 T T T个时间步 x T x_T xT是噪声数据,第0个时间步的输出是目标图片 x 0 x_0 x0。其过程可以表述为:
z = x T ⟶ p x T − 1 ⟶ p ⋯ ⟶ p x 1 ⟶ p x 0 (3) z = x_T \stackrel{p} \longrightarrow x_{T-1} \stackrel{p} \longrightarrow \cdots \stackrel{p} \longrightarrow x_{1} \stackrel{p} \longrightarrow x_0 \tag{3} z=xTpxT1ppx1px0(3)
对于DDPM它采用的是一种自回归式的重建方法,每次的输入是当前的时刻及当前时刻的噪声图片。也就是说它把噪声到目标图片的生成分成了T步,这样每一次的预测相当于是对残差的预测。优势是重建效果稳定,但速度较慢。

训练整体pipeline包含两个过程

2 diffusion pipeline

2.1前置知识:

高斯分布的一些性质

(1)如果 X ∼ N ( μ , σ 2 ) X \sim \mathcal{N}(\mu, \sigma^2) XN(μ,σ2),且 a a a b b b是实数,那么 a X + b ∼ N ( a μ + b , ( a σ ) 2 ) aX+b \sim \mathcal{N}(a\mu+b, (a\sigma)^2) aX+bN(aμ+b,()2)

(2)如果 X ∼ N ( μ ( x ) , σ 2 ( x ) ) X \sim \mathcal{N}(\mu(x), \sigma^2(x)) XN(μ(x),σ2(x)), Y ∼ N ( μ ( y ) , σ 2 ( y ) ) Y \sim \mathcal{N}(\mu(y), \sigma^2(y)) YN(μ(y),σ2(y)),且 X , Y X,Y X,Y是统计独立的正态随机变量,则它们的和也满足高斯分布(高斯分布可加性).
X + Y ∼ N ( μ ( x ) + μ ( y ) , σ 2 ( x ) + σ 2 ( y ) ) X − Y ∼ N ( μ ( x ) − μ ( y ) , σ 2 ( x ) + σ 2 ( y ) ) (4) X+Y \sim \mathcal{N}(\mu(x)+\mu{(y), \sigma^2(x) + \sigma^2(y)}) \\ X-Y \sim \mathcal{N}(\mu(x)-\mu{(y), \sigma^2(x) + \sigma^2(y)}) \tag{4} X+YN(μ(x)+μ(y),σ2(x)+σ2(y))XYN(μ(x)μ(y),σ2(x)+σ2(y))(4)
均值为 μ \mu μ方差为 σ \sigma σ的高斯分布的概率密度函数为
f ( x ) = 1 2 π σ exp ⁡ ( − ( x − μ ) 2 2 σ 2 ) = 1 2 π σ exp ⁡ [ − 1 2 ( 1 σ 2 x 2 − 2 μ σ 2 x + μ 2 σ 2 ) ] \begin{align} f(x) &= \frac{1}{\sqrt{2\pi} \sigma } \exp \left ({- \frac{(x - \mu)^2}{2\sigma^2}} \right) \nonumber \\ &= \frac{1}{\sqrt{2\pi} \sigma } \exp \left[ -\frac{1}{2} \left( \frac{1}{\sigma^2}x^2 - \frac{2\mu}{\sigma^2}x + \frac{\mu^2}{\sigma^2} \right ) \right] \tag{5} \end{align} f(x)=2π σ1exp(2σ2(xμ)2)=2π σ1exp[21(σ21x2σ22μx+σ2μ2)](5)

2.2 加噪过程

1 前向过程:将图片数据映射为噪声

每一个时刻都要添加高斯噪声,后一个时刻都是由前一个时刻加噪声得到。(其实每一个时刻加的噪声就是训练所用的标签)。即
x 0 ⟶ q x 1 ⟶ q x 2 ⟶ q ⋯ ⟶ q x T − 1 ⟶ q x T = z (6) x_0 \stackrel{q} \longrightarrow x_1 \stackrel{q} \longrightarrow x_{2} \stackrel{q} \longrightarrow \cdots \stackrel{q} \longrightarrow x_{T-1} \stackrel{q} \longrightarrow x_T=z \tag{6} x0qx1qx2qqxT1qxT=z(6)
下面我们详细来看

β t = 1 − α t \beta_t = 1 - \alpha_t βt=1αt β t \beta_t βt随t的增加而增大(论文中1时从0.0001 -> 0.02) (这是因为一开始加一点噪声就很明显,后面需要增大噪声的量才明显).DDPM将加噪声过程建模为一个马尔可夫过程 q ( x 1 : T ∣ x 0 ) : = ∏ t = 1 T q ( x t ∣ x t − 1 ) q(x_{1:T}|x_0):= \prod \limits_{t=1}^Tq(x_t|x_{t-1}) q(x1:Tx0):=t=1Tq(xtxt1) ,其中 q ( x t ∣ x t − 1 ) : = N ( x t ; α t x t − 1 , ( 1 − α t ) I ) q(x_t|x_{t-1}):=\mathcal{N}(x_t; \sqrt{\alpha_t}x_{t-1}, (1 - \alpha_t) \textbf{I}) q(xtxt1):=N(xt;αt xt1,(1αt)I)
x t = α t x t − 1 + ( 1 − α t ) z t = α t x t − 1 + β t z t \begin{align} x_t &= \sqrt{\alpha_t}x_{t-1} + \sqrt{(1 - \alpha_t)}z_t \nonumber \\ &= \sqrt{\alpha_t}x_{t-1} + \sqrt{\beta_t}z_t \tag{7} \end{align} xt=αt xt1+(1αt) zt=αt xt1+βt zt(7)
x t x_t xt为在 t t t时刻的图片,当 t = 0 t=0 t=0时为原图; z t z_t zt为在 t t t时刻所加的噪声,服从标准正态分布 z t ∼ N ( 0 , I ) z_t \sim \mathcal{N}(0, \textbf{I}) ztN(0,I); α t \alpha_t αt是常数,是自己定义的变量;从上式可见,随着 T T T增大, x t x_t xt越来越接近纯高斯分布.

同理:
x t − 1 = α t − 1 x t − 2 + 1 − α t − 1 z t − 1 (8) x_{t-1} = \sqrt{\alpha_{t-1}}x_{t-2} + \sqrt{1 - \alpha_{t-1}}z_{t-1} \tag{8} xt1=αt1 xt2+1αt1 zt1(8)
将式(8)代入式(7)可得:
x t = α t ( α t − 1 x t − 2 + 1 − α t − 1 z t − 1 ) + 1 − α t z t = α t α t − 1 x t − 2 + ( α t ( 1 − α t − 1 ) z t − 1 + 1 − α t z t ) \begin{align} x_t &=& \sqrt{\alpha_t} (\sqrt{\alpha_{t-1}}x_{t-2} + \sqrt{1 - \alpha_{t-1}}z_{t-1}) + \sqrt{1 - \alpha_t}z_t \nonumber\\ &=& \sqrt{\alpha_t \alpha_{t-1}}x_{t-2} + (\sqrt{\alpha_t (1 - \alpha_{t-1})} z_{t-1} + \sqrt{1 - \alpha_t}z_t) \tag{9} \end{align} xt==αt (αt1 xt2+1αt1 zt1)+1αt ztαtαt1 xt2+(αt(1αt1) zt1+1αt zt)(9)
由于 z t − 1 z_{t-1} zt1服从均值为0,方差为1的高斯分布(即标准正态分布),根据定义 α t ( 1 − α t − 1 ) z t − 1 \sqrt{\alpha_t (1 - \alpha_{t-1})} z_{t-1} αt(1αt1) zt1服从的是均值为0,方差为 α t ( 1 − α t − 1 ) \alpha_t (1 - \alpha_{t-1}) αt(1αt1)的高斯分布.即 α t ( 1 − α t − 1 ) z t − 1 ∼ N ( 0 , α t ( 1 − α t − 1 ) I ) \sqrt{\alpha_t (1 - \alpha_{t-1})} z_{t-1} \sim \mathcal{N}(0, \alpha_t (1 - \alpha_{t-1})\textbf{I}) αt(1αt1) zt1N(0,αt(1αt1)I).同理可得 1 − α t z t ∼ N ( 0 , ( 1 − α t ) I ) \sqrt{1 - \alpha_t}z_t \sim \mathcal{N}(0, (1 - \alpha_t)\textbf{I}) 1αt ztN(0,(1αt)I).则**(高斯分布可加性,可以通过定义推得,不赘述)**
( α t ( 1 − α t − 1 ) , z t − 1 + 1 − α t z t ) ∼ N ( 0 , α t ( 1 − α t − 1 ) + 1 − α t ) = N ( 0 , 1 − α t α t − 1 ) \begin{align} (\sqrt{\alpha_t (1 - \alpha_{t-1})} , z_{t-1} + \sqrt{1 - \alpha_t}z_t) \sim \mathcal{N}(0, \alpha_t (1 - \alpha_{t-1}) + 1 - \alpha_t) =& \mathcal{N}(0, 1 - \alpha_t \alpha_{t-1}) \tag{10} \end{align} (αt(1αt1) ,zt1+1αt zt)N(0,αt(1αt1)+1αt)=N(0,1αtαt1)(10)
我们不妨记 z ‾ t − 2 ∼ N ( 0 , I ) \overline{z}_{t-2} \sim \mathcal{N}(0, \textbf{I}) zt2N(0,I),则 1 − α t α t − 1 z ‾ t − 2 ∼ N ( 0 , ( 1 − α t α t − 1 ) I ) \sqrt{1 - \alpha_t \alpha_{t-1}} \overline{z}_{t-2} \sim \mathcal{N}(0, (1 - \alpha_t \alpha_{t-1})\textbf{I}) 1αtαt1 zt2N(0,(1αtαt1)I)则式(10)最终可改写为
x t = α t α t − 1 x t − 2 + 1 − α t α t − 1 z ‾ t − 2 (11) x_t = \sqrt{\alpha_t \alpha_{t-1}} x_{t-2} + \sqrt{1 - \alpha_t \alpha_{t-1}} \overline{z}_{t-2} \tag{11} xt=αtαt1 xt2+1αtαt1 zt2(11)
通过递推,容易得到
x t = α t α t − 1 ⋯ α 1 x 0 + 1 − α t α t − 1 … α 1 z ‾ 0 = ∏ i = 1 t α i x 0 + 1 − ∏ i = 1 t α i z ‾ 0 = 令 α ‾ t = ∏ i = 1 t α i α ‾ t x 0 + 1 − α ‾ t z ‾ 0 \begin{align} x_t =& \sqrt{\alpha_t \alpha_{t-1} \cdots \alpha_1} x_0 + \sqrt{1 - \alpha_t \alpha_{t-1} \dots \alpha_1} \overline{z}_0 \nonumber\\ =& \sqrt{\prod_{i=1}^{t} {\alpha_i}}x_0 + \sqrt{1 - \prod_{i=1}^{t} {\alpha_i}} \overline {z}_0 \nonumber \\ \stackrel{\mathrm{令} \overline{\alpha}_{t} = \prod_{i=1}^{t} {\alpha_i}} = & \sqrt{\overline{\alpha}_{t}}x_0+\sqrt{1 - \overline{\alpha}_{t}}\overline{z}_{0} \tag{12} \end{align} xt===αt=i=1tαiαtαt1α1 x0+1αtαt1α1 z0i=1tαi x0+1i=1tαi z0αt x0+1αt z0(12)
其中 z ‾ 0 ∼ N ( 0 , I ) \overline{z}_{0} \sim \mathcal{N}(0, \mathrm{I}) z0N(0,I), x 0 x_0 x0为原图.从式(13)可见,我们可以从 x 0 x_0 x0得到任意时刻的 x t x_t xt的分布(14),而无需按照时间顺序递推!这极大提升了计算效率.
q ( x t ∣ x 0 ) = N ( x t ; μ ( x t , t ) , σ 2 ( x t , t ) I ) = N ( x t ; α ‾ t x 0 , ( 1 − α ‾ t ) I ) \begin{align} q(x_t|x_0) &= \mathcal{N}(x_t; \mu{(x_t, t)},\sigma^2{(x_t, t)}{}\textbf{I}) \nonumber\\ &= \mathcal{N}(x_t; \sqrt{\overline{\alpha}_{t}}x_0,(1 - \overline{\alpha}_{t})\textbf{I}) \tag{13} \end{align} q(xtx0)=N(xt;μ(xt,t),σ2(xt,t)I)=N(xt;αt x0,(1αt)I)(13)
⚠️
加噪过程是确定的,没有模型的介入.
其目的是制作训练时标签

2.3 去噪过程

给定 x T x_T xT如何求出 x 0 x_0 x0呢?直接求解是很难的,作者给出的方案是:我们可以一步一步求解.即学习一个解码函数 p p p,这个 p p p能够知道 x t x_{t} xt x t − 1 x_{t-1} xt1的映射规则.如何定义这个 p p p是问题的关键.有了 p p p,只需从 x t x_{t} xt x t − 1 x_{t-1} xt1逐步迭代,即可得出 x 0 x_0 x0.
z = x T ⟶ p x T − 1 ⟶ p ⋯ ⟶ p x 1 ⟶ p x 0 (14) z = x_T \stackrel{p} \longrightarrow x_{T-1} \stackrel{p} \longrightarrow \cdots \stackrel{p} \longrightarrow x_{1} \stackrel{p} \longrightarrow x_0 \tag{14} z=xTpxT1ppx1px0(14)
去噪过程是加噪过程的逆向.如果说加噪过程是求给定初始分布 x 0 x_0 x0求任意时刻的分布 x t x_t xt,即 q ( x t ∣ x 0 ) q(x_t|x_0) q(xtx0)那么去噪过程所求的分布就是给定任意时刻的分布 x t x_t xt求其初始时刻的分布 x 0 x_0 x0,即 p ( x 0 ∣ x t ) p(x_0|x_t) p(x0xt) ,通过马尔可夫假设,可以对上述问题进行化简
p ( x 0 ∣ x t ) = p ( x 0 ∣ x 1 ) p ( x 1 ∣ x 2 ) ⋯ p ( x t − 1 ∣ x t ) = ∏ i = 0 t − 1 p ( x i ∣ x i + 1 ) \begin{align} p(x_0|x_t) &= p(x_0|x1)p(x1|x2)\cdots p(x_{t-1}| x_t) \nonumber \\ &= \prod_{i=0}^{t-1}{p(x_i|x_{i+1})} \tag{15} \end{align} p(x0xt)=p(x0x1)p(x1∣x2)p(xt1xt)=i=0t1p(xixi+1)(15)
如何求 p ( x t − 1 ∣ x t ) {p(x_{t-1}|x_{t})} p(xt1xt)呢?前面的加噪过程我们大力气推到出了 q ( x t ∣ x t − 1 ) {q(x_{t}|x_{t-1})} q(xtxt1),我们可以通过贝叶斯公式把它利用起来
p ( x t − 1 ∣ x t ) = p ( x t ∣ x t − 1 ) p ( x t − 1 ) p ( x t ) (16) p(x_{t-1}|x_t) = \frac{p(x_{t}|x_{t-1})p(x_{t-1})}{p(x_t)} \tag{16} p(xt1xt)=p(xt)p(xtxt1)p(xt1)(16)
⚠️这里的(去噪) p p p和上面的(加噪) q q q只是对分布的一种符号记法,它们是等价的.

有了式(17)还是一头雾水, p ( x t ) p(x_t) p(xt) p ( x t − 1 ) p(x_{t-1}) p(xt1)都不知道啊!该怎么办呢?这就要借助模型的威力了.下面来看如何构建我们的模型.

延续加噪过程的推导 p ( x t ∣ x 0 ) p(x_t|x_0) p(xtx0) p ( x t − 1 ∣ x 0 ) p(x_{t-1}|x_0) p(xt1x0)我们是可以知道的.因此若我们知道初始分布 x 0 x_0 x0,则
p ( x t − 1 ∣ x t , x 0 ) = p ( x t ∣ x t − 1 , x 0 ) p ( x t − 1 ∣ x 0 ) p ( x t ∣ x 0 ) = N ( x t ; α t x t − 1 , ( 1 − α t ) I ) N ( x t − 1 ; α ‾ t − 1 x 0 , ( 1 − α ‾ t − 1 ) I ) N ( x t ; α ‾ t x 0 , ( 1 − α ‾ t ) I ) ∝ 将式 ( 6 ) 代入 exp ⁡ ( − ( x t − α t x t − 1 ) 2 2 ( 1 − α t ) ) exp ⁡ ( − ( x t − 1 − α ‾ t − 1 x 0 ) 2 2 ( 1 − α ‾ t − 1 ) ) exp ⁡ ( − ( x t − α ‾ t x 0 ) 2 2 ( 1 − α ‾ t ) ) = exp ⁡ [ − 1 2 ( ( x t − α t x t − 1 ) 2 1 − α t + ( x t − 1 − α ‾ t − 1 x 0 ) 2 1 − α ‾ t − 1 − ( x t − α ‾ t x 0 ) 2 1 − α ‾ t ) ] = exp ⁡ [ − 1 2 ( ( α t 1 − α t + 1 1 − α ‾ t − 1 ) x t − 1 2 − ( 2 α t ‾ 1 − α t x t + 2 α ‾ t − 1 1 − α ‾ t − 1 x 0 ) x t − 1 + C ( x t , x 0 ) ) ] \small \begin{align} p(x_{t-1}|x_t,x_0) &= \frac{p(x_{t}|x_{t-1}, x_0)p(x_{t-1}|x_0)}{p(x_t|x_0)} \tag{17} \\ &= \frac{\mathcal{N}(x_t; \sqrt{\alpha_t}x_{t-1}, (1 - \alpha_t) \textbf{I} ) \mathcal{N}(x_{t-1}; \sqrt{\overline{\alpha}_{t-1}}x_0,(1 - \overline{\alpha}_{t-1}) \textbf{I})} { \mathcal{N}(x_t; \sqrt{\overline{\alpha}_{t}}x_0,(1 - \overline{\alpha}_{t}) \textbf{I} )} \tag{18} \\ &\stackrel{将式(6)代入} \propto \frac{ \exp \left ({- \frac{(x_t - \sqrt{\alpha_t}x_{t-1} )^2}{2 (1 - \alpha_t)}} \right) \exp \left ({- \frac{(x_{t-1} - \sqrt{\overline{\alpha}_{t-1}}x_0 )^2}{2 (1 - \overline{\alpha}_{t-1})}} \right) } { \exp \left ({- \frac{(x_{t} - \sqrt{\overline{\alpha}_{t}}x_0 )^2}{2 (1 - \overline{\alpha}_{t})}} \right) } \tag{19} \\ &= \exp \left [-\frac{1}{2} \left ( \frac{(x_t - \sqrt{\alpha_t}x_{t-1} )^2}{1 - \alpha_t} + \frac{(x_{t-1} - \sqrt{\overline{\alpha}_{t-1}}x_0 )^2}{1 - \overline{\alpha}_{t-1}} - \frac{(x_{t} - \sqrt{\overline{\alpha}_{t}}x_0 )^2}{1 - \overline{\alpha}_{t}} \right) \right] \tag{20} \\ &= \exp \left [ -\frac{1}{2} \left( \left( \frac{\alpha_t}{1-\alpha_t} + \frac{1}{1 - \overline{\alpha}_{t-1}} \right)x^2_{t-1} - \left ( \frac{2\sqrt{\overline{\alpha_{t}}}}{1 - \alpha_t}x_t + \frac{2 \sqrt{\overline{\alpha}_{t-1}}} {1 - \overline{\alpha}_{t-1} }x_0 \right)x_{t-1} + C(x_t, x_0) \right) \right] \tag{21} \end{align} p(xt1xt,x0)=p(xtx0)p(xtxt1,x0)p(xt1x0)=N(xt;αt x0,(1αt)I)N(xt;αt xt1,(1αt)I)N(xt1;αt1 x0,(1αt1)I)将式(6)代入exp(2(1αt)(xtαt x0)2)exp(2(1αt)(xtαt xt1)2)exp(2(1αt1)(xt1αt1 x0)2)=exp[21(1αt(xtαt xt1)2+1αt1(xt1αt1 x0)21αt(xtαt x0)2)]=exp[21((1αtαt+1αt11)xt12(1αt2αt xt+1αt12αt1 x0)xt1+C(xt,x0))](17)(18)(19)(20)(21)

结合高斯分布的定义(6)来看式(22),不难发现 p ( x t − 1 ∣ x t , x 0 ) p(x_{t-1}|x_t,x_0) p(xt1xt,x0)也是服从高斯分布的.并且结合式(6)我们可以求出其方差和均值

⚠️式17做了一个近似 p ( x t ∣ x t − 1 , x 0 ) = p ( x t ∣ x t − 1 ) p(x_t|x_{t-1}, x_0) =p(x_t| x_{t-1}) p(xtxt1,x0)=p(xtxt1),能做这个近似原因是一阶马尔科夫假设,当前时间点只依赖前一个时刻的时间点.
1 σ 2 = α t 1 − α t + 1 1 − α ‾ t − 1 2 μ σ 2 = 2 α t ‾ 1 − α t x t + 2 α ‾ t − 1 1 − α ‾ t − 1 x 0 \begin{align} \frac{1}{\sigma_2} &= \frac{\alpha_t}{1-\alpha_t} + \frac{1}{1 - \overline{\alpha}_{t-1}} \tag{22} \\ \frac{2\mu}{\sigma^2} &= \frac{2\sqrt{\overline{\alpha_{t}}}}{1 - \alpha_t}x_t + \frac{2 \sqrt{\overline{\alpha}_{t-1}}} {1 - \overline{\alpha}_{t-1} }x_0 \tag{23} \end{align} σ21σ22μ=1αtαt+1αt11=1αt2αt xt+1αt12αt1 x0(22)(23)
可以求得:
σ 2 = 1 − α ‾ t − 1 1 − α ‾ t ( 1 − α t ) μ = α t ( 1 − α ‾ t − 1 ) 1 − α ‾ t x t + α ‾ t − 1 ( 1 − α t ) 1 − α ‾ t x 0 \begin{align} \sigma^2 &= \frac{1 - \overline{\alpha}_{t-1}}{1 - \overline{\alpha}_{t}} (1 - \alpha_t) \nonumber \\ \mu &= \frac{\sqrt{\alpha_t} (1 - \overline{\alpha}_{t-1})} {1 - \overline{\alpha}_t}x_t + \frac{\sqrt{\overline{\alpha}_{t-1}} (1 - \alpha_t) }{1 - \overline{\alpha}_t}x_0 \tag{24} \end{align} σ2μ=1αt1αt1(1αt)=1αtαt (1αt1)xt+1αtαt1 (1αt)x0(24)
通过上式,我们可得
p ( x t − 1 ∣ x t , x 0 ) = N ( x t − 1 ; α t ( 1 − α ‾ t − 1 ) 1 − α ‾ t x t + α ‾ t − 1 ( 1 − α t ) 1 − α ‾ t x 0 , ( 1 − α ‾ t − 1 1 − α ‾ t ( 1 − α t ) ) I ) (25) p(x_{t-1}|x_t,x_0) = \mathcal{N}(x_{t-1}; \frac{\sqrt{\alpha_t} (1 - \overline{\alpha}_{t-1})} {1 - \overline{\alpha}_t}x_t + \frac{\sqrt{\overline{\alpha}_{t-1}} (1 - \alpha_t) }{1 - \overline{\alpha}_t}x_0 , (\frac{1 - \overline{\alpha}_{t-1}}{1 - \overline{\alpha}_{t}} (1 - \alpha_t)) \textbf{I}) \tag{25} p(xt1xt,x0)=N(xt1;1αtαt (1αt1)xt+1αtαt1 (1αt)x0,(1αt1αt1(1αt))I)(25)
该式是真实的条件分布.我们目标是让模型学到的条件分布 p θ ( x t − 1 ∣ x t ) p_\theta(x_{t-1}|x_t) pθ(xt1xt)尽可能的接近真实的条件分布 p ( x t − 1 ∣ x t , x 0 ) p(x_{t-1}|x_t, x_0) p(xt1xt,x0).从上式可以看到方差是个固定量,那么我们要做的就是让 p ( x t − 1 ∣ x t , x 0 ) p(x_{t-1}|x_t, x_0) p(xt1xt,x0) p θ ( x t − 1 ∣ x t ) p_\theta(x_{t-1}|x_t) pθ(xt1xt)的均值尽可能的对齐,即

(这个结论也可以通过最小化上述两个分布的KL散度推得)
a r g m i n θ ∥ u ( x 0 , x t ) , u θ ( x t , t ) ∥ (26) \mathrm{arg} \mathop{min}_\theta \parallel u(x_0, x_t), u_\theta(x_t, t) \parallel \tag{26} argminθu(x0,xt),uθ(xt,t)(26)
下面的问题变为:如何构造 u θ ( x t , t ) u_\theta(x_t, t) uθ(xt,t)来使我们的优化尽可能的简单

我们注意到 μ ( x 0 , x t ) \mu(x_0, x_t) μ(x0,xt) μ θ ( x t , t ) \mu_\theta(x_t, t) μθ(xt,t)都是关于 x t x_t xt的函数,不妨让他们的 x t x_t xt保持一致,则可将 μ θ ( x t , t ) \mu_\theta(x_t, t) μθ(xt,t)写成
μ θ ( x t , t ) = α t ( 1 − α ‾ t − 1 ) 1 − α ‾ t x t + α ‾ t − 1 ( 1 − α t ) 1 − α ‾ t f θ ( x t , t ) (27) \mu_\theta(x_t, t) = \frac{\sqrt{\alpha_t} (1 - \overline{\alpha}_{t-1})} {1 - \overline{\alpha}_t}x_t + \frac{\sqrt{\overline{\alpha}_{t-1}} (1 - \alpha_t) }{1 - \overline{\alpha}_t} f_\theta(x_t, t) \tag{27} μθ(xt,t)=1αtαt (1αt1)xt+1αtαt1 (1αt)fθ(xt,t)(27)
f θ ( x t , t ) f_\theta(x_t, t) fθ(xt,t)是我们需要训练的模型.这样对齐均值的问题就转化成了: **给定 x t , t x_t, t xt,t来预测原始图片输入 x 0 x_0 x0.**根据上文的加噪过程,我们可以很容易制造训练所需的数据对! (Dalle2的训练采用的是这个方式,可能这就是大力出奇迹吧).事情到这里就结束了吗?

DDPM作者表示直接从 x t x_t xt x 0 x_0 x0的预测数据跨度太大了,且效果一般.我们可以将式(12)做一下变形
x t = α ‾ t x 0 + 1 − α ‾ t z ‾ 0 x 0 = 1 α ‾ t ( x t − 1 − α ‾ t z ‾ 0 ) \begin{align} x_t &= \sqrt{\overline{\alpha}_{t}}x_0+\sqrt{1 - \overline{\alpha}_{t}}\overline{z}_{0} \nonumber \\ x_0 &= \frac{1}{\sqrt{\overline{\alpha}_{t}}}(x_t - \sqrt{1 - \overline{\alpha}_{t}}\overline{z}_{0}) \tag{28} \end{align} xtx0=αt x0+1αt z0=αt 1(xt1αt z0)(28)
代入到式(24)中
μ = α t ( 1 − α ‾ t − 1 ) 1 − α ‾ t x t + α ‾ t − 1 ( 1 − α t ) 1 − α ‾ t 1 a ‾ t ( x t − 1 − a ‾ t z ‾ 0 ) = α t ( 1 − α ‾ t − 1 ) 1 − α ‾ t x t + ( 1 − α t ) 1 − α ‾ t 1 α t ( x t − 1 − α ‾ t z ‾ 0 ) = 合并 x t α t ( 1 − α ‾ t − 1 ) + ( 1 − α t ) α t ( 1 − α ‾ t ) x t − 1 − α ‾ t ( 1 − α t ) α t ( 1 − α ‾ t ) z ‾ 0 = 1 − α ‾ t α t ( 1 − α ‾ t ) x t − 1 − α t α t 1 − α ‾ t z ‾ 0 = 1 α t x t − 1 − α t α t 1 − α ‾ t z ‾ 0 \begin{align} \mu &= \frac{\sqrt{\alpha_t} (1 - \overline{\alpha}_{t-1})} {1 - \overline{\alpha}_t}x_t + \frac{\sqrt{\overline{\alpha}_{t-1}} (1 - \alpha_t) }{1 - \overline{\alpha}_t} \frac{1}{\sqrt{\overline{a}_{t}}}(x_t - \sqrt{1 - \overline{a}_{t}}\overline{z}_{0}) \nonumber \\ &= \frac{\sqrt{\alpha_t} (1 - \overline{\alpha}_{t-1})} {1 - \overline{\alpha}_t}x_t + \frac{(1 - \alpha_t) }{1 - \overline{\alpha}_t} \frac{1}{\sqrt{\alpha}_{t}}(x_t - \sqrt{1 - \overline{\alpha}_{t}}\overline{z}_{0}) \nonumber \\ &\stackrel{合并x_t} = \frac{\alpha_t(1 - \overline{\alpha}_{t-1}) + (1 - \alpha_t) }{\sqrt{\alpha}_t (1 - \overline{\alpha}_t)}x_t - \frac{\sqrt{1 - \overline{\alpha}_t}(1 - \alpha_t) }{\sqrt{\alpha_t}(1 - \overline{\alpha}_t)}\overline{z}_0 \nonumber \\ &= \frac{1 - \overline{\alpha}_t}{\sqrt{\alpha}_t (1 - \overline{\alpha}_t)}x_t - \frac{1 - \alpha_t }{\sqrt{\alpha_t}\sqrt{1 - \overline{\alpha}_t}}\overline{z}_0 \nonumber \\ &= \frac{1}{\sqrt{\alpha}_t}x_t - \frac{1 - \alpha_t }{\sqrt{\alpha_t}\sqrt{1 - \overline{\alpha}_t}}\overline{z}_0 \tag{29} \end {align} μ=1αtαt (1αt1)xt+1αtαt1 (1αt)at 1(xt1at z0)=1αtαt (1αt1)xt+1αt(1αt)α t1(xt1αt z0)=合并xtα t(1αt)αt(1αt1)+(1αt)xtαt (1αt)1αt (1αt)z0=α t(1αt)1αtxtαt 1αt 1αtz0=α t1xtαt 1αt 1αtz0(29)
经过这次化简,我们将 μ ( x 0 , x t ) ⇒ μ ( x t , z ‾ 0 ) \mu{(x_0, x_t)} \Rightarrow \mu{(x_t, \overline{z}_0)} μ(x0,xt)μ(xt,z0),其中 z ‾ 0 ∼ N ( 0 , I ) \overline{z}_0 \sim \mathcal{N}(0, \textbf{I}) z0N(0,I),可以将式(29)转变为
μ θ ( x t , t ) = 1 α t x t − 1 − α t α t 1 − α ‾ t f θ ( x t , t ) (30) \mu_\theta(x_t, t) = \frac{1}{\sqrt{\alpha_t}} x_t - \frac{1 - \alpha_t }{\sqrt{\alpha_t}\sqrt{1 - \overline{\alpha}_t}}f_\theta(x_t, t) \tag{30} μθ(xt,t)=αt 1xtαt 1αt 1αtfθ(xt,t)(30)
此时对齐均值的问题就转化成:给定 x t , t x_t, t xt,t预测 x t x_t xt加入的噪声 z ‾ 0 \overline{z}_0 z0, 也就是说我们的模型预测的是噪声 f θ ( x t , t ) = ϵ θ ( x t , t ) ≃ z ‾ 0 f_\theta{(x_t, t)} = \epsilon_{\theta}(x_t, t) \simeq \overline{z}_0 fθ(xt,t)=ϵθ(xt,t)z0

2.3.1 训练与采样过程

训练的目标就是这所有时刻两个噪声的差异的期望越小越好(用MSE或L1-loss).
E t ∼ T ∥ ϵ − ϵ θ ( x t , t ) ∥ 2 2 (31) \mathbb{E}_{t \sim T } \parallel \epsilon - \epsilon_{\theta}(x_t, t)\parallel_2 ^2 \tag{31} EtTϵϵθ(xt,t)22(31)
下图为论文提供的训练和采样过
在这里插入图片描述

2.3.2 采样过程

通过以上讨论,我们推导出 p θ ( x t − 1 ∣ x t ) p_\theta(x_{t-1}|x_t) pθ(xt1xt)高斯分布的均值和方差. p θ ( x t − 1 ∣ x t ) = N ( x t − 1 ; μ θ ( x t , t ) , σ 2 ( t ) I ) p_\theta(x_{t-1}|x_t)=\mathcal{N}(x_{t-1}; \mu_{\theta}(x_t, t), \sigma^2(t) \textbf{I}) pθ(xt1xt)=N(xt1;μθ(xt,t),σ2(t)I),根据文献2从一个高斯分布中采样一个随机变量可用一个重参数化技巧进行近似
x t − 1 = μ θ ( x t , t ) + σ ( t ) ϵ , 其中 ϵ ∈ N ( ϵ ; 0 , I ) = 1 α t ( x t − 1 − α t 1 − α ‾ t ϵ θ ( x t , t ) ) + σ ( t ) ϵ \begin{align} x_{t-1} &= \mu_{\theta}(x_t, t) + \sigma(t) \epsilon,其中 \epsilon \in \mathcal{N}(\epsilon; 0, \textbf{I}) \tag{32} \\ & = \frac{1}{\sqrt{\alpha_t}} (x_t - \frac{1 - \alpha_t }{\sqrt{1 - \overline{\alpha}_t}}\epsilon_\theta(x_t, t)) + \sigma(t) \epsilon \tag{33} \end{align} xt1=μθ(xt,t)+σ(t)ϵ,其中ϵN(ϵ;0,I)=αt 1(xt1αt 1αtϵθ(xt,t))+σ(t)ϵ(32)(33)
式(39)和论文给出的采样递推公式一致.

至此,已完成DDPM整体的pipeline.

还没想明白的点,为什么不能根据(7)的变形来进行采样计算呢?
x t − 1 = 1 α t x t − 1 − α t α t f θ ( x t , t ) (34) x_{t-1} = \frac{1}{\sqrt{\alpha_t}}x_t - \sqrt{\frac{1 - \alpha_t}{\alpha_t}} f_\theta(x_t, t) \tag{34} xt1=αt 1xtαt1αt fθ(xt,t)(34)

3 从代码理解训练&预测过程

3.1 训练过程

参考代码仓库: https://github.com/lucidrains/denoising-diffusion-pytorch/tree/main/denoising_diffusion_pytorch

已知项: 我们假定有一批 N N N张图片 { x i ∣ i = 1 , 2 , ⋯   , N } \{x_i |i=1, 2, \cdots, N\} {xii=1,2,,N}

第一步: 随机采样 K K K组成batch,如 x _ s t a r t = { x k ∣ k = 1 , 2 , ⋯   , K } \mathrm{x\_start}= \{ x_k|k=1,2, \cdots, K \} x_start={xkk=1,2,,K}, S h a p e ( x _ s t a r t ) = ( K , C , H , W ) \mathrm{Shape}(\mathrm{x\_start}) = (K, C, H, W) Shape(x_start)=(K,C,H,W)

第二步: 随机采样一些时间步

t = torch.randint(0, self.num_timesteps, (b,), device=device).long()  # 随机采样时间步

第三步: 随机采样噪声

noise = default(noise, lambda: torch.randn_like(x_start))  # 基于高斯分布采样噪声

第四步: 计算 x _ s t a r t \mathrm{x\_start} x_start在所采样的时间步的输出 x T x_T xT(即加噪声).(根据公式12)

def linear_beta_schedule(timesteps):
    scale = 1000 / timesteps
    beta_start = scale * 0.0001
    beta_end = scale * 0.02
    return torch.linspace(beta_start, beta_end, timesteps, dtype = torch.float64)

  
betas = linear_beta_schedule(timesteps)
alphas = 1. - betas
alphas_cumprod = torch.cumprod(alphas, dim=0)
sqrt_one_minus_alphas_cumprod = torch.sqrt(1. - alphas_cumprod)
sqrt_alphas_cumprod = torch.sqrt(alphas_cumprod)


def extract(a, t, x_shape):
    b, *_ = t.shape
    out = a.gather(-1, t)
    return out.reshape(b, *((1,) * (len(x_shape) - 1)))

  
def q_sample(x_start, t, noise=None):
  """
  \begin{eqnarray}
    x_t &=& \sqrt{\alpha_t}x_{t-1} + \sqrt{(1 - \alpha_t)}z_t \nonumber \\
    &=&  \sqrt{\alpha_t}x_{t-1} + \sqrt{\beta_t}z_t
  \end{eqnarray}
  """
    return (
        extract(sqrt_alphas_cumprod, t, x_start.shape) * x_start +
        extract(sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise
    )
    
x = q_sample(x_start = x_start, t = t, noise = noise)  # 这就是x0在时间步T的输出

第五步: 预测噪声.输入 x T , t x_T,t xT,t到噪声预测模型,来预测此时的噪声 z ^ t = ϵ θ ( x T , t ) \hat{z}_t = \epsilon_\theta(x_T, t) z^t=ϵθ(xT,t).论文用到的模型结构是Unet,与传统Unet的输入有所不同的是增加了一个时间步的输入.

model_out = self.model(x, t, x_self_cond=None)  # 预测噪声

这里面有一个需要注意的点:模型是如何对时间步进行编码并使用的

  • 首先会对时间步进行一个编码,将其变为一个向量,以正弦编码为例
class SinusoidalPosEmb(nn.Module):
    def __init__(self, dim):
        super().__init__()
        self.dim = dim

    def forward(self, x):
      	"""
      	Args:
      		x (Tensor), shape like (B,)
      	"""
        device = x.device
        half_dim = self.dim // 2
        emb = math.log(10000) / (half_dim - 1)
        emb = torch.exp(torch.arange(half_dim, device=device) * -emb)
        emb = x[:, None] * emb[None, :]
        emb = torch.cat((emb.sin(), emb.cos()), dim=-1)
        return emb
      
# 时间步的编码pipeline如下,本质就是将一个常数映射为一个向量
self.time_mlp = nn.Sequential(
    SinusoidalPosEmb(dim),
    nn.Linear(fourier_dim, time_dim),
    nn.GELU(),
    nn.Linear(time_dim, time_dim)
)
  • 将时间步的embedding嵌入到Unet的block中,使模型能够学习到时间步的信息
class Block(nn.Module):
    def __init__(self, dim, dim_out, groups = 8):
        super().__init__()
        self.proj = WeightStandardizedConv2d(dim, dim_out, 3, padding = 1)
        self.norm = nn.GroupNorm(groups, dim_out)
        self.act = nn.SiLU()

    def forward(self, x, scale_shift = None):
        x = self.proj(x)
        x = self.norm(x)

        if exists(scale_shift):
            scale, shift = scale_shift
            x = x * (scale + 1) + shift  # 将时间向量一分为2,一份用于提升幅值,一份用于修改相位

        x = self.act(x)
        return x
      

class ResnetBlock(nn.Module):
    def __init__(self, dim, dim_out, *, time_emb_dim = None, groups = 8):
        super().__init__()
        self.mlp = nn.Sequential(
            nn.SiLU(),
            nn.Linear(time_emb_dim, dim_out * 2)
        ) if exists(time_emb_dim) else None

        self.block1 = Block(dim, dim_out, groups = groups)
        self.block2 = Block(dim_out, dim_out, groups = groups)
        self.res_conv = nn.Conv2d(dim, dim_out, 1) if dim != dim_out else nn.Identity()

    def forward(self, x, time_emb = None):

        scale_shift = None
        if exists(self.mlp) and exists(time_emb):
            time_emb = self.mlp(time_emb)
            time_emb = rearrange(time_emb, 'b c -> b c 1 1')
            scale_shift = time_emb.chunk(2, dim = 1)

        h = self.block1(x, scale_shift = scale_shift)

        h = self.block2(h)

        return h + self.res_conv(x)

第六步:计算损失,反向传播.计算预测的噪声与实际的噪声的损失,损失函数可以是L1或mse

    @property
    def loss_fn(self):
        if self.loss_type == 'l1':
            return F.l1_loss
        elif self.loss_type == 'l2':
            return F.mse_loss
        else:
            raise ValueError(f'invalid loss type {self.loss_type}')

通过不断迭代上述6步即可完成模型的训练

3.2采样过程

第一步:随机从高斯分布采样一张噪声图片,并给定采样时间步

img = torch.randn(shape, device=device)

第二步: 根据预测的当前时间步的噪声,通过公式计算当前时间步的均值和方差

  
  posterior_mean_coef1 = betas * torch.sqrt(alphas_cumprod_prev) / (1. - alphas_cumprod) # 式(24)x_0的系数
  posterior_mean_coef = (1. - alphas_cumprod_prev) * torch.sqrt(alphas) / (1. - alphas_cumprod)  # 式(24) x_t的系数
  
  def extract(a, t, x_shape):
    b, *_ = t.shape
    out = a.gather(-1, t)
    return out.reshape(b, *((1,) * (len(x_shape) - 1)))
  
  def q_posterior(self, x_start, x_t, t):
    posterior_mean = (
        extract(self.posterior_mean_coef1, t, x_t.shape) * x_start +
        extract(self.posterior_mean_coef2, t, x_t.shape) * x_t
    )  # 求出此时的均值
    posterior_variance = extract(self.posterior_variance, t, x_t.shape)  # 求出此时的方差
    posterior_log_variance_clipped = extract(self.posterior_log_variance_clipped, t, x_t.shape) # 对方差取对数,可能为了数值稳定性
    return posterior_mean, posterior_variance, posterior_log_variance_clipped  
  
  def p_mean_variance(self, x, t, x_self_cond = None, clip_denoised = True):
      preds = self.model_predictions(x, t, x_self_cond)  # 预测噪声
      x_start = preds.pred_x_start  # 模型预测的是在x_t时间步噪声,x_start是根据公式(12)求

      if clip_denoised:
          x_start.clamp_(-1., 1.)

      model_mean, posterior_variance, posterior_log_variance = self.q_posterior(x_start = x_start, x_t = x, t = t)
      return model_mean, posterior_variance, posterior_log_variance, x_start

第三步: 根据公式(33)计算得到前一个时刻图片 x t − 1 x_{t-1} xt1

  @torch.no_grad()
  def p_sample(self, x, t: int, x_self_cond = None, clip_denoised = True):
      b, *_, device = *x.shape, x.device
      batched_times = torch.full((x.shape[0],), t, device = x.device, dtype = torch.long)
      model_mean, _, model_log_variance, x_start = self.p_mean_variance(x = x, t = batched_times, x_self_cond = x_self_cond, clip_denoised = clip_denoised)  # 计算当前分布的均值和方差
      noise = torch.randn_like(x) if t > 0 else 0. # 从高斯分布采样噪声
      pred_img = model_mean + (0.5 * model_log_variance).exp() * noise  # 根据
      return pred_img, x_start

通过迭代以上三步,直至 T = 0 T=0 T=0完成采样.

思考和讨论

DDPM区别与传统的VAE与GAN采用了一种新的范式实现了更高质量的图像生成.但实践发现,需要较大的采样步数才能得到较好的生成结果.由于其采样过程是一个马尔可夫的推理过程,导致会有较大的耗时.后续工作如DDIM针对该特性做了优化,数十倍降低采样所用时间。

参考文献


  1. [Denoising Diffusion Probabilistic Models]( ↩︎

  2. Understanding Diffusion Models: A Unified Perspective ↩︎

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

diffusion model(一)DDPM技术小结 (denoising diffusion probabilistic) 的相关文章

  • 文档扫描与矫正-仿射变换

    图像变换是计算机视觉和图像处理中的关键技术之一 它允许我们对图像进行各种形式的变形 调整和校正 其中 仿射变换是一种常见的变换方式 在文档扫描过程中 由于拍摄角度和畸变等原因 文档图像可能存在一定程度的形变 仿射变换可以用于校正文档图像 使
  • 比尔盖茨与萨姆.奥尔特曼的对话及感想

    谈话内容 比尔 盖茨 嘿 萨姆 萨姆 奥尔特曼 嘿 比尔 比尔 盖茨 你好吗 萨姆 奥尔特曼 哦 天哪 这真的太疯狂了 我还好 这是一个非常激动人心的时期 比尔 盖茨 团队情况怎么样 萨姆 奥尔特曼 我想 你知道很多人都注意到了这样一个事实
  • 【图像融合】基于联合双边滤波和局部梯度能量的多模态医学图像融合研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 图像 文章
  • 【路径规划】基于A*算法路径规划研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • 用CHAT写一份标题为职业教育教师教学能力提升培训总结

    CHAT回复 标题 职业教育教师教学能力提升培训总结 一 活动概述 本次由学校组织的职业教育教师教学能力提升培训于8月15日至8月20日顺利进行 来自全校的60位职业教育教师参与了此次培训 主讲人为享有盛名的教育专家马丁先生 二 培训内容与
  • Soul App:年轻人的社交状态,还有多少种可能?

    查尔斯 狄更斯在 双城记 的开篇写下 这是最好的时代 这是最坏的时代 这是智慧的时代 这是愚蠢的时代 这是信仰的时期 这是怀疑的时期 人们面前有着各样事物 人们面前一无所有 既然万事万物都和狄更斯所说般 好坏参半 那又何必执着于过去 苦恼于
  • 利用CHAT写实验结论

    问CHAT 通过观察放置在玻璃表面上的单个水滴 人们可以观察到水滴充当成像系统 探究这样一个透镜的放大倍数和分辨率 CHAT回复 实验报告标题 利用玻璃表面的单一水滴观察成像系统的放大倍数和分辨率 一 实验目的 通过对比和测量 研究和探索玻
  • 面对AI革新时,Soul App等社交应用的“出圈”解法是什么?

    2023年初 ChatGPT掀开海内外互联网 AI革新 的序幕 公众在惊讶于ChatGPT对于海量信息富有逻辑的整合归纳 帮助大家提升工作及学习效率之余 更为期待的莫过于有一天人工智能的 意识觉醒 十余年前由斯派克 琼斯 Spike Jon
  • 活动日程&直播预约|智谱AI技术开放日 Zhipu DevDay

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 直播预约通道 关于AI TIME AI TIME源起于2019年 旨在发扬科学思辨精神 邀请各界人士对人工智能理论 算法和场景应用的本质问题进行探索 加强思想碰撞 链接全球AI学
  • 基于opencv的大米计数统计(详细处理流程+代码)

    在我每周的标准作业清单中 有一项是编写计算机视觉算法来计算该图像中米粒的数量 因此 当我的一个好朋友M给我发了一张纸上的扁豆照片 显然是受到上述转发的启发 请我帮他数一下谷物的数量时 它勾起了我怀旧的回忆 因此 我在我的旧硬盘上寻找很久以前
  • 毕业设计:基于深度学习的微博谣言检测系统 人工智能

    目录 前言 设计思路 一 课题背景与意义 二 算法理论原理 三 检测的实现 最后 前言 大四是整个大学期间最忙碌的时光 一边要忙着备考或实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有
  • 作物叶片病害识别系统

    介绍 由于植物疾病的检测在农业领域中起着重要作用 因为植物疾病是相当自然的现象 如果在这个领域不采取适当的护理措施 就会对植物产生严重影响 进而影响相关产品的质量 数量或产量 植物疾病会引起疾病的周期性爆发 导致大规模死亡 这些问题需要在初
  • 机器学习算法实战案例:Informer实现多变量负荷预测

    文章目录 机器学习算法实战案例系列 答疑 技术交流 1 实验数据集 2 如何运行自己的数据集 3 报错分析 机器学习算法实战案例系
  • 人工智能 AI 如何让我们的生活更加便利

    每个人都可以从新技术中获益 一想到工作或生活更为便利 简捷且拥有更多空余时间 谁会不为之高兴呢 借助人工智能 每天能够多一些空余时间 或丰富自己的业余生活 为培养日常兴趣爱好增添一点便利 从电子阅读器到智能家居 再到植物识别应用和智能室内花
  • AI-基于Langchain-Chatchat和chatglm3-6b部署私有本地知识库

    目录 参考 概述 部署安装 环境准备 原理和流程图 一键启动 启动WebAPI 服务 启动WebUI服务 Docker部署
  • 蒙特卡洛在发电系统中的应用(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现
  • 史上最全自动驾驶岗位介绍

    作者 自动驾驶转型者 编辑 汽车人 原文链接 https zhuanlan zhihu com p 353480028 点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 求职交流 技术交流群 本
  • 考虑光伏出力利用率的电动汽车充电站能量调度策略研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 两个月进口猛增10倍,买近百台光刻机,难怪ASML不舍中国市场

    据统计数据显示 2023年11月和12月 中国从荷兰进口的光刻机设备同比猛增10倍 进口金额超过19亿美元 让ASML赚得盆满钵满 ASML早前表示中国客户在2023年订购的光刻机全数交付 2023年11月中国进口的光刻机达到42台 进口金
  • 实力认证!鼎捷软件荣膺“领军企业”和“创新产品”两大奖项

    近日 由中国科学院软件研究所 中科软科技股份有限公司联合主办的 2023中国软件技术大会 于北京成功举办 本届大会以 大模型驱动下的软件变革 为主题 数十位来自知名互联网公司和软件巨头企业的技术大咖 不同领域行业专家 畅销书作者等分享嘉宾

随机推荐