Stable Diffusion系列(五):原理剖析——从文字到图片的神奇魔法(扩散篇)

文章目录

    • DDPM
      • 论文整体原理
      • 前向扩散过程
      • 反向扩散过程
      • 模型训练过程
      • 模型生成过程
      • 概率分布视角
      • 参数模型设置
      • 论文结果分析

要想完成SD中从文字到图片的操作,必须要做到两步,第一步是理解文字输入包含的语义,第二步是利用语义引导图片的生成。下面我们从几篇论文入手,首先搞懂以假乱真的图片是如何生成的,再学会对自然语言的理解方式,也就弄懂了文生图的魔法是从何而来。最后,我们会看看SDXL、Control Net、Turbo以及LCM等变种分别是从哪些角度为SD锦上添花的。这里我们先从扩散讲起。

DDPM

这是解开图片生成之谜的第一把钥匙,原文是发表于NIPS2020的Denoising Diffusion Probabilistic Models,下面我们就如庖丁解牛般,尝试洞察里面的每一丝细节。

论文整体原理

先从标题说起,很久没有看到过这么简明扼要的论文名了,用三个词就完美概括了DDPM的核心思想,去噪(Denoising)是方法、扩散(Diffusion)是架构、概率(Probabilistic)是媒介。至于目的,当然是去生成以假乱真的图片。

图片生成不是什么新鲜事,VAE和GAN都是曾经的研究宠儿,它们在生成图片时都需要一步解压的操作,也就是从低维空间中获得关于图片的表征或概率分布,再使用解码器或生成器映射到高维的图片空间。而概率扩散可以被视为一个马尔科夫过程,马尔科夫链中不论是状态矩阵还是转移矩阵的大小都是固定的,因此扩散在一个固定的维度下进行,二者的区别如下:

在这里插入图片描述

其在数学上的整体过程如下图所示:

在这里插入图片描述
可以看出,这条链是双向的。从右到左称之为前向扩散,是一个逐渐给原始图片加入噪音的过程;从左到右是反向,也就是从噪音生成原始图片,也是DDPM图片生成能力的来源。

前向扩散过程

前向过程其实就是一个逐步给图片加噪音的过程,每一步都为原始图片加一点随机采样后的高斯噪声
在这里插入图片描述
具体来说,其加噪的公式如下,从原图 x 0 x_{0} x0按照系数 β t \beta_t βt开始一步步加入噪声 ϵ t \epsilon_t ϵt
x t = β t × ϵ t + 1 − β t × x t − 1 \begin{equation} x_t=\sqrt{\beta_t} \times \epsilon_t+\sqrt{1-\beta_t} \times x_{t-1} \\ \end{equation} xt=βt ×ϵt+1βt ×xt1
其中 ϵ t \epsilon_t ϵt是符合标准正态分布的噪声, β t \beta_t βt是预先定义的一组超参数,数值逐渐增大以模拟扩散过程的不断加速
ϵ t ∼ N ( 0 , 1 ) 0 < β 1 < β 2 < β 3 < β t − 1 < β t < 1 \begin{align} \epsilon_t &\sim N(0,1) \\ 0<\beta_1 &< \beta_2 < \beta_3 < \beta_{t-1} < \beta_t < 1 \end{align} ϵt0<β1N(0,1)<β2<β3<βt1<βt<1
上面的公式描述了单步迭代的过程,理论上,既然每一步的公式是固定的,那我们应该能求导出一步到位的公式,也就是如何从原图 x 0 x_{0} x0直接得到 x t x_{t} xt。为了简化计算,令 α t = 1 − β t \alpha_t = 1-\beta_t αt=1βt,单步迭代的过程重写为:
x t = 1 − α t × ϵ t + α t × x t − 1 \begin{equation} x_t=\sqrt{1-\alpha_t} \times \epsilon_t+\sqrt{\alpha_t} \times x_{t-1} \\ \end{equation} xt=1αt ×ϵt+αt ×xt1
其上一步的结果可以写为:
x t − 1 = 1 − α t − 1 × ϵ t − 1 + α t − 1 × x t − 2 \begin{equation} x_{t-1}=\sqrt{1-\alpha_{t-1}} \times \epsilon_{t-1}+\sqrt{\alpha_{t-1}} \times x_{t-2} \\ \end{equation} xt1=1αt1 ×ϵt1+αt1 ×xt2
将式(5)代入式(4)后得:
x t = a t ( 1 − a t − 1 ) ϵ t − 1 + 1 − a t × ϵ t + a t a t − 1 × x t − 2 \begin{equation} x_t=\sqrt{a_t\left(1-a_{t-1}\right)} \epsilon_{t-1}+\sqrt{1-a_t} \times \epsilon_t+\sqrt{a_t a_{t-1}} \times x_{t-2} \end{equation} xt=at(1at1) ϵt1+1at ×ϵt+atat1 ×xt2

