通俗理解DDPM到Stable Diffusion原理

请添加图片描述

  • 代码1:stabel diffusion 代码库
  • 代码2:diffusers 代码库
  • 论文:High-Resolution Image Synthesis with Latent Diffusion Models
  • 模型权重:runwayml/stable-diffusion-v1-5

文章目录

  • 1. DDPM的通俗理解
    • 1.1 DDPM的目的
    • 1.2 扩散过程
    • 1.3 降噪过程
    • 1.4 DDPM的训练
    • 1.5 DDPM 的sampling
    • 1.6 DDPM中的Unet
  • 2. Stable Diffusion原理
    • 2.1 图片感知压缩(Perceptual Image Compression)
      • 2.1.1 动机
      • 2.1.2 方法
      • 2.1.3 训练
    • 2.2 潜在扩散模型(Latent Diffusion Models)
    • 2.3 条件机制(Conditioning Mechanisms)
    • 2.4 模型测评
    • 2.5 小结
  • 3. 参考

前一篇文章Stable Diffusion XL(SDXL)原理详解讲解了SDXL的原理以及相对SD1.x的改进点,但并未涉及SD的理论,本文将以简单易懂的方式介绍stable diffusion及其背后的相关原理,让大家能够通俗的理解SD在做什么,其中涉及DDPM的很多地方我们直接讲结论,具体的数学推导见下一篇文章。

1. DDPM的通俗理解

Stable Diffusion等扩散模型背后的主要原理就是扩散模型了,而此处的扩散模型主要是指DDPM,本文将以简单易懂的方式来讲解DDPM,尽量不涉及公式推导,具体的推导我们将在后面一篇文章中详细讲解。

1.1 DDPM的目的

DDPM的本质作用,就是学习训练数据的分布,产出尽可能符合训练数据分布的真实图片,通俗的说就是给模型喂一堆cyperpunk风格的图片,让模型学会cyberpunk风格的分布信息,然后喂给模型一个随机噪音,就能让模型产生一张逼真的cyberpunk照片。
在这里插入图片描述

DDPM算法整个过程包括两步:

  • Diffusion Process (又被称为Forward Process) 扩散过程
  • Denoise Process(又被称为Reverse Process)降噪过程

扩散模型的整体流程如下图所示,一步步加噪的过程,就被称为Diffusion Process;一步步去噪的过程,就被称为Denoise Process
请添加图片描述

1.2 扩散过程

如图所示,进行了1000步的加噪,每一步我们都往图片上加入一个高斯分布的噪声,直到图片变为一个基本是纯高斯分布的噪声
请添加图片描述

  • T T T :加噪总的步数
  • x 0 , x 1 , x 2 , . . . , x T x_0, x_1, x_2, ... , x_T x0,x1,x2,...,xT:为每步加噪后的图片,其中 x 0 x_0 x0是原始图片, x T x_T xT是第 T T T步加噪后的图片
  • ϵ ∈ N ( 0 , I ) \epsilon \in N(0, I) ϵN(0,I) 是每一步加的噪声

那个根据上图所示:

x T = x t − 1 + ϵ = x 0 + ϵ 0 + ϵ 1 + . . . + ϵ t x_T = x_{t-1}+\epsilon = x_0+\epsilon_0+\epsilon_1+...+\epsilon_t xT=xt1+ϵ=x0+ϵ0+ϵ1+...+ϵt

根据上式,为了得到 x T x_T xT需要sample多次噪声,比较麻烦。因此使用 重参数化技巧 来简化,sample一次噪声直接从 x 0 x_0 x0得到 x t x_t xt。即如下式所示(注意在本文中不进行公式推导,直接讲结论,给大家来对扩散模型一个直观的理解,所有公式将在下一篇文章中进行推导):

