Denoising Diffusion Implicit Models (DDIM)

因为扩散模型的正向过程可以实现跳步,其马尔科夫性并不重要,因此DDIM尝试在反向过程中也舍弃马尔科夫性的约束。在引入一个可控参数 σ t \sigma_t σt后,反向过程的迭代被整理为预测 x 0 x_0 x0后重新进行正向扩散的过程,扩散时使用的噪声为新初始化噪声与上一步预测噪声的加权,在特定 σ \sigma σ选择下,可以导出DDPM的采样过程和新的确定性的采样过程,并且使得反向过程同样支持跳步。

方法概述

舍弃马尔科夫性

在DDPM中,反向过程的损失函数是根据马尔科夫性推导得出的,而虽然正向过程也是马尔科夫链,但是因为高斯分布的可加性,其完全可以舍弃马尔科夫性,实现从第 0 步直接跳到第 t 步。
在这里插入图片描述
而DDIM的核心思想就是在反向过程时也舍弃马尔科夫性的约束,使得采样的过程也可以实现跳步。
在这里插入图片描述
注意,DDIM的 p p p q q q符号也与本文相反,在“理论推导”小节需要注意与原文对照。

采样公式

在DDPM中,我们先是使用了一种没有严格理论支撑但容易理解的方法导出了一个采样迭代公式:
x t − 1 = 1 α t ( x t − 1 − α ˉ t ϵ θ ( x t , t ) ) + 1 − α ˉ t − 1 z x_{t-1} = \frac{1}{\sqrt{\alpha_t}}\left(x_t-\sqrt{1-\bar{\alpha}_{t}} \epsilon_\theta\left( x_t, t\right)\right) + \sqrt{1-\bar{\alpha}_{t-1}} z xt1=αt 1(xt1αˉt ϵθ(xt,t))+1αˉt1 z
然后又在后续理论推导出中给出了DDPM原版的采样迭代公式:
x t − 1 = 1 α t ( x t − 1 − α t 1 − α ˉ t ϵ θ ( x t , t ) ) + β ~ t z x_{t-1}=\frac{1}{\sqrt{\alpha_{t}}}\left(x_{t}-\frac{1-\alpha_{t}}{\sqrt{1-\bar{\alpha}_{t}}}\epsilon_{\theta}(x_{t},t)\right)+\tilde{\beta}_tz xt1=αt 1(xt1αˉt 1αtϵθ(xt,t))+β~tz
而这两种都是DDIM这个工作提出的采样迭代公式的两种特殊情况:
x t − 1 = α ˉ t − 1 ( x t − 1 − α ˉ t ϵ θ ( x t , t ) α ˉ t ) + 1 − α ˉ t − 1 − σ t 2 ⋅ ϵ θ ( x t , t ) + σ t z x_{t-1}=\sqrt{\bar\alpha_{t-1}}\left(\frac{x_{t}-\sqrt{1-\bar\alpha_{t}}\epsilon_{\theta}(x_{t},t)}{\sqrt{\bar\alpha_{t}}}\right)+\sqrt{1-\bar\alpha_{t-1}-\sigma_{t}^{2}}\cdot\epsilon_{\theta}(x_{t},t)+\sigma_{t}z xt1=αˉt1 (αˉt xt1αˉt ϵθ(xt,t))+1αˉt1σt2 ϵθ(xt,t)+σtz
带入 σ t = 1 − α ˉ t − 1 \sigma_{t}=\sqrt{1-\bar\alpha_{t-1}} σt=1αˉt1 σ t = ( 1 − α ˉ t − 1 ) / ( 1 − α ˉ t ) 1 − α t \sigma_{t}=\sqrt{(1-\bar\alpha_{t-1})/(1-\bar\alpha_{t})}\sqrt{1-\alpha_{t}} σt=(1αˉt1)/(1αˉt) 1αt 可以分别得到以上两个迭代过程。为了便于分析和与DDIM原文对齐,这里将上式的 α ˉ t \bar\alpha_t αˉt表示为 α t \alpha_t αt,上式的 α t \alpha_t αt则对应 α t / α t − 1 \alpha_t/\alpha_{t-1} αt/αt1,将 t t t移到符号上标, z z z替换为 ϵ t \epsilon_t ϵt
x t − 1 = α t − 1 ( x t − 1 − α t ϵ θ ( t ) ( x t ) α t ) + 1 − α t − 1 − σ t 2 ⋅ ϵ θ ( t ) ( x t ) + σ t ϵ t x_{t-1}=\sqrt{\alpha_{t-1}}{\left(\frac{x_{t}-\sqrt{1-\alpha_{t}}\epsilon_{\theta}^{(t)}(x_{t})}{\sqrt{\alpha_{t}}}\right)}+{\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\cdot\epsilon_{\theta}^{(t)}(x_{t})}+{\sigma_{t}\epsilon_{t}} xt1=αt1 (αt xt1αt ϵθ(t)(xt))+1αt1σt2 ϵθ(t)(xt)+σtϵt
此时可以得到DDIM最重要的特殊情况,即设置 σ t = 0 \sigma_t=0 σt=0,此时上式等于:
x t − 1 = α t − 1 ( x t − 1 − α t ϵ θ ( t ) ( x t ) α t ) + 1 − α t − 1 ⋅ ϵ θ ( t ) ( x t ) = α t − 1 x θ ( 0 ) ( x t ) + 1 − α t − 1 ⋅ ϵ θ ( t ) ( x t ) x_{t-1}=\sqrt{\alpha_{t-1}}\left(\frac{x_{t}-\sqrt{1-\alpha_{t}}\epsilon_{\theta}^{(t)}(x_{t})}{\sqrt{\alpha_{t}}}\right)+\sqrt{1-\alpha_{t-1}}\cdot\epsilon_{\theta}^{(t)}(x_{t})=\sqrt{\alpha_{t-1}}x^{(0)}_\theta(x_t)+\sqrt{1-\alpha_{t-1}}\cdot\epsilon_{\theta}^{(t)}(x_{t}) xt1=αt1 (αt xt1αt ϵθ(t)(xt))+1αt1 ϵθ(t)(xt)=αt1 xθ(0)(xt)+1αt1 ϵθ(t)(xt)
可以发现,此时DDIM在迭代过程中没有随机性,即每一步反向过程迭代的时候并没有采样新的噪声,而是直接使用前向过程 x t = α t x 0 + 1 − α t ϵ \boldsymbol{x}_t =\sqrt{{\alpha}_t} \boldsymbol{x}_0 + \sqrt{1-{\alpha}_t} {\epsilon} xt=αt x0+1αt ϵ在估计的干净图像 x θ ( 0 ) ( x t ) x^{(0)}_\theta(x_t) xθ(0)(xt)上回加估计的噪声 ϵ θ ( t ) ( x t ) \epsilon_{\theta}^{(t)}(x_{t}) ϵθ(t)(xt),可以看作一个迭代细化的过程。当然,DDIM采样并不是完全没有随机性,因为迭代前需要采样 x T ∼ N ( 0 , I ) x_T\sim\mathcal{N}(\boldsymbol{0}, \boldsymbol{I}) xTN(0,I)