这里需要回顾一下正态分布的运算公式:如果一个正态分布的随机变量 X X X服从 N ( μ , σ 2 ) N(μ, σ^2) N(μ,σ2),即均值是 μ μ μ,方差是 σ 2 σ^2 σ2,给定常数 C C C和另一个变量 Z Z Z服从 N ( μ 1 , σ 1 2 ) N(μ_1, σ_1^2) N(μ1,σ12),则有:

  • 对新分布 Y = C × X Y=C\times X Y=C×X Y Y Y的均值为 C × μ C\times μ C×μ,方差为 C 2 × σ 2 C^2\times σ^2 C2×σ2
  • 对新分布 Y = C + X Y=C+X Y=C+X Y Y Y的均值为 C + μ C+μ C+μ,方差为 σ 2 σ^2 σ2
  • 对新分布 Y = X + Z Y=X+Z Y=X+Z Y Y Y的均值为 μ + μ 1 μ+μ_1 μ+μ1,方差为 σ 2 + σ 1 2 σ^2+ σ_1^2 σ2+σ12
  • 对新分布 Y = X × Z Y=X\times Z Y=X×Z Y Y Y不再是正态分布,而变得更为复杂

式(6)中的前两项本质上是将两个独立采样得到的满足标准正态分布的噪声乘以权重后相加,套用上述运算规则,可以得到一个新的概率分布,并且可以知道这是一个均值为0,方差为 1 − a t a t − 1 1-a_t a_{t-1} 1atat1的正态分布。运用重参数化技巧,我们可以基于一个满足标准正态分布的随机变量 ϵ \epsilon ϵ来重写:
x t = 1 − a t a t − 1 ϵ + a t a t − 1 × x t − 2 \begin{equation} x_t=\sqrt{1-a_t a_{t-1}} \epsilon+\sqrt{a_t a_{t-1}} \times x_{t-2} \end{equation} xt=1atat1 ϵ+atat1 ×xt2
接着将 x t − 2 x_{t-2} xt2关于 x t − 3 x_{t-3} xt3的递推式带入上式,在多次使用重参数化和数学归纳法之后,可以得到以下的多步递推式:
x t = 1 − a t a t − 1 a t − 2 … a t − ( k − 2 ) a t − ( k − 1 ) ϵ + a t a t − 1 a t − 2 … a t − ( k − 2 ) a t − ( k − 1 ) x t − k \begin{equation} \begin{gathered} x_t=\sqrt{1-a_t a_{t-1} a_{t-2} \ldots a_{t-(k-2)} a_{t-(k-1)}} \epsilon+ \\ \sqrt{a_t a_{t-1} a_{t-2} \ldots a_{t-(k-2)} a_{t-(k-1)}} x_{t-k} \end{gathered}\end{equation} xt=1atat1at2at(k2)at(k1) ϵ+atat1at2at(k2)at(k1) xtk
k = t , α ˉ t = ∏ i = 1 t α i k=t, \bar{\alpha}_{t} = \prod_{i=1}^{t} \alpha_{i} k=t,αˉt=i=1tαi,则一步到位的公式可以写作:
x t = 1 − α ˉ t × ϵ + α ˉ t × x 0 \begin{equation} x_t=\sqrt{1-\bar{\alpha}_{t} } \times \epsilon+\sqrt{\bar{\alpha}_{t} } \times x_{0} \\ \end{equation} xt=1αˉt ×ϵ+αˉt ×x0

反向扩散过程

反向扩散本质上就是在计算这样一个概率 P ( x t − 1 ∣ x t ) P(x_{t-1}\mid x_t) P(xt1xt),也就是去掉一部分噪音,让其跟目标图片更接近一些。
在这里插入图片描述

