论文阅读笔记:Denoising Diffusion Probabilistic Models (3)
论文阅读笔记:Denoising Diffusion Probabilistic Models (1)
论文阅读笔记:Denoising Diffusion Probabilistic Models (2)
论文阅读笔记:Denoising Diffusion Probabilistic Models (3)
4、损失函数逐项分析
可以看出 L L L总共分为了3项,首先考虑第一项 L 1 L_1 L1。
L 1 = E x 1 : T ∼ q ( x 1 : T ∣ x 0 ) ( l o g [ q ( x T ∣ x 0 ) p ( x T ) ] ) = ∫ d x 1 : T ⋅ q ( x 1 : T ∣ x 0 ) ⋅ l o g [ q ( x T ∣ x 0 ) p ( x T ) ] = ∫ d x 1 : T ⋅ q ( x 1 : T ∣ x 0 ) q ( x T ∣ x 0 ) ⋅ q ( x T ∣ x 0 ) ⋅ l o g [ q ( x T ∣ x 0 ) p ( x T ) ] = ∫ d x 1 : T ⋅ q ( x 1 : T − 1 ∣ x 0 , x T ) ⏟ q ( x 1 : T ∣ x 0 ) = q ( x T ∣ x 0 ) ⋅ q ( x 1 ; T − 1 ∣ x 0 , x T ) ⋅ q ( x T ∣ x 0 ) ⋅ l o g [ q ( x T ∣ x 0 ) p ( x T ) ] = ∫ ( ∫ q ( x 1 : T − 1 ∣ x 0 , x T ) ⋅ ∏ k = 1 T − 1 d x k ⏟ 二重积分化为两个定积分相乘,并且 = 1 ) ⋅ q ( x T ∣ x 0 ) ⋅ l o g [ q ( x T ∣ x 0 ) p ( x T ) ] ⋅ d x T = ∫ q ( x T ∣ x 0 ) ⋅ l o g [ q ( x T ∣ x 0 ) p ( x T ) ] ⋅ d x T = E x T ∼ q ( x T ∣ x 0 ) l o g [ q ( x T ∣ x 0 ) p ( x T ) ] = K L ( q ( x T ∣ x 0 ) ∣ ∣ p ( x T ) ) \begin{equation} \begin{split} L_1&=E_{x_{1:T} \sim q(x_{1:T} | x_0)} \Bigg(log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)}\Big]\Bigg) \\ &=\int dx_{1:T} \cdot q(x_{1:T}| x_0) \cdot log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)}\Big] \\ &=\int dx_{1:T} \cdot \frac{q(x_{1:T}| x_0)}{q(x_T|x_0)} \cdot q(x_T|x_0) \cdot log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)}\Big] \\ &=\int dx_{1:T} \cdot \underbrace{ q(x_{1:T-1}| x_0, x_T) }_{q(x_{1:T}| x_0)=q(x_{T}|x_0) \cdot q(x_{1;T-1}| x_0, x_T)} \cdot q(x_T|x_0) \cdot log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)}\Big] \\ &=\int \Bigg( \underbrace{ \int q(x_{1:T-1}| x_0, x_T) \cdot \prod_{k=1}^{T-1} dx_k }_{二重积分化为两个定积分相乘,并且=1} \Bigg) \cdot q(x_T|x_0) \cdot log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)} \Big] \cdot dx_{T} \\ &=\int q(x_T|x_0) \cdot log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)} \Big] \cdot dx_{T} \\ &=E_{x^T\sim q(x_T|x_0)} log \Big[ \frac{q(x_{T}|x_0)}{ p(x_T)} \Big]\\ &= KL\Big(q(x_T|x_0)||p(x_T)\Big) \end{split} \end{equation} L1=Ex1:T∼q(x1:T∣x0)(log[p(xT)q(xT∣x0)])=∫dx1:T⋅q(x1:T∣x0)⋅log[p(xT)q(xT∣x0)]=∫dx1:T⋅q(xT∣x0)q(x1:T∣x0)⋅q(xT∣x0)⋅log[p(xT)q(xT∣x0)]=∫dx1:T⋅q(x1:T∣x0)=q(xT∣x0)⋅q(x1;T−1∣x0,xT) q(x1:T−1∣x0,xT)⋅q(xT∣x0)⋅log[p(xT)q(xT∣x0)]=∫(二重积分化为两个定积分相乘,并且=1 ∫q(x1:T−1∣x0,xT)⋅k=1∏T−1dxk)⋅q(xT∣x0)⋅log[p(xT)q(xT∣x0)]⋅dxT=∫q(xT∣x0)⋅log[p(xT)q(xT∣x0)]⋅dxT=ExT∼q(xT∣x0)log[p(xT)q(xT∣x0)]=KL(q(xT∣x0)∣∣p(xT))
可以看出, L 1 L_1 L1是 q ( x T ∣ x 0 ) q(x_T|x_0) q(xT∣x0)和 p ( x T ) p(x_T) p(xT)的散度。 q ( x T ∣ x 0 ) q(x_T|x_0) q(xT∣x0)是前向加噪过程的终点,是无限趋向于标准正态分布。而 p ( x T ) p(x_T) p(xT)是高斯分布,这在论文《Denoising Diffusion Probabilistic Models》中的2 Background的第四行中有说明。由 两个高斯分布KL散度推导可以计算出 L 1 L_1 L1,也就是说 L 1 L_1 L1是一个定值。因此,在损失函数中 L 1 L_1 L1可以被忽略掉。
接着考虑第二项 L 2 L_2 L2。
L 2 = E x 1 : T ∼ q ( x 1 : T ∣ x 0 ) ( ∑ t = 2 T l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T E x 1 : T ∼ q ( x 1 : T ∣ x 0 ) ( l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T ( ∫ d x 1 : T ⋅ q ( x 1 : T ∣ x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T ( ∫ d x 1 : T ⋅ q ( x 1 : T ∣ x 0 ) q ( x t − 1 ∣ x t , x 0 ) ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T ( ∫ d x 1 : T ⋅ q ( x 0 : T ) q ( x 0 ) ⏟ q ( x 0 : T ) = q ( x 0 ) ⋅ q ( x 1 : T ∣ x 0 ) ⋅ q ( x t , x 0 ) q ( x t , x t − 1 , x 0 ) ⏟ q ( x t , x t − 1 , x 0 ) = q ( x t , x 0 ) ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T ( ∫ d x 1 : T ⋅ q ( x 0 : T ) q ( x 0 ) ⋅ q ( x t , x 0 ) q ( x t − 1 , x 0 ) ⋅ q ( x t ∣ x t − 1 , x 0 ) ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x 0 : T ) q ( x 0 ) ⋅ q ( x t , x 0 ) q ( x t − 1 , x 0 ) ⋅ q ( x t ∣ x t − 1 , x 0 ) ∏ k ≥ 1 , k ≠ t − 1 d x k ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x 0 : T ) q ( x t − 1 , x 0 ) ⋅ q ( x t , x 0 ) q ( x 0 ) ⋅ q ( x t ∣ x t − 1 , x 0 ) ∏ k ≥ 1 , k ≠ t − 1 d x k ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x k : k ≥ 1 , k ≠ t − 1 ∣ x t − 1 , x 0 ) ⏟ q ( x 0 ; T ) = q ( x t − 1 , x 0 ) ⋅ q ( x k : k ≥ 1 , k ≠ t − 1 ∣ x t − 1 , x 0 ) ⋅ q ( x t ∣ x 0 ) q ( x t ∣ x t − 1 , x 0 ) ⏟ q ( x t , x 0 ) = q ( x 0 ) ⋅ q ( x t ∣ x 0 ) ∏ k ≥ 1 , k ≠ t − 1 d x k ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x k : k ≥ 1 , k ≠ t − 1 ∣ x t − 1 , x 0 ) ⋅ q ( x t ∣ x 0 ) q ( x t ∣ x t − 1 , x 0 ) ⏟ = 1 ∏ k ≥ 1 , k ≠ t − 1 d x k ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x k : k ≥ 1 , k ≠ t − 1 ∣ x t − 1 , x 0 ) ⋅ ∏ k ≥ 1 , k ≠ t − 1 d x k ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ [ ∫ q ( x k : k ≥ 1 , k ≠ t − 1 ∣ x t − 1 , x 0 ) ⋅ ∏ k ≥ 1 , k ≠ t − 1 d x k ⏟ = 1 ] ⋅ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( ∫ q ( x t − 1 ∣ x t , x 0 ) ⋅ l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) d x t − 1 ] ) = ∑ t = 2 T ( E x t − 1 ∼ q ( x t − 1 ∣ x t , x 0 ) l o g [ q ( x t − 1 ∣ x t , x 0 ) p θ ( x t − 1 ∣ x t ) ] ) = ∑ t = 2 T K L ( q ( x t − 1 ∣ x t , x 0 ) ∣ ∣ p θ ( x t − 1 ∣ x t ) ) \begin{equation} \begin{split} L_2&=E_{x_{1:T} \sim q(x_{1:T} | x_0)} \Bigg(\sum_{t=2}^{T} log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big]\Bigg)\\ &=\sum_{t=2}^{T} E_{x_{1:T} \sim q(x_{1:T} | x_0)} \Bigg(log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big]\Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int dx_{1:T} \cdot q(x_{1:T}| x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int dx_{1:T} \cdot \frac{ q(x_{1:T}| x_0)}{q(x_{t-1}|x_t,x_0)} \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p(x_{t-1}|x_t)} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int dx_{1:T} \cdot \underbrace{ \frac{q(x_{0:T})}{q(x_0)}}_{q(x_{0:T})=q(x_0)\cdot q(x_{1:T}| x_0)} \cdot \underbrace{ \frac{q(x_t,x_0)}{q(x_t,x_{t-1},x_0)}}_{q(x_t,x_{t-1},x_0)=q(x_t,x_0)\cdot q(x_{t-1}|x_t,x_0)} \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int dx_{1:T} \cdot \frac{q(x_{0:T})}{q(x_0)}\cdot \frac{q(x_t,x_0)}{q(x_{t-1},x_0)\cdot q(x_t|x_{t-1},x_0)} \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[ \int \frac{q(x_{0:T})}{q(x_0)}\cdot \frac{q(x_t,x_0)}{q(x_{t-1},x_0)\cdot q(x_t|x_{t-1},x_0)} \prod_{k\geq1 ,k\neq t-1} dx_k \bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[ \int \frac{q(x_{0:T})}{q(x_{t-1},x_0)}\cdot \frac{q(x_t,x_0)}{q(x_0)\cdot q(x_t|x_{t-1},x_0)} \prod_{k\geq1 ,k\neq t-1} dx_k \bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[ \underbrace{ \int q(x_{k:k\geq1,k\neq t-1}|x_{t-1},x_0)}_{q(x_{0;T})=q(x_{t-1},x_0)\cdot q(x_{k:k\geq1,k\neq t-1}|x_{t-1},x_0)} \cdot \underbrace {\frac{q(x_t|x_0)}{ q(x_t|x_{t-1},x_0)}}_{q(x_t,x_0)=q(x_0)\cdot q(x_t|x_0)} \prod_{k\geq1 ,k\neq t-1} dx_k \bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[\int q(x_{k:k\geq1,k\neq t-1}|x_{t-1},x_0)\cdot \underbrace {\frac{q(x_t|x_0)}{ q(x_t|x_{t-1},x_0)}}_{=1} \prod_{k\geq1 ,k\neq t-1} dx_k \bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[\int q(x_{k:k\geq1,k\neq t-1}|x_{t-1},x_0)\cdot \prod_{k\geq1 ,k\neq t-1} dx^k \bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int \bigg[\underbrace{ \int q(x_{k:k\geq1,k\neq t-1}|x_{t-1},x^0)\cdot \prod_{k\geq1 ,k\neq t-1} dx_k }_{=1}\bigg] \cdot q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( \int q(x_{t-1}|x_t,x_0) \cdot log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} dx_{t-1} \Big] \Bigg)\\ &=\sum_{t=2}^{T} \Bigg( E_{x_{t-1}\sim q(x_{t-1}|x_t,x_0)} log \Big[\frac{q(x_{t-1}|x_t,x_0)}{ p_{\theta}(x_{t-1}|x_t)} \Big] \Bigg)\\ &=\sum_{t=2}^{T}KL\bigg(q(x_{t-1}|x_t,x_0)||p_{\theta}(x_{t-1}|x_t) \bigg) \end{split} \end{equation} L2=Ex1:T∼q(x1:T∣x0)(t=2∑Tlog[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑TEx1:T∼q(x1:T∣x0)(log[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑T(∫dx1:T⋅q(x1:T∣x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑T(∫dx1:T⋅q(xt−1∣xt,x0)q(x1:T∣x0)⋅q(xt−1∣xt,x0)⋅log[p(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑T(∫dx1:T⋅q(x0:T)=q(x0)⋅q(x1:T∣x0) q(x0)q(x0:T)⋅q(xt,xt−1,x0)=q(xt,x0)⋅q(xt−1∣xt,x0) q(xt,xt−1,x0)q(xt,x0)⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑T(∫dx1:T⋅q(x0)q(x0:T)⋅q(xt−1,x0)⋅q(xt∣xt−1,x0)q(xt,x0)⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑T(∫[∫q(x0)q(x0:T)⋅q(xt−1,x0)⋅q(xt∣xt−1,x0)q(xt,x0)k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫[∫q(xt−1,x0)q(x0:T)⋅q(x0)⋅q(xt∣xt−1,x0)q(xt,x0)k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫[q(x0;T)=q(xt−1,x0)⋅q(xk:k≥1,k=t−1∣xt−1,x0) ∫q(xk:k≥1,k=t−1∣xt−1,x0)⋅q(xt,x0)=q(x0)⋅q(xt∣x0) q(xt∣xt−1,x0)q(xt∣x0)k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫[∫q(xk:k≥1,k=t−1∣xt−1,x0)⋅=1 q(xt∣xt−1,x0)q(xt∣x0)k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫[∫q(xk:k≥1,k=t−1∣xt−1,x0)⋅k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫[=1 ∫q(xk:k≥1,k=t−1∣xt−1,x0)⋅k≥1,k=t−1∏dxk]⋅q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(∫q(xt−1∣xt,x0)⋅log[pθ(xt−1∣xt)q(xt−1∣xt,x0)dxt−1])=t=2∑T(Ext−1∼q(xt−1∣xt,x0)log[pθ(xt−1∣xt)q(xt−1∣xt,x0)])=t=2∑TKL(q(xt−1∣xt,x0)∣∣pθ(xt−1∣xt))
最后考虑 L 3 L_3 L3,事实上,在论文《Deep Unsupervised Learning using Nonequilibrium Thermodynamics》中提到为了防止边界效应,强制另 p ( x 0 ∣ x 1 ) = q ( x 1 ∣ x 0 ) p(x^0|x^1)=q(x^1|x^0) p(x0∣x1)=q(x1∣x0),因此这一项也是个常数。
由以上分析可知道,损失函数可以写为公式(3)。
L : = L 1 + L 2 + L 3 = K L ( q ( x T ∣ x 0 ) ∣ ∣ p ( x T ) ) + ∑ t = 2 T K L ( q ( x t − 1 ∣ x t , x 0 ) ∣ ∣ p θ ( x t − 1 ∣ x t ) ) − l o g [ p θ ( x 0 ∣ x 1 ) ] \begin{equation} \begin{split} L&:=L_1+L_2+L_3 \\ &=KL\Big(q(x_T|x_0)||p(x_T)\Big) + \sum_{t=2}^{T}KL\bigg(q(x_{t-1}|x_t,x_0)||p_{\theta}(x_{t-1}|x_t) \bigg)-log \Big[p_{\theta}(x_{0}|x_1)\Big] \end{split} \end{equation} L:=L1+L2+L3=KL(q(xT∣x0)∣∣p(xT))+t=2∑TKL(q(xt−1∣xt,x0)∣∣pθ(xt−1∣xt))−log[pθ(x0∣x1)]
忽略掉 L 1 L_1 L1和 L 3 L_3 L3,损失函数可以写为公式(4)。
L : = ∑ t = 2 T K L ( q ( x t − 1 ∣ x t , x 0 ) ∣ ∣ p θ ( x t − 1 ∣ x t ) ) \begin{equation} \begin{split} L:=\sum_{t=2}^{T}KL\bigg(q(x_{t-1}|x_t,x_0)||p_{\theta}(x_{t-1}|x_t) \bigg) \end{split} \end{equation} L:=t=2∑TKL(q(xt−1∣xt,x0)∣∣pθ(xt−1∣xt))
可以看出 损失函数 L L L是两个高斯分布 q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t,x_0) q(xt−1∣xt,x0)和 p θ ( x t − 1 ∣ x t ) p_{\theta}(x_{t-1}|x_t) pθ(xt−1∣xt)的KL散度。 q ( x t − 1 ∣ x t , x 0 ) q(x_{t-1}|x_t,x_0) q(xt−1∣xt,x0)的均值和方差由论文阅读笔记:Denoising Diffusion Probabilistic Models (1)可知,分别为
σ 1 = β t ⋅ ( 1 − α t − 1 ˉ ) ( 1 − α t ˉ ) μ 1 = 1 α t ⋅ ( x t − β t 1 − α t ˉ ⋅ z t ) 或者 μ 1 = α t ⋅ ( 1 − α t − 1 ˉ ) 1 − α t ˉ ⋅ x t + β t ⋅ α t − 1 ˉ 1 − α t ˉ ⋅ x 0 \begin{equation} \begin{split} \sigma_1&=\sqrt{\frac{\beta_t\cdot (1-\bar{\alpha_{t-1}})}{(1-\bar{\alpha_{t}})}}\\ \mu_1&=\frac{1}{\sqrt{\alpha_t}}\cdot (x_t-\frac{\beta_t}{\sqrt{1-\bar{\alpha_t}}}\cdot z_t) \\ 或者 \mu_1&=\frac{\sqrt{\alpha_t}\cdot(1-\bar{\alpha_{t-1}})}{1-\bar{\alpha_t}}\cdot x_t+\frac{\beta_t\cdot \sqrt{\bar{\alpha_{t-1}}}}{1-\bar{\alpha_t}} \cdot x_0 \end{split} \end{equation} σ1μ1或者μ1=(1−αtˉ)βt⋅(1−αt−1ˉ)=αt1⋅(xt−1−αtˉβt⋅zt)=1−αtˉαt⋅(1−αt−1ˉ)⋅xt+1−αtˉβt⋅αt−1ˉ⋅x0
而 p θ ( x t − 1 ∣ x t ) p_{\theta}(x_{t-1}|x_t) pθ(xt−1∣xt)则由模型(深度学习模型或者其他模型)估算出其均值和方差,分别记作 μ 2 , σ 2 \mu_2,\sigma_2 μ2,σ2。
因此损失函数 L L L可以进一步写为公式12。
L : = l o g [ σ 2 σ 1 ] + σ 1 2 + ( μ 1 − μ 2 ) 2 2 σ 2 2 − 1 2 \begin{equation} \begin{split} L:=log \Big[\frac{\sigma_2}{\sigma_1}\Big]+\frac{\sigma_1^2 +(\mu_1-\mu_2)^2}{2\sigma_2^2}-\frac{1}{2} \end{split} \end{equation} L:=log[σ1σ2]+2σ22σ12+(μ1−μ2)2−21
5、代码解析
最后结合原文中的代码diffusion-https://github.com/hojonathanho/diffusion来理解一下训练过程和推理过程。
首先是训练过程
class GaussianDiffusion2:"""Contains utilities for the diffusion model.Arguments:- what the network predicts (x_{t-1}, x_0, or epsilon)- which loss function (kl or unweighted MSE)- what is the variance of p(x_{t-1}|x_t) (learned, fixed to beta, or fixed to weighted beta)- what type of decoder, and how to weight its loss? is its variance learned too?"""# 模型中的一些定义def __init__(self, *, betas, model_mean_type, model_var_type, loss_type):self.model_mean_type = model_mean_type # xprev, xstart, epsself.model_var_type = model_var_type # learned, fixedsmall, fixedlargeself.loss_type = loss_type # kl, mseassert isinstance(betas, np.ndarray)self.betas = betas = betas.astype(np.float64) # computations here in float64 for accuracyassert (betas > 0).all() and (betas <= 1).all()timesteps, = betas.shapeself.num_timesteps = int(timesteps)alphas = 1. - betasself.alphas_cumprod = np.cumprod(alphas, axis=0)self.alphas_cumprod_prev = np.append(1., self.alphas_cumprod[:-1])assert self.alphas_cumprod_prev.shape == (timesteps,)# calculations for diffusion q(x_t | x_{t-1}) and othersself.sqrt_alphas_cumprod = np.sqrt(self.alphas_cumprod)self.sqrt_one_minus_alphas_cumprod = np.sqrt(1. - self.alphas_cumprod)self.log_one_minus_alphas_cumprod = np.log(1. - self.alphas_cumprod)self.sqrt_recip_alphas_cumprod = np.sqrt(1. / self.alphas_cumprod)self.sqrt_recipm1_alphas_cumprod = np.sqrt(1. / self.alphas_cumprod - 1)# calculations for posterior q(x_{t-1} | x_t, x_0)self.posterior_variance = betas * (1. - self.alphas_cumprod_prev) / (1. - self.alphas_cumprod)# below: log calculation clipped because the posterior variance is 0 at the beginning of the diffusion chainself.posterior_log_variance_clipped = np.log(np.append(self.posterior_variance[1], self.posterior_variance[1:]))self.posterior_mean_coef1 = betas * np.sqrt(self.alphas_cumprod_prev) / (1. - self.alphas_cumprod)self.posterior_mean_coef2 = (1. - self.alphas_cumprod_prev) * np.sqrt(alphas) / (1. - self.alphas_cumprod)# 在模型Model类当中的方法def train_fn(self, x, y):B, H, W, C = x.shapeif self.randflip:x = tf.image.random_flip_left_right(x)assert x.shape == [B, H, W, C]# 随机生成第t步t = tf.random_uniform([B], 0, self.diffusion.num_timesteps, dtype=tf.int32)# 计算第t步时对应的损失函数losses = self.diffusion.training_losses(denoise_fn=functools.partial(self._denoise, y=y, dropout=self.dropout), x_start=x, t=t)assert losses.shape == t.shape == [B]return {'loss': tf.reduce_mean(losses)}# 根据x_start采样到第t步的带噪图像def q_sample(self, x_start, t, noise=None):"""Diffuse the data (t == 0 means diffused for 1 step)"""if noise is None:noise = tf.random_normal(shape=x_start.shape)assert noise.shape == x_start.shapereturn (self._extract(self.sqrt_alphas_cumprod, t, x_start.shape) * x_start +self._extract(self.sqrt_one_minus_alphas_cumprod, t, x_start.shape) * noise)# 计算q(x^{t-1}|x^t,x^0)分布的均值和方差def q_posterior_mean_variance(self, x_start, x_t, t):"""Compute the mean and variance of the diffusion posterior q(x_{t-1} | x_t, x_0)"""assert x_start.shape == x_t.shapeposterior_mean = (self._extract(self.posterior_mean_coef1, t, x_t.shape) * x_start +self._extract(self.posterior_mean_coef2, t, x_t.shape) * x_t)posterior_variance = self._extract(self.posterior_variance, t, x_t.shape)posterior_log_variance_clipped = self._extract(self.posterior_log_variance_clipped, t, x_t.shape)assert (posterior_mean.shape[0] == posterior_variance.shape[0] == posterior_log_variance_clipped.shape[0] ==x_start.shape[0])return posterior_mean, posterior_variance, posterior_log_variance_clipped# 由深度学习模型UNet估算出p(x^{t-1}|x^t)分布的方差和均值def p_mean_variance(self, denoise_fn, *, x, t, clip_denoised: bool, return_pred_xstart: bool):B, H, W, C = x.shapeassert t.shape == [B]model_output = denoise_fn(x, t)# Learned or fixed variance?if self.model_var_type == 'learned':assert model_output.shape == [B, H, W, C * 2]model_output, model_log_variance = tf.split(model_output, 2, axis=-1)model_variance = tf.exp(model_log_variance)elif self.model_var_type in ['fixedsmall', 'fixedlarge']:# below: only log_variance is used in the KL computationsmodel_variance, model_log_variance = {# for fixedlarge, we set the initial (log-)variance like so to get a better decoder log likelihood'fixedlarge': (self.betas, np.log(np.append(self.posterior_variance[1], self.betas[1:]))),'fixedsmall': (self.posterior_variance, self.posterior_log_variance_clipped),}[self.model_var_type]model_variance = self._extract(model_variance, t, x.shape) * tf.ones(x.shape.as_list())model_log_variance = self._extract(model_log_variance, t, x.shape) * tf.ones(x.shape.as_list())else:raise NotImplementedError(self.model_var_type)# Mean parameterization_maybe_clip = lambda x_: (tf.clip_by_value(x_, -1., 1.) if clip_denoised else x_)if self.model_mean_type == 'xprev': # the model predicts x_{t-1}pred_xstart = _maybe_clip(self._predict_xstart_from_xprev(x_t=x, t=t, xprev=model_output))model_mean = model_outputelif self.model_mean_type == 'xstart': # the model predicts x_0pred_xstart = _maybe_clip(model_output)model_mean, _, _ = self.q_posterior_mean_variance(x_start=pred_xstart, x_t=x, t=t)elif self.model_mean_type == 'eps': # the model predicts epsilonpred_xstart = _maybe_clip(self._predict_xstart_from_eps(x_t=x, t=t, eps=model_output))model_mean, _, _ = self.q_posterior_mean_variance(x_start=pred_xstart, x_t=x, t=t)else:raise NotImplementedError(self.model_mean_type)assert model_mean.shape == model_log_variance.shape == pred_xstart.shape == x.shapeif return_pred_xstart:return model_mean, model_variance, model_log_variance, pred_xstartelse:return model_mean, model_variance, model_log_variance# 损失函数的计算过程def training_losses(self, denoise_fn, x_start, t, noise=None):assert t.shape == [x_start.shape[0]]# 随机生成一个噪音if noise is None:noise = tf.random_normal(shape=x_start.shape, dtype=x_start.dtype)assert noise.shape == x_start.shape and noise.dtype == x_start.dtype# 将随机生成的噪音加到x_start上得到第t步的带噪图像x_t = self.q_sample(x_start=x_start, t=t, noise=noise)# 有两种损失函数的方法,'kl'和'mse',并且这两种方法差别并不明显。if self.loss_type == 'kl': # the variational boundlosses = self._vb_terms_bpd(denoise_fn=denoise_fn, x_start=x_start, x_t=x_t, t=t, clip_denoised=False, return_pred_xstart=False)elif self.loss_type == 'mse': # unweighted MSEassert self.model_var_type != 'learned'target = {'xprev': self.q_posterior_mean_variance(x_start=x_start, x_t=x_t, t=t)[0],'xstart': x_start,'eps': noise}[self.model_mean_type]model_output = denoise_fn(x_t, t)assert model_output.shape == target.shape == x_start.shapelosses = nn.meanflat(tf.squared_difference(target, model_output))else:raise NotImplementedError(self.loss_type)assert losses.shape == t.shapereturn losses# 计算两个高斯分布的KL散度,代码中的logvar1,logvar2为方差的对数def normal_kl(mean1, logvar1, mean2, logvar2):"""KL divergence between normal distributions parameterized by mean and log-variance."""return 0.5 * (-1.0 + logvar2 - logvar1 + tf.exp(logvar1 - logvar2)+ tf.squared_difference(mean1, mean2) * tf.exp(-logvar2))# 使用'kl'方法计算损失函数def _vb_terms_bpd(self, denoise_fn, x_start, x_t, t, *, clip_denoised: bool, return_pred_xstart: bool):true_mean, _, true_log_variance_clipped = self.q_posterior_mean_variance(x_start=x_start, x_t=x_t, t=t)model_mean, _, model_log_variance, pred_xstart = self.p_mean_variance(denoise_fn, x=x_t, t=t, clip_denoised=clip_denoised, return_pred_xstart=True)kl = normal_kl(true_mean, true_log_variance_clipped, model_mean, model_log_variance)kl = nn.meanflat(kl) / np.log(2.)decoder_nll = -utils.discretized_gaussian_log_likelihood(x_start, means=model_mean, log_scales=0.5 * model_log_variance)assert decoder_nll.shape == x_start.shapedecoder_nll = nn.meanflat(decoder_nll) / np.log(2.)# At the first timestep return the decoder NLL, otherwise return KL(q(x_{t-1}|x_t,x_0) || p(x_{t-1}|x_t))assert kl.shape == decoder_nll.shape == t.shape == [x_start.shape[0]]output = tf.where(tf.equal(t, 0), decoder_nll, kl)return (output, pred_xstart) if return_pred_xstart else output
接下来是推理过程。
def p_sample(self, denoise_fn, *, x, t, noise_fn, clip_denoised=True, return_pred_xstart: bool):"""Sample from the model"""# 使用深度学习模型,根据x^t和t估算出x^{t-1}的均值和分布model_mean, _, model_log_variance, pred_xstart = self.p_mean_variance(denoise_fn, x=x, t=t, clip_denoised=clip_denoised, return_pred_xstart=True)noise = noise_fn(shape=x.shape, dtype=x.dtype)assert noise.shape == x.shape# no noise when t == 0nonzero_mask = tf.reshape(1 - tf.cast(tf.equal(t, 0), tf.float32), [x.shape[0]] + [1] * (len(x.shape) - 1))# 当t>0时,模型估算出的结果还要加上一个高斯噪音,因为要继续循环。当t=0时,循环停止,因此不需要再添加噪音了,输出最后的结果。sample = model_mean + nonzero_mask * tf.exp(0.5 * model_log_variance) * noiseassert sample.shape == pred_xstart.shapereturn (sample, pred_xstart) if return_pred_xstart else sampledef p_sample_loop(self, denoise_fn, *, shape, noise_fn=tf.random_normal):"""Generate samples"""assert isinstance(shape, (tuple, list))# 生成总的布数Ti_0 = tf.constant(self.num_timesteps - 1, dtype=tf.int32)# 随机生成一个噪音作为p(x^T)img_0 = noise_fn(shape=shape, dtype=tf.float32)# 循环T次,得到最终的图像_, img_final = tf.while_loop(cond=lambda i_, _: tf.greater_equal(i_, 0),body=lambda i_, img_: [i_ - 1,self.p_sample(denoise_fn=denoise_fn, x=img_, t=tf.fill([shape[0]], i_), noise_fn=noise_fn, return_pred_xstart=False)],loop_vars=[i_0, img_0],shape_invariants=[i_0.shape, img_0.shape],back_prop=False)assert img_final.shape == shapereturn img_final
相关文章:
论文阅读笔记:Denoising Diffusion Probabilistic Models (3)
论文阅读笔记:Denoising Diffusion Probabilistic Models (1) 论文阅读笔记:Denoising Diffusion Probabilistic Models (2) 论文阅读笔记:Denoising Diffusion Probabilistic Models (3) 4、损失函数逐项分析 可以看出 L L L总共分为了3项…...
FlauBERT:面向法语的无监督语言模型预训练
摘要 语言模型已成为在许多不同自然语言处理(NLP)任务中取得最先进成果的关键步骤。利用当今可用的大量未标注文本,它们提供了一种有效的方式来预训练连续词表示,这些表示可以在下游任务中进行微调,并在句子级别上进行…...
JavaScript严格模式
文章主要介绍JavaScript严格模式,包括启用原因、方式以及需避开的常见陷阱,助力开发者写出更健壮代码。 1. 启用原因:将普通JavaScript中的“静默错误”变为抛出错误,有助于编写健壮代码;修复阻碍JavaScript引擎优化的…...
文件上传的小点总结(1)
2.文件类型绕过 问题插入:BP无法拦截本地流量 ①插件限制 不代理的地址列表通常写有localhost和127.0.0.1,把本地的全都删掉,然后应用保存。 ②浏览器限制 Firefox浏览器设置:检查浏览器代理配置和proxy listeners都没问题后&…...
2024年数维杯数学建模B题生物质和煤共热解问题的研究解题全过程论文及程序
2024年数维杯数学建模 B题 生物质和煤共热解问题的研究 原题再现: 随着全球能源需求的不断增长和对可再生能源的追求,生物质和煤共热解作为一种潜在的能源转化技术备受关注。生物质是指可再生能源,源自植物和动物的有机物质,而煤…...
@maptalks/gl-layers中的VectorTileLayer的Symbol样式文档
maptalks/gl-layers中的VectorTileLayer的Symbol样式文档 矢量的Symbol样式分为以下几个大类: marker样式属性,定义了图标相关样式属性 text样式属性,定义了文字相关样式属性 line样式属性,定义了线相关的样式属性 polygon样式属…...
OpenCV旋转估计(3)帮助构建一个最大生成树(Maximum Spanning Tree)函数findMaxSpanningTree()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::detail::findMaxSpanningTree 是 OpenCV 中用于图像拼接工作流的一个函数,它帮助构建一个最大生成树(Maximum Spanni…...
OpenCV HighGUI 模块使用指南(Python 版)
用户让我编写一个 HighGUI 模块的使用指南,包括函数的使用和应用场景的实现。首先,我需要回顾 HighGUI 模块的主要功能:图像显示、视频捕获、鼠标和键盘事件。然后,按照用户提供的结构,整理每个部分的函数详解、代码示…...
SPI 机制与 Spring Boot AutoConfiguration 对比解析
一、架构效率革命性提升 1.1 类加载效率跃升 Spring Boot 2.7引入的AutoConfiguration.imports采用清单式配置加载,对比传统SPI机制: 传统SPI扫描路径:META-INF/services/** Spring Boot新方案:META-INF/spring/org.springfram…...
算法基础篇(1)(蓝桥杯常考点)
算法基础篇 前言 算法内容还有搜索,数据结构(进阶),动态规划和图论 数学那个的话大家也知道比较难,放在最后讲 这期包含的内容可以看目录 模拟那个算法的话就是题说什么写什么,就不再分入目录中了 注意事…...
【蓝桥杯速成】| 10.回溯切割
前面两篇内容我们都是在做有关回溯问题的组合应用 今天的题目主题是:回溯法在切割问题的应用 题目一:分割回文串 问题描述 131. 分割回文串 - 力扣(LeetCode) 给你一个字符串 s,请你将 s 分割成一些 子串ÿ…...
【Spring】深入理解 Spring 事务管理
文章目录 一、事务的基本概念原子性(Atomicity)一致性(Consistency)隔离性(Isolation)持久性(Durability) 二、Spring 事务管理的优势简化事务管理代码提供多种事务管理方式整合…...
java学习笔记6
按住shift键,选择开始的一位和最后结束的一位来全选 面向对象特征之二:继承性(inheritance) 面向对象特征之二:继承性1.继承性的理解 > 生活上:财产的继承、颜值的继承 > 代码层面:> 自上而下:定义了一个类A,在定义另一个类B时&…...
人工智能在现代科技中的应用和未来发展趋势
人工智能(Artificial Intelligence,AI)是一种模拟人类智能思维和行为的技术,已经在现代科技中得到广泛应用。以下是人工智能在现代科技中的应用和未来发展趋势: 应用: 机器学习:机器学习是人工…...
第二十一章:模板与继承_《C++ Templates》notes
模板与继承 重点和难点编译与测试说明第一部分:多选题 (10题)第二部分:设计题 (5题)答案与详解多选题答案:设计题参考答案 测试说明 重点和难点 21.1 空基类优化(EBCO) 知识点 空基类优化(Empty Base Cla…...
STC89C52单片机学习——第35节: [16-1] AD/DA
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.03.23 51单片机学习——第35节: [16-1] AD/DA 前言开发板说明引用解答和科普一、AD问题…...
算法-最大公约数
1、约数: 1.1 试除法求约数 原理:只需要遍历最小的约数即可,较大的那个可以直接算出来。 import java.util.*; public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {int t sc.nextIn…...
在 SaaS 应用上构建 BI 能力的实战之路
SaaS 产品在持续运营过程中积累了大量数据,这些数据不仅是数字的记录,更是洞察市场趋势、优化产品功能、提升用户体验的宝贵资源。 因此,大部分的 SaaS 产品在发展到一定阶段后,都会开始构建自己的报表模块或分析模块,…...
代码随想录刷题day51|(二叉树篇)654.最大二叉树
一、二叉树基础知识 详见:代码随想录刷题day34|(二叉树篇)二叉树的递归遍历-CSDN博客 二、递归思路 递归三部曲 构造树一般采用前序遍历,因为先构造中间节点,然后递归构造左子树和右子树; 1.递归函数参数…...
深入理解 C++11 智能指针:独占、共享与弱引用的完美管理
文章目录 std::unique_ptr(独占式智能指针)std::shared_ptr(共享式智能指针)std::weak_ptr(弱引用智能指针)示例展示:智能指针的原理内存泄漏**什么是内存泄漏,内存泄漏的危害****如…...
1.2 编译器结构
编译器具有模块化的高层结构。还可以将模块化进一步细化。编译器可以看成多个阶段构成的流水线结构。 一种没有优化的编译器结构 更复杂的编译器结构...
文件操作助手
文件操作助手 在我们实现一个大型项目时,往往会有一个公共模块,这个公共模块是公用的,里面可能会包含文件操作助手、字符串操作助手、时间戳操作助手… 而我们今天就来实现一个文件操作助手,里面包含的功能有: 判断…...
线段树与扫描线 —— 详解算法思想及其C++实现
目录 一、线段树(Segment Tree) 基本概念 结构 操作 示例代码 二、扫描线(Sweep Line) 基本概念 应用场景 示例代码(矩形面积并集) 三、总结 一、线段树(Segment Tree) 基本…...
Leetcode 刷题笔记1 图论part04
leetcode 110 字符串接龙 def judge(s1, s2):count 0for i in range(len(s1)):if s1[i] ! s2[i]:count 1return count 1if __name__ __main__:n int(input())begin_str, end_str map(str, input().split())if begin_str end_str:print(0)exit()strlist []for _ in ran…...
快速入手:Nacos融合SpringCloud成为注册配置中心
快速入手:Nacos融合SpringCloud成为注册配置中心 前言安装Nacos项目搭建添加配置启动类添加注解运行项目服务调用RestTemplate 模式FeignClient 模式 前言 Spring Cloud是一系列框架的集合,提供了微服务架构下的各种解决方案,如服务治理、配…...
others-rustdesk远程
title: others-rustdesk远程 categories: Others tags: [others, 远程] date: 2025-03-19 10:19:34 comments: false mathjax: true toc: true others-rustdesk远程, 替代 todesk 的解决方案 前篇 官方 服务器 - https://rustdesk.com/docs/zh-cn/self-host/rustdesk-server-o…...
go:前后端分离
1.前端代码 新建一个前端文件夹,在该文件夹下新建一个.html文件,写入自己的html代码。 前端搞定。 2.后端代码 其核心是挂载路由接受前端传来的数据核心代码如下: func main() { // 服务运行提示 fmt.Println("go web server is runn…...
lodash 学习笔记/使用心得
lodash 学习笔记/使用心得 简单记一下 lodash 的一点学习笔记使用心得,最近也是打算清理一下所有的 dead code,然后发现我们用了好多的 lodash 方法。对比了之前的写法,重新看了一下官方文档,再自己重新动手写了点 util 之后发现…...
网络爬虫【爬虫库request】
我叫不三不四,很高兴见到大家,欢迎一起学习交流和进步 今天来讲一讲爬虫 Requests是Python的一个很实用的HTTP客户端库,完全满足如今网络爬虫的需求。与Urllib对比,Requests不仅具备Urllib的全部功能;在开发使用上&…...
AI日报 - 2025年3月24日
🌟 今日概览(60秒速览) ▎🤖 AGI突破 | Lyra生物序列建模架构效率惊人 在100生物任务中达最优,推理速度提升高达12万倍 ▎💼 商业动向 | OpenAI用户破4亿,Meta与Reliance探讨AI合作 生态扩展与全…...
Android平台毫秒级低延迟HTTP-FLV直播播放器技术探究与实现
一、前言 在移动互联网蓬勃发展的今天,视频播放功能已成为众多Android应用的核心特性之一。面对多样化的视频格式和传输协议,开发一款高效、稳定的视频播放器是许多开发者追求的目标。FLV(Flash Video)格式,尽管随着H…...
动态规划——混合背包问题
动态规划——混合背包问题 混合背包问题01背包与完全背包的混合:完全背包与多重背包的混合:三种背包混合混合背包OJ汇总 混合背包问题 将01背包、完全背包、多重背包混合起来的背包问题。也就是说,有的物品只可以取一次(01背包&a…...
数据库操作练习
一.向heros表中新增一列信息,添加一些约束,并尝试查询一些信息 //向表中添加一列age信息 alter table heros add column age int;//id列添加主键约束,设置自增 alter table heros modify column id int auto_increment primary key;//name列…...
3.milvus索引-HNSW
索引作用 加速大型数据集上的查询。 向量字段,仅只能创建一个索引。 milvus支持的向量索引类型大部分使用 近似最近邻搜索算法。ANNS该算法的核心不局限于返回最准确的结果,而是仅搜索目标的邻居。ANNS通过在可接受的范围内牺牲准确性提高检索效率。 …...
算法基础——栈
一、栈的概念 栈是⼀种只允许在⼀端进⾏数据插⼊和删除操作的线性表。 进⾏数据插⼊或删除的⼀端称为栈顶,另⼀端称为栈底。不含元素的栈称为空栈。进栈就是往栈中放⼊元素,出栈就是将元素弹出栈顶。 二、栈的模拟实现 1. 创建 本质还是线性表&#…...
开发语言漫谈-groovy
groovy是一门脚本语言,在前期的脚本语言中简单介绍了下。现在再深入介绍下,因为它是本平台上选用的脚本语言。所谓脚本语言就是不用编译,直接执行。这种特色非常适合做嵌入编程,即编即用。我们知道平台后台的业务开发语言是Java&a…...
ArkUI-List组件
列表是一个复杂的容器,当列表项达到一定数量,使得列表内容超出其范围的时候,就会自动变为可以滚动。列表适合用来展现同类数据类型。 List组件支持使用,条件渲染,循环渲染,懒加载等渲染控制方式生成子组件…...
数据仓库的 DWD 分层架构:构建高效数据平台的基石
在数据驱动的时代,数据仓库(Data Warehouse)作为企业数据分析的核心基础设施,扮演着至关重要的角色。而数据仓库的分层设计,则是确保数据高效流转、提升数据质量、支持复杂分析的关键。本文将深入探讨数据仓库的 DWD 分…...
山东大学数据结构课程设计
题目:全国交通咨询模拟系统 问题描述 处于不同目的的旅客对交通工具有不同的要求。例如,因公出差的旅客希望在旅途中的时间尽可能地短,出门旅游的旅客则期望旅费尽可能省,而老年旅客则要求中转次数最少。编织一个全国城市间的交…...
动态规划-01背包
兜兜转转了半天,发现还是Carl写的好。 看过动态规划-基础的读者,大概都清楚。 动态规划是将大问题,分解成子问题。并将子问题的解储存下来,避免重复计算。 而背包问题,就是动态规划延申出来的一个大类。 而01背包&…...
【2025】基于node.js的中医药科普平台的设计与实现(源码、万字文档、图文修改、调试答疑)
项目完整功能以演示视频为准 基于Node.js的中医药科普平台的设计与实现功能结构图如下 课题背景 随着人们健康意识的提高,中医药作为传统医学的重要组成部分,越来越受到关注。然而,中医药知识专业性强,普通大众获取准确、全面的中…...
基于Flux模型的多模态可控图像生成工作流实践
一、技术框架与模型选型 当前图像生成领域对多模态控制与一致性保持的需求日益增强,本文将基于Black Forest Labs推出的Flux.1模型,结合ControlNet的循环一致性优化技术,构建一套融合Canny边缘检测与深度图(Depth)控制…...
缓存过期时间之逻辑过期
1. 物理不过期(Physical Non-Expiration) 定义:在Redis中不设置EXPIRE时间,缓存键永久存在(除非主动删除或内存淘汰)。目的:彻底规避因缓存自动过期导致的击穿(单热点失效ÿ…...
JVM类加载过程详解
文章目录 前言1.加载2.链接验证文件格式验证元数据验证字节码验证符号引用验证 准备解析 3.初始化4.类卸载 前言 类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段:加载(Loading)、验证&a…...
第三十二篇 深入解析Kimball维度建模:构建企业级数据仓库的完整框架
目录 一、维度建模设计原则深度剖析1.1 业务过程驱动设计1.2 星型模式VS雪花模式 二、维度建模五步法实战(附完整案例)2.1 业务需求映射2.2 模型详细设计2.3 缓慢变化维处理 三、高级建模技术解析3.1 渐变维度桥接表3.2 快照事实表设计 四、性能优化体系…...
WPF 布局中的共性尺寸组(Shared Size Group)
1. 什么是共性尺寸组? 在 WPF 的 Grid 布局中,SharedSizeGroup 允许多个 Grid 共享同一列或行的尺寸,即使它们属于不同的 Grid 也能保持大小一致。这样可以保证界面元素的对齐性,提高布局的一致性。 SharedSizeGroup 主要用于需…...
19 数码管的动态显示
1、八段数码管 八段数码管 是一个 “ 8 ” 字型数码管,分为八段,a b c d e f g dp,其中dp为小数点。每一段为一个发光二极管,这样的 8 段称为 段选信号 。 2、实验 1、实验目标:让六位数码管 从 0 开始记数࿰…...
pytorch 笔记:张量索引的维度扩展规则
1 基本原理 在PyTorch中,张量索引的维度扩展规则遵循以下原则: 索引操作的核心规则: 当使用索引数组访问张量时: 索引数组的每个元素对应选取原张量的一个子张量结果形状 索引数组形状 原张量剩余维度形状 这么说可能不清…...
课外活动:怎么理解可变成本?
可变成本深度解析 🧮 一、可变成本的本质 #mermaid-svg-qoqQaFxQBuZZfAD2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qoqQaFxQBuZZfAD2 .error-icon{fill:#552222;}#mermaid-svg-qoqQaFxQBuZZfAD2 …...
深入理解 JVM 的垃圾收集器:CMS、G1、ZGC
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...