加速采样

对于DDPM,如果要贯彻推导时使用的马尔科夫性,那么在采样时需要使用训练时设置的 T T T步进行采样,而在绝大部分扩散模型中,都设置 T = 1000 T=1000 T=1000,这导致DDPM生成图像需要执行1000次去噪网络 ϵ θ \epsilon_\theta ϵθ,而 ϵ θ \epsilon_\theta ϵθ是一个参数量和计算量都很大的UNet(甚至是DiT),导致耗时不可接受,因此减少采样步数是必不可少的。
一个简单的方法是,在训练时依旧使用1000步 t ∈ { 0 , 1 , 2 , . . . , 999 } t\in \{0, 1, 2, ..., 999\} t{0,1,2,...,999},但在采样时只使用timestep的子集,比如 t ∈ { 249 , 499 , 749 , 999 } t\in \{249, 499, 749, 999\} t{249,499,749,999},并索引训练时计算好的 α t \alpha_{t} αt列表,实验证明,这种跳步方法在50步左右依旧可以生成清晰的图像。DDIM将timestep的子序列定义为 { τ 1 , … , τ S } \{\tau_{1},\ldots,\tau_{S}\} {τ1,,τS},并一般设置为等间隔。此时生成过程为:
z = x T → x τ S → x τ S − 1 → ⋯ → x τ 1 → x 0 = x {z} = {x}_{T} \to {x}_{\tau_{S}} \to {x}_{\tau_{S-1}} \to \cdots \to {x}_{\tau_{1}} \to {x}_{0} = {x} z=xTxτSxτS1xτ1x0=x
此外,DDIM将 σ t \sigma_{t} σt定义为:
σ τ i ( η ) = η ( 1 − α τ i − 1 ) / ( 1 − α τ i ) 1 − α τ i / α τ i − 1 \sigma_{\tau_{i}}(\eta)=\eta\sqrt{(1-\alpha_{\tau_{i-1}})/(1-\alpha_{\tau_{i}})}\sqrt{1-\alpha_{\tau_{i}}/\alpha_{\tau_{i-1}}} στi(η)=η(1ατi1)/(1ατi) 1ατi/ατi1
其中 η ∈ [ 0 , 1 ] \eta\in{[0, 1]} η[0,1] η = 0 \eta=0 η=0时对应确定性的反向迭代过程, η = 1 \eta=1 η=1对应DDPM。如果不特指 η \eta η的值,DDIM默认采用确定性采样,一般采样步数在20~30步,并且一般质量比DDPM更好。