这里需要回顾一下贝叶斯公式,它描述了在给定相关证据的情况下,某个假设的概率是如何更新的。
贝叶斯公式的基本形式如下: P ( A ∣ B ) = P ( B ∣ A ) ⋅ P ( A ) P ( B ) P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)
其中:

  • P ( A ∣ B ) P(A|B) P(AB) 是在事件B发生的条件下事件A发生的概率,称为后验概率。
  • P ( B ∣ A ) P(B|A) P(BA) 是在事件A发生的条件下事件B发生的概率,称为似然概率。
  • P ( A ) P(A) P(A) 是事件A发生的概率,称为先验概率。
  • P ( B ) P(B) P(B) 是事件B发生的概率,称之为证据。

根据贝叶斯公式,将概率进行拆解
P ( x t − 1 ∣ x t ) = P ( x t ∣ x t − 1 ) P ( x t − 1 ) P ( x t ) \begin{equation} P\left(x_{t-1} \mid x_t\right)=\frac{P\left(x_t \mid x_{t-1}\right)P\left(x_{t-1}\right)}{P\left(x_t\right)} \end{equation} P(xt1xt)=P(xt)P(xtxt1)P(xt1)
我们知道 x t − 1 x_{t-1} xt1 x t x_t xt都不是凭空产生的,而是从 x 0 x_0 x0一步步转换来的,并且遵循马尔可夫链原理,即每一步只与上一步有关,而与最开始的 x 0 x_0 x0无关,因此在条件概率公式里加上 x 0 x_0 x0对结果无影响。所以,计算目标可以转换为 P ( x t − 1 ∣ x t , x 0 ) P(x_{t-1} \mid x_t, x_0) P(xt1xt,x0),在上式中统一加上一个 x 0 x_0 x0后可得:
P ( x t − 1 ∣ x t , x 0 ) = P ( x t ∣ x t − 1 ) P ( x t − 1 ∣ x 0 ) P ( x t ∣ x 0 ) \begin{equation} P\left(x_{t-1} \mid x_t, x_0\right)=\frac{P\left(x_t \mid x_{t-1}\right) P\left(x_{t-1} \mid x_0\right)}{P\left(x_t \mid x_0\right)} \end{equation} P(xt1xt,x0)=P(xtx0)P(xtxt1)P(xt1x0)
也可以通过条件概率公式推导出来这个结论:
P ( x t − 1 ∣ x t , x 0 ) = P ( x t − 1 , x t , x 0 ) P ( x t , x 0 ) = P ( x t ∣ x t − 1 ) P ( x t − 1 ∣ x 0 ) P ( x 0 ) P ( x t ∣ x 0 ) P ( x 0 ) = P ( x t ∣ x t − 1 ) P ( x t − 1 ∣ x 0 ) P ( x t ∣ x 0 ) \begin{equation} \begin{gathered} P\left(x_{t-1} \mid x_t, x_0\right)=\frac{P\left(x_{t-1}, x_t, x_0\right)}{P\left(x_t, x_0\right)}= \\ \frac{P\left(x_t \mid x_{t-1}\right) P\left(x_{t-1} \mid x_0\right) P\left(x_0\right)}{P\left(x_t \mid x_0\right) P\left(x_0\right)}= \\\frac{P\left(x_t \mid x_{t-1}\right) P\left(x_{t-1} \mid x_0\right)}{P\left(x_t \mid x_0\right)} \end{gathered}\end{equation} P(xt1xt,x0)=P(xt,x0)P(xt1,xt,x0)=P(xtx0)P(x0)P(xtxt1)P(xt1x0)P(x0)=P(xtx0)P(xtxt1)P(xt1x0)
接下来,根据正态分布运算公式分别计算 P ( x t ∣ x t − 1 ) P ( x t − 1 ∣ x 0 ) P ( x t ∣ x 0 ) \frac{P\left(x_t \mid x_{t-1}\right) P\left(x_{t-1} \mid x_0\right)}{P\left(x_t \mid x_0\right)} P(xtx0)P(xtxt1)P(xt1x0)中各项的概率分布,根据式(4)有 P ( x t ∣ x t − 1 ) ∼ N ( α t × x t − 1 , 1 − α t ) P\left(x_t \mid x_{t-1}\right)\sim N(\sqrt{\alpha_t} \times x_{t-1},1-\alpha_t) P(xtxt1)N(αt ×xt1,1αt),根据式(9)有 P ( x t − 1 ∣ x 0 ) ∼ N ( α ˉ t − 1 × x 0 , 1 − α ˉ t − 1 ) P\left(x_{t-1} \mid x_0\right)\sim N(\sqrt{\bar{\alpha}_{t-1} } \times x_{0},1-\bar{\alpha}_{t-1}) P(xt1x0)N(αˉt1 ×x0,1αˉt1) P ( x t ∣ x 0 ) ∼ N ( α ˉ t × x 0 , 1 − α ˉ t ) P\left(x_{t} \mid x_0\right)\sim N(\sqrt{\bar{\alpha}_{t} } \times x_{0},1-\bar{\alpha}_{t}) P(xtx0)N(αˉt ×x0,1αˉt)