x t = α ˉ t x 0 + 1 − α ˉ t ϵ x_{t}={\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon xt=αˉt x0+1αˉt ϵ

其中 α ˉ t = α 1 α 2 . . . α t \bar\alpha_{t}=\alpha_{1}\alpha_{2}...\alpha_{t} αˉt=α1α2...αt α t = 1 − β t \alpha_t=1-\beta_t αt=1βt β 1 , β 2 . . . β t \beta_1, \beta_2 ... \beta_t β1,β2...βt 是一系列常数,是我们直接设定的超参数,随着T的增加越来越大。这样 α t \alpha_t αt随着 T T T增大而减小, α ˉ t \bar\alpha_{t} αˉt随着 T T T增大而减小。对上式的一个直观解释为:随着步数的增加,图片中原始信息含量越少,噪声越多,因此给原始图片权重越来越小,给噪声一个越来越大的权重。

1.3 降噪过程

降噪过程就是给定 x t x_t xt,让模型能把它还原到 x t − 1 x_{t-1} xt1。通常加噪过程表示为 q ( x t ∣ x t − 1 ) q(x_t|x_{t-1}) q(xtxt1),而去噪过程表示成 p ( x t − 1 ∣ x t ) p(x_{t-1}|x_t) p(xt1xt)。由于加噪过程只是按照设定好的超参数进行前向加噪,本身不经过模型。但去噪过程是真正训练并使用模型的过程。所以更进一步,用 p θ ( x t − 1 ∣ x t ) p_{\theta}(x_{t-1}|x_t) pθ(xt1xt) 来表示去噪过程,其中 θ \theta θ 表示模型参数。

具体反向过程如下图所示,从第T个timestep开始,模型的输入为 x t x_t xt 与当前timestep T T T。模型是一个噪声预测器(网络结构为UNet),它会根据当前的输入预测出噪声,然后将当前图片减去预测出来的噪声,就可以得到去噪后的图片 x t − 1 x_{t-1} xt1。重复这个过程,直到还原出原始图片 x 0 x_0 x0为止:请添加图片描述
由于模型每一步的去噪都用的是同一个模型,所以必须告诉模型,现在进行的是哪一步去噪。因此引入timestep。timestep的表达方法类似于Transformer中的位置编码,将一个常数转换为一个向量,再和我们的输入图片进行相加。

1.4 DDPM的训练

如上文所述,UNet模型是DDPM的核心架构,DDPM模型训练的目的是给定time_step和加噪的图片,结合两者去预测图片中的噪声。现在我们已知:

  • 第t个时刻的输入图片可以表示为: x t = α ˉ t x 0 + 1 − α ˉ t ϵ x_{t}={\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon xt=αˉt x0+1αˉt ϵ
  • 第t个时刻sample出的噪声(即真实噪声)为: ϵ ∈ N ( 0 , I ) \epsilon \in N(0, I) ϵN(0,I)
  • Unet模型预测出来的噪声为: ϵ θ ( α ˉ t x 0 + 1 − α ˉ t ϵ , t ) \epsilon_\theta({\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon, t) ϵθ(αˉt x0+1αˉt ϵ,t),其中 θ \theta θ 为模型参数

那么损失函数可以表示成:
l o s s = ϵ − ϵ θ ( α ˉ t x 0 + 1 − α ˉ t ϵ , t ) loss=\epsilon-\epsilon_\theta({\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon, t) loss=ϵϵθ(αˉt x0+1αˉt ϵ,t)

我们的训练目标就是最小化该损失,当然该损失也可写成MSE的形式。

请添加图片描述

如上图所示,整个训练过程如下:

  • 从训练数据中,抽样出一条 x 0 x_0 x0
  • 随机抽样出一个timestep t t t。( t ∈ Uniform ( 1 , 2 , 3... , T ) t \in \text {Uniform}(1, 2, 3 ..., T) tUniform(1,2,3...,T)
  • 随机抽样出一个噪声 ϵ ∈ N ( 0 , I ) \epsilon \in N(0, I) ϵN(0,I)
  • 计算损失: l o s s = ϵ − ϵ θ ( α ˉ t x 0 + 1 − α ˉ t ϵ , t ) loss=\epsilon-\epsilon_\theta({\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon, t) loss=ϵϵθ(αˉt x0+1αˉt ϵ,t)
  • 计算梯度,更新模型,重复上面过程,直至收敛

以上是一个数据计算,也可按整个batch计算

1.5 DDPM 的sampling

所谓sampling就是推理过程,对于训练好的模型,我们从最后一个时刻(T)开始,传入一个纯噪声(或者是一张加了噪声的图片),逐步去噪。根据 x t = α ˉ t x 0 + 1 − α ˉ t ϵ x_{t}={\sqrt{{\bar{\alpha}}_{t}}}x_{0}+{\sqrt{1-{\bar{\alpha}}_{t}}}\epsilon xt=αˉt x0+1αˉt ϵ 可以推导出 x t − 1 x_{t-1} xt1

x t − 1 = 1 α t ( x t − 1 − α t 1 − α ˉ t ϵ θ ( x t , t ) ) \mathbf{x}_{t-1}=\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta\left(\mathbf{x}_t, t\right)\right) xt1=αt 1(xt1αˉt 1αtϵθ(xt,t))

为了增加推理中的随机性,额外增添一项,从而得到下式:

x t − 1 = 1 α t ( x t − 1 − α t 1 − α ˉ t ϵ θ ( x t , t ) ) + σ t z \mathbf{x}_{t-1}=\frac{1}{\sqrt{\alpha_t}}\left(\mathbf{x}_t-\frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \boldsymbol{\epsilon}_\theta\left(\mathbf{x}_t, t\right)\right)+\sigma_t \mathbf{z} xt1=αt 1(xt1αˉt 1αtϵθ(xt,t))+σtz

如下图所示,从时间步T开始,输入模型纯噪声 x T x_T xT和时间步 t t t,预测该时间步的噪声 ϵ t = ϵ θ ( x T , t ) \epsilon_t=\epsilon_{\theta}(x_{T}, t) ϵt=ϵθ(xT,t),然后得到 x t − 1 = x t − ϵ t x_{t-1}=x_t-\epsilon_t xt1=xtϵt,将其输入到模型中再预测噪声,直到得到 x 0 x_0 x0

请添加图片描述

1.6 DDPM中的Unet

如下图所示,Unet主要包括三部分,左边绿色的encoder部分,中间橙色的MidBlock部分,以及右边黄色的decoder部分。在Encoder部分中,UNet模型会逐步压缩图片的大小;在Decoder部分中,则会逐步还原图片的大小。同时在Encoder和Deocder间,还会使用“残差连接”(虚线部分),确保Decoder部分在推理和还原图片信息时,不会丢失掉之前步骤的信息。下图展示了输入为32*32*3的图片,在DDPM的Unet中的流程,其中红色箭头是下采样,绿色箭头为上采样,蓝色箭头代表卷积操作和attention操作。
在这里插入图片描述
上图中蓝色箭头部分,不仅仅有卷积操作还有self-attention操作,具体如下图所示,TimeEmbedding层采用和Transformer一致的三角函数位置编码,将常数转变为向量。Attention层则是沿着channel维度将图片拆分为token,做完attention后再重新组装成图片。
请添加图片描述

2. Stable Diffusion原理

上文中提到的扩散模型,在扩散(采样)过程会向U-Net提供完整尺寸的图像来获得最终结果。这使得纯扩散模型在总扩散步数T和图像大小较大时生成图像极其缓慢,Stable Diffusion 因此而诞生。

Stable Diffusion的最大贡献主要有如下两点:

  • Diffusion model相比GAN可以取得更好的图片生成效果,但是Diffusion Model训练和推理代价都很高,需要更大的显存和计算资源。SD提出在潜在表示空间(latent space)上进行diffusion过程的方法,从而能够大大减少计算复杂度,同时也能达到十分不错的图片生成效果
  • SD通过cross-attention的方法来实现多模态训练,使得条件图片生成任务也可以实现。SD中条件图片生成任务包括类别条件图片生成(class-condition), 文图生成(text-to-image), 布局条件图片生成(layout-to-image)等

Stable Diffusion的结构如下图所示,主要由AutoEncoder、扩散模型和Condition条件模块三部分组成。具体方法是首先需要训练好一个自编码模型(AutoEncoder,包括一个编码器 E E E和一个解码器 D D D )。之后利用编码器对图片进行压缩,然后在潜在表示空间上做diffusion操作,最后我们再用解码器恢复到原始像素空间即可,论文将这个方法称之为感知压缩(Perceptual Compression)。
请添加图片描述
在潜在表示空间上做diffusion操作其主要过程和标准的扩散模型没有太大的区别,所用到的扩散模型的具体实现为 time-conditional UNet。但是有一个重要的地方是SD引入了条件机制(Conditioning Mechanisms),通过cross-attention的方式来实现多模态训练,使得条件图片生成任务也可以实现。下面对三个模块进行详细分析

2.1 图片感知压缩(Perceptual Image Compression)

图片感知压缩实际就是使用VAE来编码和解码图片,VAE相关内容看查看之前的文章从VAE到Diffusion生成模型详解(1):变分自编码器VAE

2.1.1 动机

感知压缩本质上是一个tradeoff,非感知压缩的扩散模型由于在像素空间上训练模型,若期望生成一张高分辨率图片,意味着训练的空间也是一个很高维的空间,从而训练过程中计算成本非常大。引入感知压缩是通过VAE这类自编码模型对原图片进行处理,忽略掉图片中的高频信息,只保留重要、基础的一些特征,将高维图片压缩到一个低维表示,然后在低维空间上进行训练,从而能够大幅降低训练和采样阶段的计算复杂度,让文图生成等任务能够在消费级GPU上,在10秒级别时间生成图片,大大降低了落地门槛。

感知压缩主要利用一个预训练的自编码模型,该模型能够学习到一个在感知上等同于图像空间的潜在表示空间,但是维度确比原始图像小很多。这样只需要训练一个通用的自编码模型,就可以用于不同的扩散模型的训练,在不同的任务上使用。

2.1.2 方法

基于感知压缩的扩散模型的训练本质上是一个两阶段训练的过程,第一阶段训练一个自编码器,第二阶段才需要训练扩散模型本身。在第一阶段训练自编码器时,为了防止得到的latent的标准差过大,作者使用了两种正则化方法,一种是KL-reg,另一种是VQ-reg,因此在官方发布的一阶段预训练模型中,会看到KL和VQ两种实现。在Stable Diffusion中主要采用AutoencoderKL这种实现。

具体来说,给定图像 x ∈ R H × W × 3 x\in\mathbb{R}^{H\times W\times3} xRH×W×3 ,先利用一个编码器 E E E来将图像编码到潜在表示空间 z = E ( x ) z={\mathcal{E}}(x) z=E(x),其中 z ∈ R h × s × c z \in \mathbb{R}^{h \times s \times c} zRh×s×c,然后用解码器从潜在表示空间重建图片 x ~ = D ( z ) = D ( E ( x ) ) {\tilde{x}}={\mathcal{D}}(z)={\mathcal{D}}({\mathcal{E}}(x)) x~=D(z)=D(E(x)) 。在感知压缩压缩的过程中,下采样因子的大小为 f = H / h = W / w f=H/h=W/w f=H/h=W/w,它是2的次方,即 f = 2 m f=2^{m} f=2m

2.1.3 训练

在训练autoencoder过程中,除了采用L1重建损失外,还增加了感知损失(perceptual loss,即LPIPS,具体见论文The Unreasonable Effectiveness of Deep Features as a Perceptual Metric)以及基于patch的对抗训练。同时为了防止得到的latent的标准差过大,采用了两种正则化方法:第一种是KL-reg,类似VAE增加一个latent和标准正态分布的KL loss,这里为了保证重建效果,采用比较小的权重(~10e-6);第二种是VQ-reg,引入一个VQ (vector quantization)layer,此时的模型可以看成是一个VQ-GAN,不过VQ层是在decoder模块中,这里VQ的codebook采样较高的维度(8192)来降低正则化对重建效果的影响.具体损失函数如下所示:

L A u t o e n c o d e r = min ⁡ ε , D max ⁡ ψ ( L r e c ( x , D ( E ( x ) ) ) − L a d v ( D ( E ( x ) ) ) + log ⁡ D ψ ( x ) + L r e g ( x ; E , D ) ) {\cal L}_{\mathrm{Autoencoder}}=\operatorname*{min}_{\varepsilon,D}\operatorname*{max}_{\psi}\left({\cal L}_{r e c}(x,{\cal D}({\cal E}(x)))-{\cal L}_{a d v}({\cal D}({\cal E}(x)))+\log{\cal D}_{\psi}(x)+{\cal L}_{r e g}(x;{\cal E},{\cal D})\right) LAutoencoder=ε,Dminψmax(Lrec(x,D(E(x)))Ladv(D(E(x)))+logDψ(x)+Lreg(x;E,D))

上式摘自论文的附录,但是该损失与论文3.1章节描述有出入,3.1中描述还有感知损失,然而此处并没有;此外,该损失函数中对抗损失的写法貌似也不太正确。总而言之,在训练Autoencoder过程中包含如下几个损失:

  • 重建损失(Reconstruction Loss):是重建图像与原始图像在像素空间上的均方误差
  • 感知损失(Perceptual Loss):是最小化重构图像和原始图像分别在预训练的VGG网络上提取的特征在像素空间上的均方误差;可参考感知损失(perceptual loss)详解
  • 对抗损失(Adversarial Loss):使用Patch-GAN的判别器来进行对抗训练, 可参考PatchGAN原理
  • 正则项(KL divergence Loss):通过增加正则项来使得latent的方差较小且是以0为均值,即计算latent和标准正态分布的KL损失

论文将不同的autoencoder在扩散模型上进行实验,在ImageNet数据集上训练同样的步数(2M steps),其训练过程的生成质量如下所示,可以看到过小的(比如1和2)下收敛速度慢,此时图像的感知压缩率较小,扩散模型需要较长的学习;而过大的其生成质量较差,此时压缩损失过大。
请添加图片描述
f f f 在4~16时,可以取得相对好的效果。SD采用基于KL-reg的autoencoder,其中下采样率 f = 8 f=8 f=8,特征维度为 c = 4 c=4 c=4,当输入图像为512x512大小时将得到64x64x4大小的latent。

autoencoder将图片压缩到latent后再重建其实是有损的,比如会出现文字和人脸的畸变等情况,这种有损压缩对SD的生成图像质量是有一定影响的。此外,由于KL-reg的权重系数非常小,实际得到latent的标准差还是比较大,latent diffusion论文中提出了一种rescaling方法:首先计算出第一个batch数据中的latent的标准差 δ ^ \hat \delta δ^,然后采用 1 / δ ^ 1/\hat \delta 1/δ^这个系数来rescale latent,这样就尽量保证latent的标准差接近1(防止扩散过程的SNR较高,影响生成效果),然后扩散模型也是应用在rescaling的latent上,在解码时只需要将生成的latent除以 1 / δ ^ 1/\hat \delta 1/δ^,然后再送入autoencoder的decoder即可。对于SD 1.x所使用的autoencoder,这个rescaling系数为0.18215。

2.2 潜在扩散模型(Latent Diffusion Models)

SD中的扩散模型结构与1.6章节中图类似,主要差别在于增加了CrossAttention来引入条件,Attention的query是UNet的中间特征,而key和value则是text embeddings。将AutoEncoder的编码器输出的latent加噪后作为Unet的输入(同时还有其他条件输入),来预测噪声, 损失函数就是真实噪声和预测噪声的L1或L2损失。
请添加图片描述
在训练条件扩散模型时,会采用Classifier-Free Guidance (简称为CFG),即在训练条件扩散模型的同时也训练一个无条件的扩散模型,将条件控制下预测的噪音和无条件下的预测噪音组合在一起来确定最终的噪音,具体的计算公式如下所示

pred_noise = w ⋅ cond_pred_noise + ( 1 − w ) ⋅ uncond_pred_noise = w ϵ θ ( x t , t , c ) + ( 1 − w ) ϵ θ ( x t , t ) \begin{aligned} \text {pred\_noise} & =w \cdot \text {cond\_pred\_noise}+(1-w) \cdot \text {uncond\_pred\_noise} \\ & =w \epsilon_\theta\left(\mathbf{x}_t, t, \mathbf{c}\right)+(1-w) \epsilon_\theta\left(\mathbf{x}_t, t\right) \end{aligned} pred_noise=wcond_pred_noise+(1w)uncond_pred_noise=wϵθ(xt,t,c)+(1w)ϵθ(xt,t)

这里的 w w w为guidance scale,当 w w w越大时,condition起的作用越大,即生成的图像其更和输入文本一致。CFG的具体实现非常简单,在训练过程中,我们只需要以一定的概率(比如10%)随机drop掉text即可,将text置为空字符串;SD默认采用的guidance_scale为7.5,当guidance_scale较低时生成的图像效果是比较差,当采用更大的guidance_scale比如11,图像的色彩过饱和而看起来不自然。

此外CFG和SD的negtive prompt参数相关,在去噪过程时的噪音预测不仅仅依赖条件扩散模型,也依赖无条件扩散模型:这里的negative_prompt便是无条件扩散模型的text输入,上面说过训练过程中我们将text置为空字符串来实现无条件扩散模型,即negative_prompt = None = “”。但是有时候我们可以使用不为空的negative_prompt来避免模型生成的图像包含不想要的东西,因为从上述公式可以看到这里的无条件扩散模型是我们想远离的部分。

最后,SD默认生成512x512大小的图像,但实际上可以生成其它分辨率的图像,但是可能会出现不协调,如果采用多尺度策略训练,会改善这种情况,比如SDXL。

2.3 条件机制(Conditioning Mechanisms)

SD采用CLIP text encoder来对输入text 提取text embeddings,具体的是采用目前OpenAI所开源的最大CLIP模型:clip-vit-large-patch14。对于输入text,送入CLIP text encoder后得到最后的hidden states,其特征维度大小为77x768(77是token的数量),这个细粒度的text embeddings将以cross attention的方式送入UNet中。注意,在训练SD的过程中,CLIP text encoder模型是冻结的。此外输入的条件不只能是文本,还可以是轮廓图,图片等。

2.4 模型测评

对于文生图模型,目前常采用的定量指标是FID(Fréchet inception distance)和CLIP score,其中FID可以衡量生成图像的逼真度(image fidelity),而CLIP score评测的是生成的图像与输入文本的一致性,其中FID越低越好,而CLIP score是越大越好。当CFG的gudiance scale参数设置不同时,FID和CLIP score会发生变化,下图为不同的gudiance scale参数下,SD模型在COCO2017验证集上的评测结果,注意这里是zero-shot评测,即SD模型并没有在COCO训练数据集上精调。
请添加图片描述

2.5 小结

本章节主要对SD的结构进行了讲解,但是部分细节并没有涉及,比如CrossAttention是如何交互的。此外对于SD的具体应用,如文生图、图生图、Inpainting等操作都未讲解,这些细节都将在下一篇文章和代码结合在一起讲解。

下面两张图片分别展示了普通扩散模型和Stable Diffusion的模型结构对比,可以看到最大的区别在于SD使用了自编码器将原始图片进行了压缩,从而有利于减少计算资源,以及SD引入了contition模块,从而使得文生图等得以实现。
请添加图片描述

图2.5.1 普通Diffusion模型结构

请添加图片描述

图2.5.2 Stable Diffusion结构

关注公众号 funNLPer一起进步起飞😘😘😘

3. 参考

  • 深入浅出扩散模型系列:基石DDPM(模型架构篇),最详细的DDPM架构图解 👍
  • 彻底搞懂CNN中的卷积和反卷积
  • Diffusion 和Stable Diffusion的数学和工作原理详细解释
  • Stable Diffusion原理解读
  • 一文看懂PatchGAN
  • Understanding Stable Diffusion
  • 感知损失(perceptual loss)详解
  • 硬核解读Stable Diffusion(完整版)👍
  • stabel diffusion 代码库
  • diffusers 代码库
  • High-Resolution Image Synthesis with Latent Diffusion Models
  • runwayml/stable-diffusion-v1-5

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

编写Dockerfile制作Web应用系统nginx镜像,生成镜像nginx:v1.1,并推送其到私有仓库。

环境: CentOS 7 Linux 3.10.0-1160.el7.x86_64 具体要求如下: (1)基于centos基础镜像; (2)指定作者信息; (3)安装nginx服务,将提供的dest目录…

Linux学习之DNS服务的原理

DNS服务一些理论 域名系统(Domain Name System,DNS)是互联网的核心应用服务,可以通过IP地址查询到域名,也可以通过域名查询到IP地址。 FQDN(Full Qualified Domain Name)是完全限定域名&#xf…

Apache Paimon 实时数据湖 Streaming Lakehouse 的存储底座

摘要:本文整理自阿里云开源大数据表存储团队负责人,阿里巴巴高级技术专家李劲松(之信),在 Streaming Lakehouse Meetup 的分享。内容主要分为四个部分: 流计算邂逅数据湖 Paimon CDC 实时入湖 Paimon 不止…

java八股文面试[多线程]——死锁、活锁、饥饿

DCL双重锁:TODO 如何预防死锁: 如何查看线程死锁: 知识来源: 【2023年面试】描述一下线程安全活跃态问题,以及竞态条件_哔哩哔哩_bilibili 【2023年面试】如何预防死锁_哔哩哔哩_bilibili 【并发与线程】阿里一面&…

element Collapse 折叠面板 绑定事件

1. 点击面板触发事件 change <el-collapse accordion v-model"activeNames" change"handleChange"><el-collapse-item title"一致性 Consistency"><div>与现实生活一致&#xff1a;与现实生活的流程、逻辑保持一致&#xff0c…

迅为RK3588开发板Android12 设置系统默认不锁屏

修改 frameworks/base/packages/SettingsProvider/res/values/defaults.xml 文件&#xff0c;修改为如下 所示&#xff1a; - <bool name"def_lockscreen_disabled">false</bool> <bool name"def_lockscreen_disabled">true</bool&…

怎么建设ITIIL运维管理体系?

市场上大多数ITIL解决方案都过于复杂&#xff0c;让我们举一个客户希望实施ITIL方案的例子。首先&#xff0c;客户要通过ITIL咨询来定义ITIL流程&#xff0c;并使其与业务目标保持一致。接下来就是购买ITIL软件&#xff1b;大多数ITIL解决方案将事件、问题和变更管理作为不同的…

一生一芯9——ubuntu22.04安装valgrind

这里安装的valgrind版本是3.19.0 下载安装包 在选定的目录下打开终端&#xff0c;输入以下指令 wget https://sourceware.org/pub/valgrind/valgrind-3.19.0.tar.bz2直至下载完成 解压安装包 输入下面指令解压安装包 tar -xvf valgrind-3.19.0.tar.bz2.tar.bz2注&#xf…

Jmeter(二十八):beanshell的使用

Beanshell 是一种轻量级的 Java 脚本,纯 Java 编写的,能够动态的执行标准 java 语法及一些扩展脚本语法,类似于 javaScript,在工作中可能用的多的就是: Beanshell 取样器:跟Http取样器并列Beanshell前置处理器:一般放在Http请求下,在请求前处理一些数据Beanshell后置处…

1.6 服务器处理客户端请求

客户端进程向服务器进程发送一段文本&#xff08;MySQL语句&#xff09;&#xff0c;服务器进程处理后再向客户端进程发送一段文本&#xff08;处理结果&#xff09;。 从图中我们可以看出&#xff0c;服务器程序处理来自客户端的查询请求大致需要经过三个部分&#xff0c;分别…

关于disriminative 和 generative这两种模型

但是&#xff0c;其实&#xff0c;根据李宏毅老师讲到的&#xff0c;generative model是做了一些假设的&#xff0c;比如&#xff0c;如果使用Naive Bayes的话&#xff0c;不同特征x1,x2...之间相互独立的话&#xff0c;其实是很容易出现较大的偏差的&#xff0c;因为不同特征变…

在kaggle中用GPU使用CGAN生成指定mnist手写数字

文章目录 1项目介绍2参考文章3代码的实现过程及对代码的详细解析独热编码定义生成器定义判别器打印我们的引导信息模型训练迭代过程中生成的图片损失函数的变化 4总结5 模型相关的文件 1项目介绍 在GAN的基础上进行有条件的引导生成图片cgan 2参考文章 GAN实战之Pytorch 使用…

UbuntuDDE 23.04发布,体验DeepinV23的一个新选择

UbuntuDDE 23.04发布&#xff0c;体验DeepinV23的一个新选择 昨晚网上搜索了一圈&#xff0c;无意看到邮箱一条新闻&#xff0c;UbuntuDDE 23.04发布了 因为前几天刚用虚拟机安装过&#xff0c;所以麻溜的从网站下载了ISO文件&#xff0c;安装上看看。本来没多想&#xff0c;…

什么是字体图标(Icon Font)?如何在网页中使用字体图标?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 字体图标&#xff08;Icon Font&#xff09;⭐ 如何在网页中使用字体图标⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…

9.4 集成功率放大电路

OTL、OCL 和 BTL 电路均有各种不同输出功率和不同电压增益的集成电路。应当注意&#xff0c;在使用 OTL 电路时&#xff0c;需外接输出电容。为了改善频率特性&#xff0c;减小非线性失真&#xff0c;很多电路内部还引入深度负反馈。这里以低频功放为例。 一、集成功率放大电路…

【C++】详解声明和定义

2023年8月28日&#xff0c;周一下午 研究了一个下午才彻底弄明白... 写到晚上才写完这篇博客。 目录 声明和定义的根本区别结构体的声明和定义声明结构体 定义结构体类的声明和定义函数的定义和声明声明函数 定义函数变量声明和定义声明变量定义变量 声明和定义的根本区别 …

全景图像生成算法

摘要 全景图像生成是计算机视觉领域的一个重要研究方向。本文对五种经典的全景图像生成算法进行综述&#xff0c;包括基于相机运动估计的算法、基于特征匹配的算法、基于图像切割的算法、基于多项式拟合的算法和基于深度学习的算法。通过对这些算法的原理、优缺点、适用场景等…

14-redis

一 Redis概述 1 为什么要用NoSQL 单机Mysql的美好年代 在90年代&#xff0c;一个网站的访问量一般都不大&#xff0c;用单个数据库完全可以 轻松应付。在那个时候&#xff0c;更多的都是静态网页&#xff0c;动态交互类型的网站不多。 遇到问题&#xff1a; 随着用户数的增长…

【建议收藏】Kubernetes 网络策略入门:概念、示例和最佳实践,附云原生资料

目录 摘要 一、Kubernetes 网络策略组件 二、实施网络策略 示例 1&#xff1a;在命名空间中限制流量 示例 2&#xff1a;允许特定 Pod 的流量 示例 3&#xff1a;在单个策略中组合入站和出站规则 示例 4&#xff1a;阻止对特定 IP 范围的出站流量 三、Kubernetes 网络策…

R包开发-2.2:在RStudio中使用Rcpp制作R-Package(更新于2023.8.23)

目录 4-添加C函数 5-编辑元数据 6-启用Roxygen&#xff0c;执行文档化。 7-单元测试 8-在自己的计算机上安装R包&#xff1a; 9-程序发布 参考&#xff1a; 为什么要写这篇文章的更新日期&#xff1f;因为R语言发展很快&#xff0c;很多函数或者方式&#xff0c;现在可以使…