理论推导

反向过程的非马尔可夫推断

回顾DDPM的简化训练目标:
L = E t , x 0 , ϵ [ ∥ ϵ − ϵ θ ( t ) ( α t x 0 + 1 − α t ϵ ) ∥ 2 ] L=\mathbb{E}_{t, {x}_0, {\epsilon}}\left[\left\|{\epsilon}-{\epsilon}_\theta^{(t)}\left(\sqrt{{\alpha}_t} {x}_0 + \sqrt{1-{\alpha}_t} {\epsilon}\right)\right\|^2\right] L=Et,x0,ϵ[ ϵϵθ(t)(αt x0+1αt ϵ) 2]
该损失函数关于 t t t的每一项,都只与 x 0 x_0 x0以及 x t x_t xt相关,而且根据 x 0 = 1 α t ( x t − 1 − α t ϵ ) {x}_0=\frac{1}{\sqrt{{\alpha}_t}}\left({x}_t-\sqrt{1-{\alpha}_t} {\epsilon}\right) x0=αt 1(xt1αt ϵ),上式等价于每一步都估计干净图像 x 0 x_0 x0,只是在 t t t越大时估计越不准确。因此,只需要在采样到达 t t t步时 x t x_t xt包含的噪声的方差与训练时正向过程添加的噪声方差一致,那么训练和推理就不会有明显的gap。对于正向过程,正向过程扩散到 x t − 1 x_{t-1} xt1 p ( x t − 1 ∣ x 0 ) = N ( x t − 1 ; α t − 1 x 0 , ( 1 − α t − 1 ) I ) p({x}_{t-1}|{x}_{0})=\mathcal{N}({x}_{t-1};\sqrt{{\alpha}_{t-1}} {x}_{0}, (1-{\alpha}_{t-1})\boldsymbol{I}) p(xt1x0)=N(xt1;αt1 x0,(1αt1)I),即方差为 1 − α t − 1 1-{\alpha}_{t-1} 1αt1。因为我们在 t t t步估计出 x ^ 0 ( t ) = 1 α t ( x t − 1 − α t ϵ θ ( t ) ( x ^ t ) ) \hat{x}_0^{(t)}=\frac{1}{\sqrt{{\alpha}_t}}\left({x}_t-\sqrt{1-{\alpha}_t} {\epsilon}_\theta^{(t)}(\hat{x}_t)\right) x^0(t)=αt 1(xt1αt ϵθ(t)(x^t)),迭代采样过程中会替代正向过程的 x 0 x_0 x0,因此我们只需要在 x ^ 0 ( t ) \hat{x}_0^{(t)} x^0(t)上添加方差为 1 − α t − 1 1-{\alpha}_{t-1} 1αt1即可满足反向过程的状态转移,而无需考虑状态转移是否满足马尔科夫性。因此可以引入一个可调的辅助变量 σ t \sigma_t σt
ϵ ( t ) = 1 − α t − 1 − σ t 2 ⋅ ϵ θ ( t ) ( x t ) + σ t ϵ t \epsilon^{(t)}=\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\cdot\epsilon_{\theta}^{(t)}(x_{t})+\sigma_{t}\epsilon_{t} ϵ(t)=1αt1σt2 ϵθ(t)(xt)+σtϵt
很明显, ( 1 − α t − 1 − σ t 2 ) 2 + σ t 2 = 1 − α t − 1 \left(\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\right)^2+\sigma_{t}^2=1-{\alpha}_{t-1} (1αt1σt2 )2+σt2=1αt1,满足训练时噪声方差的设定。