由于这是多个正态分布间的乘除操作,因此不能再套用加减情况下的规则计算联合分布,而要将均值 μ \mu μ和标准差 σ \sigma σ代入正态分布的概率密度函数 f ( x ) = 1 σ 2 π e − 1 2 ( x − μ σ ) 2 f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2} f(x)=σ2π 1e21(σxμ)2中计算具体概率值再反向代入回来,经过一番简单但繁琐的整理,可以得到下面的公式:
P ( x t − 1 ∣ x t , x 0 ) ∼ N ( a t ( 1 − a ˉ t − 1 ) 1 − a ˉ t x t + a ˉ t − 1 ( 1 − a t ) 1 − a ˉ t x 0 , β t ( 1 − a ˉ t − 1 ) 1 − a ˉ t ) = N ( a t ( 1 − a ˉ t − 1 ) 1 − a ˉ t x t + a ˉ t − 1 ( 1 − a t ) 1 − a ˉ t × x t − 1 − a ˉ t × ϵ a ˉ t , β t ( 1 − a ˉ t − 1 ) 1 − a ˉ t ) = N ( 1 α t ( x t − 1 − α t 1 − α t ˉ ϵ ) , β t ( 1 − a ˉ t − 1 ) 1 − a ˉ t ) \begin{equation} \begin{gathered} P(x_{t-1} \mid x_t, x_0) \sim N(\frac{\sqrt{a_t}(1-\bar{a}_{t-1})}{1-\bar{a}_t} x_t+ \\\frac{\sqrt{\bar{a}_{t-1}}(1-a_t)}{1-\bar{a}_t} x_0, \frac{\beta_t(1-\bar{a}_{t-1})}{1-\bar{a}_t}) =\\ N(\frac{\sqrt{a_t}(1-\bar{a}_{t-1})}{1-\bar{a}_t} x_t+ \frac{\sqrt{\bar{a}_{t-1}}(1-a_t)}{1-\bar{a}_t} \times \\ \frac{x_t-\sqrt{1-\bar{a}_t} \times \epsilon}{\sqrt{\bar{a}_t}}, \frac{\beta_t(1-\bar{a}_{t-1})}{1-\bar{a}_t}) = \\ N(\frac{1}{\sqrt{\alpha_t}}(x_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha_t}}}\epsilon),\frac{\beta_t(1-\bar{a}_{t-1})}{1-\bar{a}_t}) \end{gathered}\end{equation} P(xt1xt,x0)N(1aˉtat (1aˉt1)xt+1aˉtaˉt1 (1at)x0,1aˉtβt(1aˉt1))=N(1aˉtat (1aˉt1)xt+1aˉtaˉt1 (1at)×aˉt xt1aˉt ×ϵ,1aˉtβt(1aˉt1))=N(αt 1(xt1αtˉ 1αtϵ),1aˉtβt(1aˉt1))

这个式子只是在描述概率的分布情况,运用重参数化方法,可以将 x t − 1 x_{t-1} xt1表示为如下的形式,其中 z z z是满足标准正态分布的随机变量:
x t − 1 = 1 α t ( x t − 1 − α t 1 − α t ˉ ϵ ) + β t ( 1 − a ˉ t − 1 ) 1 − a ˉ t z \begin{equation} \begin{gathered} x_{t-1} = \frac{1}{\sqrt{\alpha_t}}(x_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha_t}}}\epsilon) + \sqrt{\frac{\beta_t(1-\bar{a}_{t-1})}{1-\bar{a}_t}}z \end{gathered}\end{equation} xt1=αt 1(xt1αtˉ 1αtϵ)+1aˉtβt(1aˉt1) z

