珠海服务好的网站建设网站建设要托管服务器
- 作者: 五速梦信息网
- 时间: 2026年03月21日 05:05
当前位置: 首页 > news >正文
珠海服务好的网站建设,网站建设要托管服务器,网站游戏网站建设,做网站公扩散模型DDPM开源代码的剖析【对应公式与作者给的开源项目#xff0c;diffusion model】一、简介二、扩散过程#xff1a;输入是x_0和时刻num_steps#xff0c;输出是x_t三、逆扩散过程#xff1a;输入x_t#xff0c;不断采样最终输出x_0四、具体参考算法流程图五、模型mo… 扩散模型DDPM开源代码的剖析【对应公式与作者给的开源项目diffusion model】一、简介二、扩散过程输入是x_0和时刻num_steps输出是x_t三、逆扩散过程输入x_t不断采样最终输出x_0四、具体参考算法流程图五、模型model和损失函数最重要1、先看损失函数2、model看解释六、损失函数的推导一、简介 论文地址https://proceedings.neurips.cc/paper/2020/hash/4c5bcfec8584af0d967f1ab10179ca4b-Abstract.html 项目地址https://github.com/hojonathanho/diffusion 公式推导参考这篇博客https://blog.csdn.net/qq_45934285/article/details/129107994?spm1001.2014.3001.5502 本文主要对扩散模型的关键公式给出原代码帮助理解和学习。有pytorch和TensorFlow版。 原作者给的代码不太好理解给出了pytorch的好理解一些。 二、扩散过程输入是x_0和时刻num_steps输出是x_t 首先值得注意的是x_0是一个二维数组例如这里给的是一个10000行2列的数组即每一行代表一个点。 这里取了s_curve的x轴和z轴的坐标用点表示看起来就像一个s型 scurve, make_s_curve(104,noise0.1) s_curve s_curve[:,[0,2]]/10.0 dataset torch.Tensor(s_curve).float()扩散过程其实就是一个不断加噪的过程其不含参。可以给出最终公式。 xtα‾tx0xt\sqrt {\overline{\alpha} {t}}x_ {0}xtαtx0 1−α‾t\sqrt {1-\overline {\alpha} }_ {t}1−αt z‾t\overline {z}_tzt 在t不断变大的时候βt\beta_tβt越来越大αt1−βt\alpha_t1-\beta_tαt1−βt越来越小。即t增大的时候上面公式的前一项系数越来越小后一项系数越来越大不断接近一个z‾t\overline {z}_tzt的高斯分布。 代码来自diffusion_tf/diffusion_utils_2.py def q_sample(self, x_start, t, noiseNone):Diffuse the data (t 0 means diffused for 1 step)if noise is None:noise tf.random_normal(shapex_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)pytorch #计算任意时刻的x采样值基于x_0和重参数化 def q_x(x_0,t):可以基于x[0]得到任意时刻t的x[t]noise torch.randn_like(x_0)# 创建了一个与 x_0 张量具有相同形状的名为 noise 的张量并且该张量的值是从标准正态分布中随机采样得到的。alphas_t alphas_bar_sqrt[t]alphas_1_m_t one_minus_alphas_bar_sqrt[t]return (alphas_t * x_0 alphas_1_m_t * noise)#在x[0]的基础上添加噪声可见对于求xtx_txt的公式最难理解的就是代码如何实现z‾t\overline {z}_tzt在代码中是创建了一个与 x_0 张量具有相同形状*的名为 noise 的张量并且该张量的值是从标准正态分布中随机采样得到的。这个noise其元素的值是从均值为0、标准差为1的正态分布中随机采样得到的。这个张量可以被用于实现噪声注入数据增强等操作也可以被用于一些随机化的算法中。 值得一提的是原项目中用num_diffusion_timesteps1000来表示t假如num_steps100那么很多需要用到的参数都可以提前算出来。 三、逆扩散过程输入x_t不断采样最终输出x0 最终公式是 q(Xt−1∣XtX0)N(Xt−1;1αt(Xt−βt(1−αˉt)Z),1−αˉt−11−αˉtβt),Z∼N(0,I)q\left(X{t-1} \mid X{t} X{0}\right)N\left(X_{t-1} ; \frac{1}{\sqrt{\alphat}} (X{t}-\frac{\beta{t}}{\sqrt{\left(1-\bar{\alpha}{t}\right)}} Z), \frac{1-\bar{\alpha}{t-1}}{1-\bar{\alpha}{t}} \beta_{t}\right), Z \sim N(0, I) q(Xt−1∣XtX0)N(Xt−1;αt1(Xt−(1−αˉt)βtZ),1−αˉt1−αˉt−1βt),Z∼N(0,I) 在论文中方差设置为一个常数βt\beta _tβt或β~t\tilde{\beta }_tβ~t其中 β~t1−αˉt−11−αˉtβt\tilde{\beta }t\frac{1-\bar{\alpha}{t-1}}{1-\bar{\alpha}{t}} \beta{t} β~t1−αˉt1−αˉt−1βt 因此可训练的参数只存在与其均值之中。 就是这个公式方差变为βt\betatβt其中ϵθ\epsilon\thetaϵθ是模型model def p_sample(model,x,t,betas,one_minus_alphas_bar_sqrt):从x[T]采样t时刻的重构值t torch.tensor([t])coeff betas[t] / one_minus_alphas_bar_sqrt[t]eps_theta model(x,t)mean (1/(1-betas[t]).sqrt())(x-(coeff*eps_theta))z torch.randn_like(x)sigma_t betas[t].sqrt()sample mean sigma_t * zreturn (sample)代码来自diffusion_tf/diffusion_utils_2.py def p_sample(self, denoise_fn, *, x, t, noise_fn, clip_denoisedTrue, return_pred_xstart: bool):Sample from the modelmodel_mean, _, model_log_variance, pred_xstart self.p_mean_variance(denoise_fn, xx, tt, clip_denoisedclip_denoised, return_pred_xstartTrue)noise noise_fn(shapex.shape, dtypex.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))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 sample循环恢复。 可见初始的x_t完全是一个随机噪声。torch.randn(shape) cur_x可以看做是一个当前的采样是一个二维数组就是上面说的10000行2列。 然后x_seq可以看做是一个三维数组即元素为cur_x的一个数组。 i是时刻从n_steps的反向开始。 def p_sample_loop(model,shape,n_steps,betas,one_minus_alphas_bar_sqrt):从x[T]恢复x[T-1]、x[T-2]|…x[0]cur_x torch.randn(shape)x_seq [cur_x]for i in reversed(range(n_steps)):cur_x p_sample(model,cur_x,i,betas,one_minus_alphas_bar_sqrt)x_seq.append(cur_x)return x_seq代码来自diffusion_tf/diffusion_utils_2.py def p_sample_loop(self, denoise_fn, *, shape, noise_fntf.random_normal):Generate samplesassert isinstance(shape, (tuple, list))i_0 tf.constant(self.num_timesteps - 1, dtypetf.int32)img_0 noisefn(shapeshape, dtypetf.float32), img_final tf.whileloop(condlambda i, _: tf.greaterequal(i, 0),bodylambda i, img: [i_ - 1,self.p_sample(denoise_fndenoisefn, ximg, ttf.fill([shape[0]], i_), noise_fnnoise_fn, return_pred_xstartFalse)],loop_vars[i_0, img_0],shape_invariants[i_0.shape, img_0.shape],back_propFalse)assert img_final.shape shapereturn img_final那么最终得到的x_seq就是最终从噪声恢复出的x_T到x_0序列。 恢复图像过程中利用了 βt\beta_tβt数组其可以引申出很多参数(带α\alphaα的)num_steps即时刻。一个model 参数只有model那么我们来看model到底是什么。 四、具体参考算法流程图 五、模型model和损失函数最重要 1、先看损失函数 其中x_0就是一个batch的数据batch_size取x_0的行数就是batch_size 值得注意的是这里t是一个列向量那么a也是一个列向量其与x_0相乘的时候用了广播机制第二列完全复制第一列然后与x_0对应位置上的元素相乘。 def diffusion_loss_fn(model,x_0,alphas_bar_sqrt,one_minus_alphas_bar_sqrt,n_steps):对任意时刻t进行采样计算lossbatch_size x_0.shape[0] #对一个batchsize样本生成随机的时刻t 覆盖到更多不同的tt torch.randint(0,n_steps,size(batch_size//2,))t torch.cat([t,n_steps-1-t],dim0)# [batchsize]行向量t t.unsqueeze(-1)#压缩最后的时刻1[batchsize1]列向量 #x0的系数a alphas_bar_sqrt[t] #eps的系数aml one_minus_alphas_bar_sqrt[t] #生成随机噪音epse torch.randn_like(x_0) #构造模型的输入x x_0*ae*aml #送入模型得到t时刻的随机噪声预测值output model(x,t.squeeze(-1)) #这里t又变为一维向量[batchsize] #与真实噪声一起计算误差求平均值return (e - output).square().mean()其调用过程见 重要的batch_x是dataset的一个batch_size行的数据。例如dataset是10000行batch_size128那么batch_x是dataset的128行。需要注意的是如果 dataset 的大小不能被 batch_size 整除那么最后一个批次的大小可能会小于 batch_size。即一个epoch的batch数量为dataset.size()/batch_size向上取整。 dataloader torch.utils.data.DataLoader(dataset,batch_sizebatch_size,shuffleTrue) for idx,batch_x in enumerate(dataloader):loss diffusion_loss_fn(model,batch_x,alphas_bar_sqrt,one_minus_alphas_bar_sqrt,num_steps)dataloader这行代码是使用 PyTorch 中的 DataLoader 函数来创建一个数据加载器对象。这个对象可以用来迭代访问输入数据以便将其输入到神经网络中进行训练或评估。 dataset一个包含输入数据和对应标签的数据集对象。这个对象需要实现 getitem 和 len 方法以便能够通过索引或长度访问数据集中的数据。 batch_size一个整数值表示每个批次的数据量。 shuffle一个布尔值表示是否需要在每个 epoch 开始前随机打乱数据集中的数据。 这个函数返回的是一个数据加载器对象可以通过迭代器的方式来访问其中的数据。例如可以使用 for 循环来遍历整个数据集每次迭代会返回一个批次的数据和对应的标签。这样就可以方便地将数据输入到神经网络中进行训练或评估。 for idx,batch_x in enumerate(dataloader):这行代码是使用 enumerate 函数和 DataLoader 对象来遍历整个数据集并按照 batch_size 的大小分成若干批次进行迭代。 具体来说enumerate 函数用于同时返回迭代对象中的元素以及它们的索引。在这里dataloader 对象就是要被迭代的对象而 idx 变量则表示当前迭代的批次索引。batch_x 变量则是当前批次中的输入数据它是一个包含 batch_size 个样本的张量对象。 需要注意的是在使用 enumerate 函数时可以通过设置 start 参数来指定起始索引的值默认为 0。例如如果设置 start1那么第一个迭代的索引就是 1 而不是 0 2、model看解释 这里给出了一个比较简单的model论文中使用的是Unet结构的模型。具体可以参考https://nn.labml.ai/diffusion/ddpm/unet.html 具体训练过程可以参考https://nn.labml.ai/diffusion/ddpm/experiment.html import torch import torch.nn as nnclass MLPDiffusion(nn.Module):def init(self,n_steps,num_units128):super(MLPDiffusion,self).init()self.linears nn.ModuleList([nn.Linear(2,num_units),nn.ReLU(),nn.Linear(num_units,num_units),nn.ReLU(),nn.Linear(num_units,num_units),nn.ReLU(),nn.Linear(num_units,2),])self.step_embeddings nn.ModuleList([nn.Embedding(n_steps,num_units),nn.Embedding(n_steps,num_units),nn.Embedding(n_steps,num_units),])
第6步的modeldef forward(self,x,t):
x x_0for idx,embedding_layer in enumerate(self.step_embeddings):t_embedding embedding_layer(t)x self.linears2*idxx t_embeddingx self.linears2*idx1x self.linears-1return x首先
batch_size 128 dataloader torch.utils.data.DataLoader(dataset,batch_sizebatch_size,shuffleTrue) num_epoch 4000 # 4000个散点图 plt.rc(text,colorblue) model MLPDiffusion(num_steps)#输出维度是2输入是x和step optimizer torch.optim.Adam(model.parameters(),lr1e-3)然后训练这个model for t in range(num_epoch):for idx,batch_x in enumerate(dataloader):loss diffusion_loss_fn(model,batch_x,alphas_bar_sqrt,one_minus_alphas_bar_sqrt,num_steps)optimizer.zero_grad()loss.backward()torch.nn.utils.clip_gradnorm(model.parameters(),1.)optimizer.step()该模型的参数包括多个线性层和Embedding层的权重和偏置在代码中用nn.ModuleList保存。在优化器更新时通过model.parameters()方法获取所有可更新的参数包括线性层和Embedding层的权重和偏置。因此优化器更新的参数就是这些权重和偏置。 全连接层可以对输入数据进行线性变换并输出与变换后数据维度相同的结果。例如对于输入向量 xxx全连接层可以通过将其与权重矩阵 WWW 相乘加上偏置向量 bbb并应用某种非线性激活函数 σ\sigmaσ来计算输出向量 yyy yσ(Wxb)y \sigma(Wx b)yσ(Wxb) 更新的是这个W和b Embedding 的参数也是模型中需要被训练的权重矩阵它的维度是 (vocab_size, embedding_dim)其中 vocab_size 是词汇表大小embedding_dim 是词嵌入的维度。Embedding 的参数在训练过程中被不断地更新以最小化模型在训练集上的损失函数。每个词都被编码成一个 embedding_dim 维的向量这些向量将作为输入传递到后续的网络层中。Embedding 层通过学习将每个词映射到一个低维空间中的向量表示从而使得相似的词在这个向量空间中也更加接近提高了模型的泛化能力。 更新的是(vocab_size, embedding_dim) optimizer.zero_grad()的作用是将模型参数的梯度清零。在每次反向传播计算梯度之前需要先清除之前的梯度否则之前计算的梯度会累加到当前计算中导致梯度计算出错。因此在每次训练之前需要调用zero_grad()来清除梯度。 loss.backward()是PyTorch中用于计算梯度的函数。在神经网络训练中首先需要将输入数据通过前向传递计算出预测值然后根据预测值和真实标签计算出损失函数值。接下来需要计算损失函数对于模型参数的梯度以便使用优化算法对参数进行更新。loss.backward()函数的作用就是计算损失函数对于所有需要梯度的参数的导数。在调用该函数之前需要将所有需要梯度计算的参数设置requires_gradTrue。该函数计算得到的梯度会保存在参数的.grad属性中。通常计算完梯度后需要对其进行裁剪以避免梯度爆炸问题然后使用优化器对模型参数进行更新。 torch.nn.utils.clip_gradnorm()是PyTorch中用于梯度裁剪的函数。梯度裁剪是一种防止梯度爆炸的技术它限制了梯度的最大范数从而避免梯度值过大。函数的第一个参数是一个可迭代对象通常是模型的参数列表第二个参数是梯度的最大范数。在该代码中model.parameters()返回模型的参数列表1.指定了梯度的最大范数为1。因此该函数的作用是将模型参数的梯度限制在最大范数为1的范围内。梯度裁剪通常在计算梯度后和参数更新之前进行以保证梯度不会过大。 optimizer.step()是PyTorch中用于更新模型参数的函数。在每次梯度计算之后需要使用优化器来更新模型的参数。优化器根据梯度和学习率等参数来计算参数更新的值并将计算得到的值应用到模型参数中。调用optimizer.step()函数可以实现该操作。该函数会更新优化器内部的参数状态以便下一次迭代使用。 在Python中super() 函数是用来调用父类(超类)的一个方法。在面向对象编程中通常使用 super() 函数来初始化父类的构造方法。在这里super(MLPDiffusion,self).init() 调用了父类 nn.Module 的构造函数相当于显式调用 nn.Module 的构造函数初始化了当前类 MLPDiffusion 的基类 nn.Module。这样做是为了确保子类继承父类中的属性和方法并且能够正确地使用它们。 for idx,embedding_layer in enumerate(self.step_embeddings):这行代码是在遍历self.step_embeddings列表中的每个embedding层同时记录下每个embedding层在列表中的索引idx。 在MLPDiffusion模型的forward函数中self.step_embeddings是一个由三个Embedding层组成的ModuleList每个Embedding层的作用是将当前时间步t转化为一个num_units维的向量。在模型的forward函数中需要遍历这三个Embedding层并将其输出的向量与模型的输入x相加。这样做的目的是为了将当前时间步t的信息融入到模型的计算中。因此遍历每个Embedding层并将其输出的向量与模型的输入x相加是非常必要的。 x self.linears2*idx这行代码的作用是对模型的输入x进行线性变换即将x通过一个全连接层线性层进行变换。其中2idx表示要使用第idx个Embedding层的输出而self.linears[2idx]则表示要使用与之对应的全连接层。 需要注意的是由于self.linears是一个由多个层组成的ModuleList而不是一个单独的层因此需要通过下标来获取其中的某个层。2*idx表示要使用第idx个Embedding层的输出因为每个Embedding层输出的维度都是num_units所以输入到全连接层的维度也是num_units。这里采用的激活函数是ReLU。 第idx个Embedding层的输出是一个维度为batch_sizenum_units的张量表示对输入的时间步t进行了嵌入embedding后的结果。其中batch_size表示输入数据的批次大小numunits是预定义的嵌入向量的维度这里为128。Embedding层将整数编码转换为密集向量这些密集向量在整个模型的训练过程中逐渐学习得到类似于单词的词向量。在本模型中使用三个Embedding层分别嵌入了当前时间步t前一时间步t-1和后一时间步t1这些嵌入向量会在全连接层中与输入向量x进行加权求和以产生输出。 x self.linears-1这行代码对应的是在模型的最后一层加上一个全连接层输出维度为2。该全连接层对前面所有层的输出进行线性变换并输出一个维度为2的向量作为最终的预测值。 ReLU它是一个激活函数用于在神经网络的前向传播过程中对输入进行非线性变换。ReLU函数的形式为f(x)max(0,x)f(x) \max(0, x)f(x)max(0,x)可以将输入的负值部分清零保留正值部分。在反向传播中ReLU层的导数可以被有效地计算因此可以通过反向传播算法对模型的其他参数进行更新。 六、损失函数的推导 我们根据负对数似然优化 ELBO来自简森不等式。 E[−logpθ(x0)]≤Eq[−logpθ(x0:T)q(x1:T∣x0)]L\mathbb{E}[-\log \textcolor{lightgreen}{p\theta}(x_0)] \le \mathbb{E}q [ -\log \frac{\textcolor{lightgreen}{p\theta}(x{0:T})}{q(x{1:T}|x_0)} ] \ L E[−logpθ(x0)]≤Eq[−logq(x1:T∣x0)pθ(x0:T)]L 损失可以改写如下。 LEq[−logpθ(x0:T)q(x1:T∣x0)]Eq[−logp(xT)−∑t1Tlogpθ(xt−1∣xt)q(xt∣xt−1)]Eq[−logp(xT)q(xT∣x0)−∑t2Tlogpθ(xt−1∣xt)q(xt−1∣xt,x0)−logpθ(x0∣x1)]Eq[DKL(q(xT∣x0)∥p(xT))∑t2TDKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt))−logpθ(x0∣x1)]L \mathbb{E}q [ -\log \frac{\textcolor{lightgreen}{p\theta}(x{0:T})}{q(x{1:T}|x_0)} ] \ \mathbb{E}_q [ -\log p(xT) - \sum{t1}^T \log \frac{\textcolor{lightgreen}{p\theta}(x{t-1}|x_t)}{q(xt|x{t-1})} ] \ \mathbb{E}_q [ -\log \frac{p(x_T)}{q(x_T|x0)} -\sum{t2}^T \log \frac{\textcolor{lightgreen}{p\theta}(x{t-1}|xt)}{q(x{t-1}|x_t,x0)} -\log \textcolor{lightgreen}{p\theta}(x_0|x_1)] \ \mathbb{E}q [ D{KL}(q(x_T|x_0) \Vert p(xT)) \sum{t2}^T D{KL}(q(x{t-1}|x_t,x0) \Vert \textcolor{lightgreen}{p\theta}(x_{t-1}|xt)) -\log \textcolor{lightgreen}{p\theta}(x_0|x1)] LEq[−logq(x1:T∣x0)pθ(x0:T)]Eq[−logp(xT)−t1∑Tlogq(xt∣xt−1)pθ(xt−1∣xt)]Eq[−logq(xT∣x0)p(xT)−t2∑Tlogq(xt−1∣xt,x0)pθ(xt−1∣xt)−logpθ(x0∣x1)]Eq[DKL(q(xT∣x0)∥p(xT))t2∑TDKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt))−logpθ(x0∣x1)] DKL(q(xT∣x0)∥p(xT))D{KL}(q(x_T|x_0) \Vert p(x_T))DKL(q(xT∣x0)∥p(xT)) 是常数因为我们保持 β1,…,βT\beta_1, \dots, \betaTβ1,…,βT 不变。 计算 Lt−1DKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt))L{t-1} D{KL}(q(x{t-1}|x_t,x0) \Vert \textcolor{lightgreen} {p\theta}(x_{t-1}| x_t))Lt−1DKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt)) 以 x0x0x0 为条件的前向过程后验是 q(xt−1∣xt,x0)N(xt−1;μ~t(xt,x0),β~tI)μ~t(xt,x0)αˉt−1βt1−αˉtx0αt(1−αˉt−1)1−αˉtxtβ~t1−αˉt−11−αˉtβtq(x{t-1}|x_t, x0) \mathcal{N} \Big(x{t-1}; \tilde\mu_t(x_t, x_0), \tilde\beta_t \mathbf{I} \Big) \ \tilde\mu_t(x_t, x0) \frac{\sqrt{\bar\alpha{t-1}}\beta_t}{1 - \bar\alpha_t}x_0 \frac{\sqrt{\alphat}(1 - \bar\alpha{t-1})}{1-\bar\alpha_t}x_t \ \tilde\betat \frac{1 - \bar\alpha{t-1}}{1 - \bar\alpha_t} \betat q(xt−1∣xt,x0)N(xt−1;μ~t(xt,x0),β~tI)μ~t(xt,x0)1−αˉtαˉt−1βtx01−αˉtαt(1−αˉt−1)xtβ~t1−αˉt1−αˉt−1βt 该论文设置 Σθ(xt,t)σt2I\textcolor{lightgreen}{\Sigma\theta}(x_t, t) \sigma_t^2 \mathbf{I}Σθ(xt,t)σt2I 其中 σt2\sigma_t^2σt2 设置为常量 βt\beta_tβt 或 β~t\tilde\betatβ~t。 然后, pθ(xt−1∣xt)N(xt−1;μθ(xt,t),σt2I)\textcolor{lightgreen}{p\theta}(x_{t-1} | xt) \mathcal{N}\big(x{t-1}; \textcolor{lightgreen}{\mu_\theta}(x_t, t), \sigma_t^2 \mathbf{I} \big)pθ(xt−1∣xt)N(xt−1;μθ(xt,t),σt2I) 对于给定噪声 ϵ∼N(0,I)\epsilon\sim\mathcal{N}(\mathbf{0}, \mathbf{I})ϵ∼N(0,I) 使用 q(xt∣x0)q(x_t|x_0)q(xt∣x0) xt(x0,ϵ)αˉtx01−αˉtϵx01αˉt(xt(x0,ϵ)−1−αˉtϵ)x_t(x_0, \epsilon) \sqrt{\bar\alpha_t} x_0 \sqrt{1-\bar\alpha_t}\epsilon \ x_0 \frac{1}{\sqrt{\bar\alpha_t}} \Big(x_t(x_0, \epsilon) - \sqrt{1-\bar\alphat}\epsilon\Big) xt(x0,ϵ)αˉtx01−αˉtϵx0αˉt1(xt(x0,ϵ)−1−αˉtϵ) 这给出了 Lt−1DKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt))Eq[12σt2∥μ~(xt,x0)−μθ(xt,t)∥2]Ex0,ϵ[12σt2∥1αt(xt(x0,ϵ)−βt1−αˉtϵ)−μθ(xt(x0,ϵ),t)∥2]L{t-1} D{KL}(q(x{t-1}|x_t,x0) \Vert \textcolor{lightgreen}{p\theta}(x_{t-1}|x_t)) \ \mathbb{E}_q \Bigg[ \frac{1}{2\sigma_t^2} \Big \Vert \tilde\mu(x_t, x0) - \textcolor{lightgreen}{\mu\theta}(xt, t) \Big \Vert^2 \Bigg] \ \mathbb{E}{x_0, \epsilon} \Bigg[ \frac{1}{2\sigma_t^2} \bigg\Vert \frac{1}{\sqrt{\alpha_t}} \Big( x_t(x_0, \epsilon) - \frac{\beta_t}{\sqrt{1 - \bar\alphat}} \epsilon \Big) - \textcolor{lightgreen}{\mu\theta}(x_t(x0, \epsilon), t) \bigg\Vert^2 \Bigg] \ Lt−1DKL(q(xt−1∣xt,x0)∥pθ(xt−1∣xt))Eq[2σt21μ(xt,x0)−μθ(xt,t)2]Ex0,ϵ[2σt21αt1(xt(x0,ϵ)−1−αˉtβtϵ)−μθ(xt(x0,ϵ),t)2] 使用模型重新参数化以预测噪声 μθ(xt,t)μ(xt,1αˉt(xt−1−αˉtϵθ(xt,t)))1αt(xt−βt1−αˉtϵθ(xt,t))\textcolor{lightgreen}{\mu\theta}(x_t, t) \tilde\mu \bigg(x_t, \frac{1}{\sqrt{\bar\alpha_t}} \Big(x_t - \sqrt{1-\bar\alphat}\textcolor{lightgreen}{\epsilon\theta}(x_t, t) \Big) \bigg) \ \frac{1}{\sqrt{\alpha_t}} \Big(x_t - \frac{\beta_t}{\sqrt{1-\bar\alphat}}\textcolor{lightgreen}{\epsilon\theta}(xt, t) \Big) μθ(xt,t)μ~(xt,αˉt1(xt−1−αˉtϵθ(xt,t)))αt1(xt−1−αˉtβtϵθ(xt,t)) 其中 ϵθ\epsilon\thetaϵθ 是一个学习函数它在给定 (xt,t)(xt, t)(xt,t) 的情况下预测 ϵ\epsilonϵ。 这给出了 Lt−1Ex0,ϵ[βt22σt2αt(1−αˉt)∥ϵ−ϵθ(αˉtx01−αˉtϵ,t)∥2]L{t-1} \mathbb{E}_{x_0, \epsilon} \Bigg[ \frac{\beta_t^2}{2\sigma_t^2 \alpha_t (1 - \bar\alphat)} \Big\Vert \epsilon - \textcolor{lightgreen}{\epsilon\theta}(\sqrt{\bar\alpha_t} x_0 \sqrt{1-\bar\alphat}\epsilon, t) \Big\Vert^2 \Bigg] Lt−1Ex0,ϵ[2σt2αt(1−αˉt)βt2ϵ−ϵθ(αˉtx01−αˉtϵ,t)2] 也就是说我们正在训练预测噪声。 Simplified loss Lsimple(θ)Et,x0,ϵ[∥ϵ−ϵθ(αˉtx01−αˉtϵ,t)∥2]L{\text{simple}}(\theta) \mathbb{E}_{t,x0, \epsilon} \Bigg[ \bigg\Vert \epsilon - \textcolor{lightgreen}{\epsilon\theta}(\sqrt{\bar\alpha_t} x_0 \sqrt{1-\bar\alphat}\epsilon, t) \bigg\Vert^2 \Bigg]Lsimple(θ)Et,x0,ϵ[ϵ−ϵθ(αˉtx01−αˉtϵ,t)2] 这最小化 −logpθ(x0∣x1)-\log \textcolor{lightgreen}{p\theta}(x_0|x1)−logpθ(x0∣x1) when t1t1t1 和 Lt−1L{t-1}Lt−1 for t1t\gt1t1 丢弃 在 Lt−1L_{t-1}Lt−1 中加权。丢弃权重 βt22σt2αt(1−αˉt)\frac{\beta_t^2}{2\sigma_t^2 \alpha_t (1 - \bar\alpha_t)}2σt2αt(1−αˉt)βt2 增加赋予较高 ttt具有较高噪声水平的权重从而提高样本质量。 如果觉得有帮助的话记得点赞收藏支持一下哦。如果有问题请在评论区一起交流讨论。 Reference https://www.bilibili.com/video/BV1b541197HX/?spm_id_from333.999.0.0 https://nn.labml.ai/diffusion/ddpm/index.html
- 上一篇: 珠海定制网站建设推广常州辉煌网络网站建设
- 下一篇: 珠海高端网站建设报价超级简历网站
相关文章
-
珠海定制网站建设推广常州辉煌网络网站建设
珠海定制网站建设推广常州辉煌网络网站建设
- 技术栈
- 2026年03月21日
-
珠海策划网站建设平台网站微信建设经验
珠海策划网站建设平台网站微信建设经验
- 技术栈
- 2026年03月21日
-
珠海策划网站建设平台丹徒网站建设报价
珠海策划网站建设平台丹徒网站建设报价
- 技术栈
- 2026年03月21日
-
珠海高端网站建设报价超级简历网站
珠海高端网站建设报价超级简历网站
- 技术栈
- 2026年03月21日
-
珠海工程建设信息网站win2003 wordpress
珠海工程建设信息网站win2003 wordpress
- 技术栈
- 2026年03月21日
-
珠海公司网站设计wordpress汉语插件
珠海公司网站设计wordpress汉语插件
- 技术栈
- 2026年03月21日