边缘分布

DDIM原文并不是直接从噪声方差的训练-推断一致的角度进行推导的,而是从边缘分布 p σ ( x t ) p_\sigma({x}_t) pσ(xt)的一致性考虑。因为 x 0 ∼ p d a t a x_0\sim p_{data} x0pdata不受参数 σ \sigma σ影响,则只需证明参数 σ \sigma σ不影响条件分布 p σ ( x t ∣ x 0 ) p_\sigma({x}_t|{x}_0) pσ(xtx0),即:
p σ ( x t ∣ x 0 ) = N ( α t x 0 , ( 1 − α t ) I ) p_\sigma({x}_t|{x}_0)=\mathcal N(\sqrt{\alpha_t}{x}_0,(1-\alpha_t){I}) pσ(xtx0)=N(αt x0,(1αt)I)
接下来开始证明:考虑DDPM的训练过程,其最小化 p ( x t − 1 ∣ x t , x 0 ) p({x}_{t-1}|{x}_{t},{x}_{0}) p(xt1xt,x0) q θ ( x t − 1 ∣ x t ) q_\theta(x_{t-1}|x_t) qθ(xt1xt)的KL散度,训练完成后可以使用 q θ ( x t − 1 ∣ x t ) q_\theta(x_{t-1}|x_t) qθ(xt1xt)替代 p ( x t − 1 ∣ x t , x 0 ) p({x}_{t-1}|{x}_{t},{x}_{0}) p(xt1xt,x0)。当前,我们的反向过程迭代定义为:
x t − 1 = α t − 1 ( x t − 1 − α t ϵ θ ( t ) ( x t ) α t ) + 1 − α t − 1 − σ t 2 ⋅ ϵ θ ( t ) ( x t ) + σ t ϵ t x_{t-1}=\sqrt{\alpha_{t-1}}{\left(\frac{x_{t}-\sqrt{1-\alpha_{t}}\epsilon_{\theta}^{(t)}(x_{t})}{\sqrt{\alpha_{t}}}\right)}+{\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\cdot\epsilon_{\theta}^{(t)}(x_{t})}+{\sigma_{t}\epsilon_{t}} xt1=αt1 (αt xt1αt ϵθ(t)(xt))+1αt1σt2 ϵθ(t)(xt)+σtϵt
其中 x ^ 0 = x t − 1 − α t ϵ θ ( t ) ( x t ) α t \hat{x}_0=\frac{x_{t}-\sqrt{1-\alpha_{t}}\epsilon_{\theta}^{(t)}(x_{t})}{\sqrt{\alpha_{t}}} x^0=αt xt1αt ϵθ(t)(xt)可近似 x 0 x_0 x0,那么:
p σ ( x t − 1 ∣ x t , x 0 ) = N ( α t − 1 x 0 + 1 − α t − 1 − σ t 2 ⋅ x t − α t x 0 1 − α t , σ t 2 I ) p_{\sigma}({x}_{t-1}|{x}_{t},{x}_{0})=\mathcal{N}\left(\sqrt{\alpha_{t-1}}{x}_{0}+\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\cdot\frac{{x}_{t}-\sqrt{\alpha_{t}}{x}_{0}}{\sqrt{1-\alpha_{t}}},\sigma_{t}^{2}\boldsymbol{I}\right) pσ(xt1xt,x0)=N(αt1 x0+1αt1σt2 1αt xtαt x0,σt2I)
上式可表示为 x t − 1 = α t − 1 x 0 + 1 − α t − 1 − σ t 2 ⋅ x t − α t x 0 1 − α t + σ t ϵ t x_{t-1}=\sqrt{\alpha_{t-1}}x_0+{\sqrt{1-\alpha_{t-1}-\sigma_{t}^{2}}\cdot\frac{{x}_{t}-\sqrt{\alpha_{t}}{x}_{0}}{\sqrt{1-\alpha_{t}}}}+{\sigma_{t}\epsilon_{t}} xt1=αt1 x0+1αt1σt2 1αt xtαt x0+σtϵt。考虑 p σ ( x t ∣ x 0 ) = N ( α t x 0 , ( 1 − α t ) I ) = α t x 0 + 1 − α t ϵ , ϵ ∼ N ( 0 , I ) p_{\sigma}(x_{t}|x_{0})=\mathcal{N}(\sqrt{\alpha_{t}}x_{0},(1-\alpha_{t}){I})=\sqrt{\alpha_{t}}x_{0}+\sqrt{1-\alpha_{t}}\epsilon, \epsilon\sim \mathcal{N}(\boldsymbol{0},\boldsymbol{I}) pσ(xtx0)=N(αt x0,(1αt)I)=αt x0+1αt ϵ,ϵN(0,I),则 p σ ( x t − 1 ∣ x 0 ) p_\sigma({x}_{t-1}|{x}_0) pσ(xt1x0)的均值和方差:
μ t − 1 = α t − 1 x 0 + 1 − α t − 1 − σ t 2 ⋅ α t x 0 − α t x 0 1 − α t = α t − 1 x 0 σ t − 1 = σ t 2 I + 1 − α t − 1 − σ t 2 1 − α t ( 1 − α t ) I = ( 1 − α t − 1 ) I \begin{aligned} \mu_{t-1} &=\sqrt{\alpha_{t-1}}{x}_0+\sqrt{1-\alpha_{t-1}-\sigma_t^2}\cdot\frac{\sqrt{\alpha_t}{x}_0-\sqrt{\alpha_t}{x}_0}{\sqrt{1-\alpha_t}} =\sqrt{\alpha_{t-1}}x_{0} \\ \sigma_{t-1}&=\sigma_t^2\boldsymbol{I}+\frac{1-\alpha_{t-1}-\sigma_t^2}{1-\alpha_t}(1-\alpha_t)\boldsymbol{I}=(1-\alpha_{t-1})\boldsymbol{I} \end{aligned} μt1σt1=αt1 x0+1αt1σt2 1αt αt x0αt x0=αt1 x0=σt2I+1αt1αt1σt2(1αt)I=(1αt1)I
p σ ( x t − 1 ∣ x 0 ) = N ( α t − 1 x 0 , ( 1 − α t − 1 ) I ) p_\sigma({x}_{t-1}|{x}_0)=\mathcal N(\sqrt{\alpha_{t-1}}{x}_0,(1-\alpha_{t-1}){I}) pσ(xt1x0)=N(αt1 x0,(1αt1)I),与 p σ ( x t ∣ x 0 ) = N ( α t x 0 , ( 1 − α t ) I ) p_\sigma({x}_t|{x}_0)=\mathcal N(\sqrt{\alpha_t}{x}_0,(1-\alpha_t){I}) pσ(xtx0)=N(αt x0,(1αt)I)一致。
因此,只要 q θ ( x t − 1 ∣ x t ) q_\theta(x_{t-1}|x_t) qθ(xt1xt)可以很好地近似 p ( x t − 1 ∣ x t , x 0 ) p({x}_{t-1}|{x}_{t},{x}_{0}) p(xt1xt,x0),那么DDIM的转移过程与DDPM共享相同的边缘分布。DDIM原文使用与DDPM相似的变分推导来更严谨地导出了该结论,有兴趣可以阅读DDIM附录。