模型训练过程

从前向扩散的过程中我们可以发现,随着模型步数的增加,原图上覆盖的噪音越来越大,新图与原图间的区别也越来越大。这里我们训练一个噪音预测器,让它能根据当前步数及加噪图像,预测出加的噪声,一个简单的图示如下。
在这里插入图片描述
在实际训练时,为了简化计算,我们根据式(9)实现加噪图像的一步到位式生成,令 ϵ θ \epsilon_\theta ϵθ为噪音预测器,训练目标是通过MSE来最小化预测噪音和真实噪音之间的差距。
在这里插入图片描述

模型生成过程

在训练好一个噪音预测器后,根据式(14),可以很轻松地写出下面的模型生成算法,其中 σ t z \sigma_tz σtz对应要加的方差项。
在这里插入图片描述
在这里你可能会有些疑问, x T x_T xT不是由 x 0 x_0 x0一步步生成出来的吗,为什么这里可以直接用一个正态分布的随机噪声来代替呢。我们回顾一下式(9),由于 α ˉ t = ∏ i = 1 t α i \bar{\alpha}_{t} = \prod_{i=1}^{t} \alpha_{i} αˉt=i=1tαi,当 t t t取极大时,由于 α i \alpha_{i} αi是位于01之间的小数,因此其累乘后趋近于0,也就是 x t ≈ ϵ x_t \approx \epsilon xtϵ

如果还是不够直观,可以想象这样一个过程:你手头有这样一个纯白的石膏像,你一层层在它上面抹石膏,直到变成一个浑圆的坤蛋。然后你再从这个坤蛋开始,一层层剥离石膏,直到复原出那个你心中的偶像。尽管坤蛋中既看不出篮球也看不出中分,但它们的形状已经牢牢刻进了你鸡爪的肌肉记忆之中。这,就是ikun 扩散。
在这里插入图片描述
在这里,我们不妨再重新审视一下式(1),为什么两个分布加权时,要在系数前面加根号呢。如果把 t t t看得足够大,那么 x t − 1 x_{t-1} xt1 ϵ t \epsilon_t ϵt都服从标准高斯分布,它们相加之后的新分布的方差就是系数的平方和。为了保证扩散过程的稳定,也就是每一步的结果大致服从相似的分布,需要保持方差的稳定,所以要求系数的平方和始终为一,否则方差就会变成0或者无穷大,这跟batch norm的意思有点像。(当然上面的想法使用了循环论证,并不严谨,差不多这意思)。

概率分布视角

看过论文的朋友可能会有点奇怪,你这上面说的和论文里写的好像是两码事啊,论文里那些一大长串完全看不懂的公式被你吃了?其实上面的内容是从较为直观的视角展示扩散过程的,而为了更深入地理解其数学原理,接下来我们从概率分布的视角去重新审视DDPM,并与论文中的公式做个对应。

不管是VAE还是DDPM,图像生成模型的最终目标都是让生成图像的概率分布与真实图像的分布尽可能接近。以VAE为例,给定随机输入的分布 z z z,使用极大似然估计法优化生成的图像,也就是让KL距离尽可能接近。
在这里插入图片描述
在这里插入图片描述
针对特定的 x x x,通过变分推断法计算其下界
在这里插入图片描述

这里的 z z z是VAE的随机噪声,放到DDPM里则是加了噪音之后的 x 1 , . . . , x T x_1, ...,x_T x1,...,xT,也就是论文里面的公式(3)
在这里插入图片描述
对上式做变换,并转换成KL散度的形式,得到下面的论文公式(5)
在这里插入图片描述
最小化论文公式(5),也就是最小化 L T L_T LT L t − 1 L_{t-1} Lt1,最大化 L 0 L_0 L0
针对 L T L_T LT对应的噪音分布一致的目标,由于 β t \beta_t βt可以看做是常数项,因此 L T L_T LT可以视为常数项忽略。
针对 L t − 1 L_{t-1} Lt1对应的去噪过程一致的目标,首先这两项都是高斯分布,然后令它们的方差一样,根据KL散度的计算公式得到下面的论文公式(8),其中 C C C是常数:
在这里插入图片描述
上式主要目的是让网络学习到的均值和后验分布的均值一致,我们把后验分布的均值公式代入之后得到论文公式(9-10)
在这里插入图片描述
根据定义将均值预测函数 μ θ \mu_\theta μθ转换为噪音预测函数 μ ϵ \mu_\epsilon μϵ,得到论文公式(11-12)
在这里插入图片描述
在这里插入图片描述
针对 L 0 L_0 L0对应的真实数据生成的目标,论文中提到要将[0, 255]的像素值归一化到[-1, 1]间以确保扩散的稳定性,因此可以用论文公式(13)来优化
在这里插入图片描述
L 0 L_0 L0 L t − 1 L_{t-1} Lt1对应的情况合并后,就得到了以下训练目标:
在这里插入图片描述
以上就是论文中的理论部分了,只能说确实难懂,建议多看几遍吧。

