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,一经查实,立即删除!

相关文章

【Java基础题型】力扣88、合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 (要合并到的目标数组)中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&a…

使用redis实现手机短信验证码和lua完成重置功能

文章目录 前言一、介绍二、代码1.LoginController2.reset.lua 总结 前言 2024了,各种各样的门户网站和APP都需要登录,登录方式也各种各样,由于都要绑定用户手机号码,所以大部分都支持了手机验证码登录的方式,接下来我们使用redis来完成验证码的功能。 一、介绍 方法名描述get…

深度学习入门-第2章-感知机

感知机&#xff08;perceptron&#xff09; 严格地讲&#xff0c;本章中所说的感知机应该称为“人工神经元”或“朴素感知机”&#xff0c;但是因为很多基本的处理都是共通的&#xff0c;所以这里就简单地称为“感知机”。2.1 感知机是什么 感知机接收多个输入信号&#xff0c…

Uipath 实现Excel 文件合并

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

解锁机器学习多类分类之门:Softmax函数的全面指南

1. 引言 Softmax函数的定义和基本概念 Softmax函数&#xff0c;也称为归一化指数函数&#xff0c;是一个将向量映射到另一个向量的函数&#xff0c;其中输出向量的元素值代表了一个概率分布。在机器学习中&#xff0c;特别是在处理多类分类问题时&#xff0c;Softmax函数扮演…

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

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

第11讲投票创建后端实现

投票创建页面实现 文件选择上传组件 uni-file-picker 扩展组件 安装 https://ext.dcloud.net.cn/plugin?nameuni-file-picker 日期选择器uni-datetime-picker组件 安装 https://ext.dcloud.net.cn/plugin?nameuni-datetime-picker iconfont小图标 https://www.iconfont…

【教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;项目方舟框架&#…

Java:性能优化细节01-10

Java&#xff1a;性能优化细节01-10 在Java程序开发过程中&#xff0c;性能优化是一个重要的考虑因素。常见的误解是将性能问题归咎于Java语言本身&#xff0c;然而实际上&#xff0c;性能瓶颈更多地源于程序设计和代码实现方式的不当。因此&#xff0c;培养良好的编码习惯不仅…

(力扣记录)235. 二叉搜索树的最近公共祖先

数据结构&#xff1a;树&#x1f332; 时间复杂度&#xff1a;O(n) 空间复杂度&#xff1a;O(1) 代码实现&#xff1a; class Solution:def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:while True:if p.val < root.val <…

数据的艺术与保障:深入探索OSI模型的表示层

引言 在现代计算机网络中&#xff0c;数据的传输和交换是至关重要的。为了促进不同计算机系统之间的有效通信&#xff0c;国际标准化组织&#xff08;ISO&#xff09;提出了开放系统互连&#xff08;OSI&#xff09;参考模型。该模型定义了网络通信的七个层次&#xff0c;每一…

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

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

我的大数据之路 - 基于HANA构建实时方案的历程

产品内部前期有一个共识&#xff0c;依据业务要求的时效性来选择技术平台&#xff0c;即&#xff1a; 实时类业务&#xff0c;时效性小于2小时&#xff0c;则使用HANA构建。离线类业务&#xff0c;时效性大于2小时&#xff0c;则使用大数据平台构建。 经过五月、六月两月的努…

今日JAVA小练习之复制数组

题目描述 将两个有序数组按照大小顺序复制成一个数组 实现思路 创建新的数组&#xff0c;长度为要复制的两个数组长度之和定义3个初始变量i,p1,p2在循环中依次比较两个数组中元素大小&#xff0c;小的放入新数组若p1小于ns1的长度&#xff0c;则说明在上面while循环中ns1的元…

Redis 的 SETNX

Redis 的 SETNX 命令是一个用于设置键的值的原子性操作。SETNX 表示 "SET if Not eXists"&#xff0c;即当键不存在时才进行设置。该命令可以实现一种简单的分布式锁和限流策略。 SETNX 命令的语法如下&#xff1a; 复制代码 SETNX key value key&#xff1a;要设…

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…

Windows注册表的参数,比如: %* %0 %1 %2 %D %L %V %W

Windows注册表的参数,比如: %* %0 %1 %2 %D %L %V %W 参数意义%*代表所有的参数%0, %1第1个&#xff08;文件&#xff09;参数的完整路径&#xff0c;不包含引号。当应用程序是16位时&#xff0c;得到8.3短路径形式&#xff1b;当应用程序是32/64位时&#xff0c;得到长路径。…