加速采样

当设定采样子序列为 { τ 1 , … , τ S } \{\tau_{1},\ldots,\tau_{S}\} {τ1,,τS}时,对应的前向过程为:
p τ ( x 1 : T ∣ x 0 ) = p τ ( x τ S ∣ x 0 ) ∏ i = 1 S p τ ( x τ i − 1 ∣ x τ i , x 0 ) ∏ t ∈ τ ˉ p τ ( x t ∣ x 0 ) p_{\tau}(x_{1:T}|x_{0})=p_{\tau}(x_{\tau_{S}}|x_{0})\prod_{i=1}^{S}p_{\tau}(x_{\tau_{i-1}}|x_{\tau_{i}},x_{0})\prod_{t\in\bar{\tau}}p_{\tau}(x_{t}|x_{0}) pτ(x1:Tx0)=pτ(xτSx0)i=1Spτ(xτi1xτi,x0)tτˉpτ(xtx0)
对应的反向过程为:
q θ ( x 0 : T ) : = q θ ( x T ) ∏ i = 1 S q θ ( τ i ) ( x τ i − 1 ∣ x τ i ) × ∏ t ∈ τ ˉ q θ ( t ) ( x 0 ∣ x t ) q_\theta({x}_{0:T}):=q_\theta({x}_T)\prod_{i=1}^Sq_\theta^{(\tau_i)}({x}_{\tau_{i-1}}|{x}_{\tau_i})\times\prod_{t\in\bar{\tau}}q_\theta^{(t)}({x}_0|{x}_t) qθ(x0:T):=qθ(xT)i=1Sqθ(τi)(xτi1xτi)×tτˉqθ(t)(x0xt)
上式乘号的右半部分实际对应训练时的去噪损失,它与反向过程的迭代过程本身没有关系,当在完整的timestep序列上训练后,这部分得到良好定义。左半部分的单项则是一个与 θ \theta θ无直接关联的项:
q θ ( τ i ) ( x τ i − 1 ∣ x τ i ) = p τ ( x τ i − 1 ∣ x τ i , x ^ 0 ( τ i ) ( x τ i − 1 ) ) q_{\theta}^{(\tau_{i})}(x_{\tau_{i-1}}|x_{\tau_{i}})=p_{\tau}(x_{\tau_{i-1}}|x_{\tau_{i}},\hat{x}_0^{(\tau_{i})}(x_{\tau_{i-1}})) qθ(τi)(xτi1xτi)=pτ(xτi1xτi,x^0(τi)(xτi1))
因此只要在完整timestep上训练,那么在任意子序列上推断都是受到良好约束的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/70998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LearnOpenGL之Shader编程用算法绘画