参数模型设置

论文将总采样步数 T T T设为1000,令加噪系数从 β 1 = 1 0 − 4 \beta_1 = 10^{-4} β1=104 β 1 000 = 0.02 \beta_1000 = 0.02 β1000=0.02间线性增加。
在这里插入图片描述

论文使用了上图所示的U-Net backbone作为去噪器的实现,其实现时有以下几个要点:

  • 使用transformer中的正弦位置编码即sinusoidal position embedding编码输入时间步,并在各层中共享。
  • 采用GroupNorm进行归一化。
  • 引入残差块。
  • 在16×16的特征图上采用自注意力机制。

论文结果分析

  • 总体生成质量比较
    在这里插入图片描述
  • 预测噪音比预测均值更好
    在这里插入图片描述
  • 与自回归模型比较
    论文提出了一种很新奇的想法,如果让加噪步数等于总像素数,加噪音时依次屏蔽当前步数对应的像素坐标,这样每次加噪音时都利用了被屏蔽像素的真实值,就转化成了自回归模型。
  • 插值加噪过程
    反向扩散时,令中间结果是不同图像的加权和,即 x ˉ t = ( 1 − λ ) x 0 + λ x 0 ′ \bar x_t = (1-\lambda)x_0+\lambda x'_0 xˉt=(1λ)x0+λx0,可以生成融合两张图的图片。
    在这里插入图片描述
    在这里插入图片描述

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

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

相关文章

Uipath 实现Excel 文件合并

场景描述 某文件夹下有多个相同结构(标题列相同)的Excel 文件&#xff0c;需实现汇总到一个Excel文件。 常见场景有销售明细汇总&#xff0c;订单汇总等。 解决方案 对于非IT 人员则可使用Uipath 新式Excel活动&#xff0c;通过拖拉实现。也可以通过内存表或使用VB脚本&…

寒假学习记录17:包管理器(包管理工具)

概念 包&#xff08;package&#xff09; 包含元数据的库&#xff0c;这些元数据包括&#xff1a;名称&#xff0c;描述&#xff0c;git主页&#xff0c;许可证协议&#xff0c;作者&#xff0c;依赖..... 库&#xff08;library&#xff0c;简称lib&#xff09; 以一个或多个模…

【教3妹学编程-算法题】子集中元素的最大数量

2哥 : 3妹&#xff0c;今年过年收到压岁钱了没呢。 3妹&#xff1a;切&#xff0c;我都多大了啊&#xff0c;肯定没收了啊 2哥 : 俺也一样&#xff0c;不仅没收到&#xff0c;小侄子小外甥都得给&#xff0c;还倒贴好几千 3妹&#xff1a;哈哈哈哈&#xff0c;2叔叔&#xff0c…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Navigation组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之Navigation组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Navigation组件 鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#…

Python中多种生成随机密码超实用实例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 前言 密码是信息安全的基石&#xff0c;它用于保护我们的账户、数据和隐私。为了确保密码足够强大&#xff0c;…

clang前端

Clang可以处理C、C和Objective-C源代码 Clang简介 Clang可能指三种不同的实体&#xff1a; 前端&#xff08;在Clang库中实现&#xff09;编译驱动程序&#xff08;在clang命令和Clang驱动程序库中实现&#xff09;实际的编译器&#xff08;在clang-ccl命令中实现&#xff0…

kafka如何保证消息不丢?

概述 我们知道Kafka架构如下&#xff0c;主要由 Producer、Broker、Consumer 三部分组成。一条消息从生产到消费完成这个过程&#xff0c;可以划分三个阶段&#xff0c;生产阶段、存储阶段、消费阶段。 产阶段: 在这个阶段&#xff0c;从消息在 Producer 创建出来&#xff0c;…