———————————————————— 前序 ——————————————————— AndroidLearnOpenGL是本博主自己实现的LearnOpenGL练习集合: Github地址:GitHub - wangyongyao1989/AndroidLearnOpenGL: OpenGL基础及运用 系列文章&#xff…

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_buf_t

ngx_buf_t 定义在 src/core/ngx_buf.h typedef struct ngx_buf_s ngx_buf_t;struct ngx_buf_s {u_char *pos;u_char *last;off_t file_pos;off_t file_last;u_char *start; /* start of buffer */u_char …

第5章_管理策略

管理策略 如前所述,策略定义了在授予对对象的访问权限之前必须满足的条件。 单击 Policy (策略) 选项卡可查看与资源服务器关联的所有策略。 在此选项卡上,您可以查看以前创建的策略列表,以及创建和编辑策略。 要创…

Chromium_src源码

Chromium_src源码 码云上有一个OpenHarmony-TPC/chromium_src项目,目前已经停止维护了,迁移到GitCode上了,源代码项目地址为:openharmony-tpc/chromium_chrome 特此记录一下老的项目的相关软件架构 Chromium 简介 软件架构 软…

Android ObjectBox数据库使用与集成指南

ObjectBox其核心特点ObjectBox与 SQLite 和 Realm 的对比Android集成ObjectBox创建ObjectBox实体对象创建ObjectBox操作管理类OBManager在Application初始化ObjectBox插入或更新数据查询数据统计数据分页数据查询删除数据总结今天分享一套Android另一个数据库ObjectBox。Object…

JAVA调用Deepseek的api,完成基本对话

一、准备工作 注册账号 访问 DeepSeek 官网(如 https://www.deepseek.com/)或对应平台。完成注册并登录,部分服务可能需要企业认证或申请权限。 获取 API 密钥(如使用 API) 进入控制台或开发者页面,创建…

013作用域

一、基本概念 C语言中,标识符都有一定的可见范围,这些可见范围保证了标识符只能在一个有限的区域内使用,这个可见范围,被称为作用域(scope)。 软件开发中,尽量缩小标识符的作用域是一项基本原…

AH表情捕捉设备:虚拟人动态表情捕捉

在虚拟人应用里,除了关注虚拟人能否展现流畅的肢体动作,其表情是否自然流畅同样关键。虚拟人作为新兴技术产物,广泛应用于娱乐直播、影视动画等领域。自然的表情能让虚拟人更具亲和力与真实感,大幅提升用户体验。 而广州虚拟动力…

pikachu

暴力破解 基于表单的暴力破解 【2024版】最新BurpSuit的使用教程(非常详细)零基础入门到精通,看一篇就够了!让你挖洞事半功倍!_burpsuite使用教程-CSDN博客 登录页面,随意输入抓包,发送到攻击…

az devops login报错:Failed to authenticate using the supplied token.

PowerShell,az devops login报错: Failed to authenticate using the supplied token. 检查了一下PAT token是对的。 检查命令: az devops login --organization https://dev.azure.com/xxxxxxxx/ 乍一看好像没问题问题,然后想…

C++预编译、编译、汇编、链接详解

一、准备阶段 g编译环境&#xff0c;配置好环境变量 新建一个helloworld.cpp #include <iostream> using namespace std; int main() {cout << "Hello, world!" << endl;return 0; }命令查看 g --help 二、预编译 预处理阶段对自定义和预定义…

docker使用代理的简单配置

1准备代理服务器 准备代理服务器&#xff0c;例如192.168.120.168:52209 配置docker.service文件 查看service文件的位置 systemctl status docker 编辑service文件 vim /usr/lib/systemd/system/docker.service 添加代理配置 ... [Service] Environment"HTTP_PROXY…

【FL0090】基于SSM和微信小程序的球馆预约系统

&#x1f9d1;‍&#x1f4bb;博主介绍&#x1f9d1;‍&#x1f4bb; 全网粉丝10W,CSDN全栈领域优质创作者&#xff0c;博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发…

使用esp32接入大模型(http请求)

本示例适用于所有乐鑫的esp32模组及开发板。使用串口通信和http协议。实现简单的和大模型对话要求。 话不多说直接上代码 #include <WiFi.h> #include <HTTPClient.h> #include <ArduinoJson.h>#define DEBUG 1// 替换为你的Wi-Fi网络凭据 #define WLAN_SSI…

GitHub高效搜索工具

[GitHub项目搜索工具] 一款开发者专属的星矿探测仪&#xff01; 你是否还在用stars:>1000手动筛选GitHub项目&#xff1f; 你是否经常为了找一个合适的开源库翻遍搜索结果&#xff1f; 这个工具或许能改变你的代码资源发掘方式… &#x1f31f; 痛点洞察 在GitHub的3.28亿个…

Windows Qt开发到底选MSVC编译还是MinGW编译?

Qt Windows开发编译器选择深度解析&#xff1a;MSVC与MinGW全面对比 一、编译器背景与核心定位 1.1 MSVC&#xff1a;微软生态的深度整合者 MSVC&#xff08;Microsoft Visual C&#xff09;是微软官方推出的C编译器套件&#xff0c;通常与Visual Studio开发环境深度绑定。作…

【解决】OnTriggerEnter/OnTriggerExit 调用匿名委托误区的问题

开发平台&#xff1a;Unity 开发语言&#xff1a;CSharp 6.0 开发工具&#xff1a;Visual Studio 2022   问题背景 public void OnTriggerEnter(Collider collider) {output.OnInteractionNoticed () > OnInteractionTriggered?.Invoke(); }public void OnTriggerExit(C…

【uniapp原生】实时记录接口请求延迟,并生成写入文件到安卓设备

在开发实时数据监控应用时&#xff0c;记录接口请求的延迟对于性能分析和用户体验优化至关重要。本文将基于 UniApp 框架&#xff0c;介绍如何实现一个实时记录接口请求延迟的功能&#xff0c;并深入解析相关代码的实现细节。 前期准备&必要的理解 1. 功能概述 该功能的…

支付宝 IoT 设备入门宝典(下)设备经营篇

上篇介绍了支付宝 IoT 设备管理&#xff0c;但除了这些基础功能外&#xff0c;商户还可以利用设备进行一些运营动作&#xff0c;让设备更好的帮助自己&#xff0c;本篇就会以设备经营为中心&#xff0c;介绍常见的设备相关能力和问题解决方案。如果对上篇感兴趣&#xff0c;可以…

通过查询hive的元数据库中的表分区清单,拼写出来删除表分区的sql脚本

以下是通过直接查询Hive元数据库生成分区删除SQL的脚本方案&#xff0c;支持MySQL/PostgreSQL元数据库类型&#xff0c;已考虑安全性和性能优化&#xff1a; #!/bin/bash # 脚本名称&#xff1a;metastore_drop_partitions.sh # 描述&#xff1a;通过Hive元数据库生成分区删除…