c++阶梯之类与对象(下)

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;&#xff1c; 续集 &#xff1e;-CSDN博客 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&a…

【机器学习笔记】3 逻辑回归

分类问题 分类问题监督学习最主要的类型&#xff0c;主要特征是标签离散&#xff0c;逻辑回归是解决分类问题的常见算法&#xff0c;输入变量可以是离散的也可以是连续的 二分类 先从用蓝色圆形数据定义为类型1&#xff0c;其余数据为类型2&#xff1b;只需要分类1次&#x…

Java并发基础:SynchronousQueue全面解析!

内容概要 SynchronousQueue的优点在于其直接性和高效性&#xff0c;它实现了线程间的即时数据交换&#xff0c;无需中间缓存&#xff0c;确保了数据传输的实时性和准确性&#xff0c;同时&#xff0c;其灵活的阻塞机制使得线程同步变得简单而直观&#xff0c;适用于需要精确协…

相机图像质量研究(13)常见问题总结:光学结构对成像的影响--鬼影

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

TiDB 在医疗保障信息平台的应用实践

文章介绍了 TiDB 在医疗保障信息平台中的应用。东软医保云应用管理平台通过与 TiDB 联合&#xff0c;成功满足了医疗保障业务中高并发、实时性和复杂查询的要求。在某地市医疗保障信息平台的实践中&#xff0c;TiDB 分布式数据库有效实现了在线交易和实时分析服务&#xff0c;日…

C语言学习day14:数组定义和使用

定义变量&#xff1a; 数据类型 变量 值 数组定义&#xff1a; 数据类型 数组名[元素个数]{值1,值2,值3} 代码&#xff1a; int main() {//定义变量//数据类型 变量 值//数组定义//数据类型 数组名[元素个数]{值1,值2,值3}//数组下标 数组名[小标]//数组下标是…

.NET Core WebAPI中封装Swagger配置

一、创建相关文件 创建一个Utility/SwaggerExt文件夹&#xff0c;添加一个类 二、在Program中找到Swagger相关配置信息 三、添加方法&#xff0c;在Program中调用 在SwaggerExt类中添加方法&#xff0c;将相关配置添写入 /// <summary> /// swagger配置 /// </sum…

初识Qt | 从安装到编写Hello World程序

文章目录 1.前端开发简单分类2.Qt的简单介绍3.Qt的安装和环境配置4.创建简单的Qt项目 1.前端开发简单分类 前端开发&#xff0c;这里是一个广义的概念&#xff0c;不单指网页开发&#xff0c;它的常见分类 网页开发&#xff1a;前端开发的主要领域&#xff0c;使用HTML、CSS …

[经验] 欧阳修唐宋八大家之首是谁 #微信#知识分享#学习方法

欧阳修唐宋八大家之首是谁 1、唐宋八大家之首是谁 唐宋八大家是中国文学史上最具代表性的八位大文豪&#xff0c;他们的文学成就在中国文学史上占有重要地位&#xff0c;被誉为文学史上的“巨人”。 唐宋八大家之首&#xff0c;无疑是唐代著名诗人杜甫。他出生在一个贫苦的家…

牛客——IncDec Sequence(差分)

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 给定一个长度为 n(n≤105)(n \leq 10^5 )(n≤105) 的数列a1,a2,…,an{a_1,a_2,…,a_n}a1​,a2​,…,an​&#xff0c;每次可以选择一个区间 [l,r]&#xff0c;使下标在这个区间内的数…

每日一题 力扣107 二叉树的层序遍历Ⅱ

107. 二叉树的层序遍历 II 题目描述&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20…

如何用 ChatGPT 做项目管理?

ChatGPT 可以通过创建和维护跨团队项目协作计划&#xff0c;让员工更容易理解他们的角色和职责。 这个协作计划里面会包括每个团队或个人要执行的具体任务&#xff0c;每个任务最后期限和任何事情之 间的依赖关系。 该场景对应的关键词库:(24 个) 项目管理、项目协作计划、跨…

操作 Docker 存储卷的常用指令汇总

1. 什么是存储卷&#xff1f; 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。使得可以在宿主机和容器内共享数据库内容&#xff0c;让容器直接访问宿主机中的内容&#xff0c;也可以宿主机向容器写入内容&#xff0c;容…