机器学习周报十三
摘要
本周学习了DDPM和unet,只是对数学原理的简单理解,因为DDPM原始论文的数学推导十分复杂,只能由易到难。
Abstract
This week I studied DDPM and U-Net, but only have a simple understanding of the mathematical principles, as the mathematical derivation in the original DDPM paper is very complex and can only be approached gradually from easy to difficult.
###1扩散模型
1.1 定义
生成模型的目标是学习一个数据的真实分布,从而生成新的、与真实数据相似的数据。常见的生成模型有GAN和VAE,2020年,DDPM被提出,被称为扩散模型,同样可以用于图像生成。
扩散模型是从噪声生成目标数据样本。
模型包括两个过程:前向和反向过程,其中前向过程称为扩散。反向用于生成数据样本。
1.2 前置知识
1.2.1 概率
随机实验:在相同条件下,对随机现象进行的大量重复观测。例如抛骰子,观察点数;
先验概率(根据过往经验和分析得到的概率):q(xt∣xt−1)q(x_t|x_{t-1})q(xt∣xt−1),给定前一时刻的xt−1x_{t-1}xt−1预测当前时刻xtx_txt的概率。
后验概率(在得到结果后重新修正的概率):q(xt−1∣xt)q(x_{t-1}|x_t)q(xt−1∣xt),给定当前时刻的xtx_txt预测当前时刻xt−1x_{t-1}xt−1的概率。
贝叶斯公式:P(A∣B)=P(AB)P(B)P(A|B)=\frac{P(AB)}{P(B)}P(A∣B)=P(B)P(AB)为事件B发生的条件下,事件A发生的条件概率。P(AB)P(AB)P(AB)为既发生A事件又发生B事件的概率。P(AB)=P(B∣A)P(A),P(A∣B)=P(B∣A)P(A)P(B)P(AB)=P(B|A)P(A),P(A|B)=\frac{P(B|A)P(A)}{P(B)}P(AB)=P(B∣A)P(A),P(A∣B)=P(B)P(B∣A)P(A)
已知事件C的情况下,条件概率变为P(A∣B,C)=P(B∣A,C)P(A∣C)P(B∣C)P(A|B,C)=\frac{P(B|A,C)P(A|C)}{P(B|C)}P(A∣B,C)=P(B∣C)P(B∣A,C)P(A∣C)
1.2.2 统计
期望:一个随机变量x,在取不同值时的概率函数为f(x)f(x)f(x),对不同取值,需要根据概率进行加权
E(x)=μ=∑xf(x)E(x)=\mu=\sum xf(x)E(x)=μ=∑xf(x)
方差:用于表示数据的分散程度,数据波动越大,方差越大,其中σ\sigmaσ为标准差,标准差时方差的算术平方根
Var(x)=σ2=∑(x−μ)2f(x)Var(x)=\sigma^2=\sum (x-\mu)^2f(x)Var(x)=σ2=∑(x−μ)2f(x)
若一个随机变量XXX服从一个位置参数μ\muμ和尺度参数σ\sigmaσ的概率分布,且其概率密度函数为
f(x)=12πσexp(−(x−μ)22σ2)f(x)=\frac{1}{\sqrt{2\pi \sigma}}exp(-\frac{(x-\mu)^2}{2\sigma^2})f(x)=2πσ1exp(−2σ2(x−μ)2)
则称这个随机变量为正态随机变量,服从的正态分布,记作X−N(μ,σ2)X - N(\mu,\sigma^2)X−N(μ,σ2)
对aX+b∼N(aμ+b,a2,σ2)aX+b\sim N(a\mu+b,a^2,\sigma^2)aX+b∼N(aμ+b,a2,σ2)
对于X1∼N(μ1,σ1),X2−N(μ2,σ2)X_1\sim N(\mu_1,\sigma_1),X_2-N(\mu_2,\sigma_2)X1∼N(μ1,σ1),X2−N(μ2,σ2),则二者进行叠加仍是高斯分布,且
X1+X2∼N(μ1+μ2,σ12+σ22)X_1+X_2 \sim N(\mu_1+\mu_2,\sigma_1^2+\sigma_2^2)X1+X2∼N(μ1+μ2,σ12+σ22)
#####1.2.3马尔科夫链
随机过程:一串随机变量的序列,在这个序列当中,每个数据都可以看作是一个随机变量。例如某十字路口每分钟通过的车辆数量构成的序列。
马尔科夫链:状态空间中经过一个状态到另一个状态的转换的随机过程,该过程无记忆性,下一状态的概率分布只由当前状态决定,在时间序列中它前面的事件均与之无关。
图1.1 马尔科夫链
#####1.2.4 unet
一个 基于深度学习的卷积神经网络 ,主要用于图像分割任务,特别是生物医学图像的分割。它由编码器(下采样路径)和解码器(上采样路径)两部分组成,形状呈U型,因此得名U-Net。
unet常被用于生物医学图像的像素级分类任务,输出的是每个像素点的类别,每个像素都被赋予一个特定的标签,这些标签通常以不同颜色在图像中显示,以便区分不同的类别。
编码器-解码器结构:unet采用了编码器-解码器结构, 其中编码器逐渐减小特征图的空间尺寸以捕获上下文信息,而解码器则逐渐恢复空间尺寸以精确定位每个像素的类别。
跳跃连接:unet中的跳跃连接(skip connections)将编码器的特征图直接传递给解码器,从而保留了更多的空间信息,有助于提高定位准确性。
端到端训练:unet可以直接对整个图像进行训练,而无需使用滑动窗口方法。这大大减少了计算量,提高了训练效率。
unet的工作流程:通过编码器和解码器的对称结构以及跳跃连接,实现图像分割任务。
输入与预处理:接收待分割的图像,并进行必要的预处理,如归一化、尺寸调整等,以便于网络处理。
编码器(下采样):图像通过一系列的卷积层进行特征提取。每一层都包含卷积、激活函数(如ReLU)和可能的池化操作。 随着网络的深入,特征图的尺寸逐渐减小 ,而特征通道的数量逐渐增加,从而提取到更高级别的语义信息。
解码器(上采样):解码器从编码器接收的特征图开始, 通过上采样操作(如反卷积)逐步增加特征图的尺寸。 在每一步上采样后,通过跳跃连接将编码器相应层级的特征图与解码器当前层级的特征图进行拼接。
输出与图像分割:在解码器的最后一层,使用卷积操作将特征图映射到与类别数相同数量的通道上。每个通道代表一个类别在图像中的可能性分布。 应用softmax函数或其他分类器对每个像素进行分类,生成一个与输入图像尺寸相同的分割结果图。
from PIL import Image
import os
from torch.utils.data import Dataset
from torchvision import transforms
transform = transforms.Compose([transforms.ToTensor()
])
import torch
from torch import nn
from torch.nn import functional as F
from torch.utils.data import DataLoader
from torch.optim import Adam
import os
from tqdm import tqdm
def keep_same_size(path, size=(256, 256)):img = Image.open(path)max_size = max(img.width, img.height)mask = Image.new('RGB', (max_size, max_size), (0, 0, 0))mask.paste(img, (0, 0))mask = mask.resize(size)return mask
class VocDataset(Dataset):def __init__(self, path):self.path = path# 获取训练集文件名列表self.name_list = os.listdir(os.path.join(path, 'SegmentationClass'))def __len__(self):return len(self.name_list)def __getitem__(self, index):# 获取训练集中索引为index的图像的文件名,该图像标签的文件名file_name = self.name_list[index]image_name = os.path.join(self.path, 'JPEGImages', file_name.replace('png', 'jpg'))label_name = os.path.join(self.path, 'SegmentationClass', file_name)# 读取图像并进行resize操作,将不同尺寸的图像都缩放为固定尺寸的图像,这里取256*256img = keep_same_size(image_name, (256, 256))label_img = keep_same_size(label_name, (256, 256))# 返回归一化后的图像return transform(img), transform(label_img)
class ConvBlock(nn.Module):def __init__(self, in_channel, out_channel):super(ConvBlock, self).__init__()self.layer = nn.Sequential(nn.Conv2d(in_channel, out_channel, 3, 1, 1, padding_mode='reflect', bias=False),nn.BatchNorm2d(out_channel),nn.Dropout(0.3),nn.LeakyReLU(),nn.Conv2d(out_channel, out_channel, 3, 1, 1, padding_mode='reflect', bias=False),nn.BatchNorm2d(out_channel),nn.Dropout(0.3),nn.LeakyReLU())def forward(self, x):return self.layer(x)class DownSample(nn.Module):def __init__(self, channel):super(DownSample, self).__init__()self.layer = nn.Sequential(nn.Conv2d(channel, channel, 3, 2, 1, padding_mode='reflect', bias=False),nn.BatchNorm2d(channel),nn.LeakyReLU())def forward(self, x):return self.layer(x)class UpSample(nn.Module):def __init__(self, channel):super(UpSample, self).__init__()self.layer = nn.Conv2d(channel, channel//2, 1, 1)def forward(self, x, feature_map):up = F.interpolate(x, scale_factor=2, mode='nearest')out = self.layer(up)return torch.cat((out, feature_map), dim=1)class UNet(nn.Module):def __init__(self):super(UNet, self).__init__()self.c1 = ConvBlock(3, 64)self.d1 = DownSample(64)self.c2 = ConvBlock(64, 128)self.d2 = DownSample(128)self.c3 = ConvBlock(128, 256)self.d3 = DownSample(256)self.c4 = ConvBlock(256, 512)self.d4 = DownSample(512)self.c5 = ConvBlock(512, 1024)self.u1 = UpSample(1024)self.c6 = ConvBlock(1024, 512)self.u2 = UpSample(512)self.c7 = ConvBlock(512, 256)self.u3 = UpSample(256)self.c8 = ConvBlock(256, 128)self.u4 = UpSample(128)self.c9 = ConvBlock(128, 64)self.out = nn.Conv2d(64, 3, 3, 1, 1)self.Th = nn.Sigmoid()def forward(self, x):R1 = self.c1(x)R2 = self.c2(self.d1(R1))R3 = self.c3(self.d2(R2))R4 = self.c4(self.d3(R3))R5 = self.c5(self.d4(R4))o1 = self.c6(self.u1(R5, R4))o2 = self.c7(self.u2(o1, R3))o3 = self.c8(self.u3(o2, R2))o4 = self.c9(self.u4(o3, R1))return self.Th(self.out(o4))
x_input = torch.randn(2, 3, 256, 256)
net = UNet()
print(net(x_input).shape)def train():# 设置设备device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')print(f"Using device: {device}")# 超参数设置batch_size = 4learning_rate = 1e-4num_epochs = 50save_interval = 5# 创建数据集和数据加载器train_dataset = VocDataset('/kaggle/input/voc2007/VOC2007')# 注意:在Windows上,num_workers最好设为0train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=0)# 初始化模型、损失函数和优化器model = UNet().to(device)criterion = nn.BCELoss()optimizer = Adam(model.parameters(), lr=learning_rate)# 训练循环for epoch in range(num_epochs):model.train()epoch_loss = 0.0progress_bar = tqdm(train_loader, desc=f'Epoch {epoch+1}/{num_epochs}')for batch_idx, (images, labels) in enumerate(progress_bar):images = images.to(device)labels = labels.to(device)# 前向传播outputs = model(images)loss = criterion(outputs, labels)# 反向传播和优化optimizer.zero_grad()loss.backward()optimizer.step()epoch_loss += loss.item()progress_bar.set_postfix({'Loss': f'{loss.item():.4f}'})avg_loss = epoch_loss / len(train_loader)print(f'Epoch [{epoch+1}/{num_epochs}], Average Loss: {avg_loss:.4f}')# 保存模型if (epoch + 1) % save_interval == 0:torch.save(model.state_dict(), f'unet_epoch_{epoch+1}.pth')print(f'Model saved at epoch {epoch+1}')# 保存最终模型torch.save(model.state_dict(), 'unet_final.pth')print('Training completed and final model saved.')
def test():# 设置设备device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 加载模型model = UNet().to(device)model.load_state_dict(torch.load('unet_final.pth', map_location=device))model.eval() # 设置为评估模式# 创建测试数据集test_dataset = VocDataset('/kaggle/input/voc2007/VOC2007') test_loader = DataLoader(test_dataset, batch_size=1, shuffle=False)# 创建保存结果的目录os.makedirs('results', exist_ok=True)# 测试循环with torch.no_grad():for i, (image, label) in enumerate(test_loader):image = image.to(device)# 预测output = model(image)# 将输出转换为图像output = output.squeeze().cpu().numpy() # 移除批次维度并转到CPUoutput = (output * 255).astype(np.uint8) # 转换为0-255范围output = np.transpose(output, (1, 2, 0)) # 从(C, H, W)转换为(H, W, C)# 保存结果output_img = Image.fromarray(output)output_img.save(f'results/result_{i}.png')# 同时保存原始图像和标签以供比较original = image.squeeze().cpu().numpy()original = (original * 255).astype(np.uint8)original = np.transpose(original, (1, 2, 0))Image.fromarray(original).save(f'results/original_{i}.png')label_img = label.squeeze().cpu().numpy()label_img = (label_img * 255).astype(np.uint8)label_img = np.transpose(label_img, (1, 2, 0))Image.fromarray(label_img).save(f'results/label_{i}.png')print(f'Processed image {i+1}/{len(test_loader)}')
train()
test()
2DDPM
图2.1 DDPM
DDPM包含两个步骤,前向加噪和后向去噪
2.1 前向加噪
从x0x_0x0到xTx_TxT的过程就是前向加噪过程,对原始图片x0x_0x0进行操作,使其变得模糊,去噪就类似还原过程。
论文中加入的噪声是正态分布的。往图片加入噪声,图片就会变得很模糊接近纯噪声,纯噪声代表多样性,去噪时会产生更多样的图片。
x0x_0x0是原始图片,其满足初始分布q(x0)q(x_0)q(x0),即x0−q(x0)x_0-q(x_0)x0−q(x0)
对于t∈[1,T]t\in [1,T]t∈[1,T]时刻,xtx_txt和xt−1x_{t-1}xt−1满足如下关系
xt=1−βtxt−1+βtϵx_t=\sqrt{1-\beta_t}x_{t-1}+\sqrt{\beta_t}\epsilonxt=1−βtxt−1+βtϵ
ϵ∼N(0,1)\epsilon \sim N(0,1)ϵ∼N(0,1)
令αt=1−βt\alpha_t=1-\beta_tαt=1−βt,则公式变形为
xt=αtxt−1+1−αtϵx_t=\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}\epsilonxt=αtxt−1+1−αtϵ
其中的βt\beta_tβt是固定常数,随着t的增加而增加
xt=αtxt−1+1−αtϵ=αt(αt−1xt−2+1−αt−1ϵ)+1−αtϵ=αtαt−1xt−2+αt1−αt−1+1−αtϵx_t =\sqrt{\alpha_t}x_{t-1}+\sqrt{1-\alpha_t}\epsilon =\sqrt{\alpha_t}(\sqrt{\alpha_{t-1}}x_{t-2}+\sqrt{1-\alpha_{t-1}}\epsilon )+\sqrt{1-\alpha_t}\epsilon \\ = \sqrt{\alpha_t\alpha_{t-1}}x_{t-2}+\sqrt{\alpha_t}\sqrt{1-\alpha_{t-1}}+\sqrt{1-\alpha_t}\epsilonxt=αtxt−1+1−αtϵ=αt(αt−1xt−2+1−αt−1ϵ)+1−αtϵ=αtαt−1xt−2+αt1−αt−1+1−αtϵ
由正态分布的叠加性,αt1−αt−1ϵ+1−αtϵ\sqrt{\alpha_t}{\sqrt {1-\alpha_{t-1}}}\epsilon+\sqrt{1-\alpha_t}\epsilonαt1−αt−1ϵ+1−αtϵ可以看作
X1∼αt1−αt−1θ=N(0,αt(1−αt−1))X2∼1−αtθ=N(0,1−αt)X1+X2=N(0,1−αtαt−1)\begin{aligned}X_1 \sim \sqrt{\alpha_t}\sqrt{1-\alpha_{t-1}}\theta &=N(0,\alpha_t(1-\alpha_{t-1}))\\ X_2 \sim \sqrt{1-\alpha_t}\theta &=N(0,1-\alpha_t) \\ X_1+X_2&=N(0,1-\alpha_t\alpha_{t-1})\end{aligned}X1∼αt1−αt−1θX2∼1−αtθX1+X2=N(0,αt(1−αt−1))=N(0,1−αt)=N(0,1−αtαt−1)
公式则化简为xt=αtαt−1xt−2+(1−αtαt−1)ϵx_t=\sqrt{\alpha_t\alpha_{t-1}}x_{t-2}+(\sqrt{1-\alpha_t\alpha_{t-1}})\epsilonxt=αtαt−1xt−2+(1−αtαt−1)ϵ
由数学归纳法,可以进一步推导得xt=αtαt−1...α1x0+(1−αtαt−1α1)ϵx_t = \sqrt{\alpha_t\alpha_{t-1}...\alpha_1}x_{0} + (\sqrt{1-\alpha_t\alpha_{t-1}\alpha_{1}})\epsilonxt=αtαt−1...α1x0+(1−αtαt−1α1)ϵ
令αˉt=αtαt−1⋯α1\bar\alpha_t=\alpha_t\alpha_{t-1}\cdots \alpha_1αˉt=αtαt−1⋯α1,则公式简化为xt=αtˉx0+1−αtˉϵx_t = \sqrt{\bar{\alpha_t}}x_0 + \sqrt{1-\bar{\alpha_t}}\epsilonxt=αtˉx0+1−αtˉϵ
xt=αtˉx0+1−αtˉϵx_t = \sqrt{\bar{\alpha_t}}x_0 + \sqrt{1-\bar{\alpha_t}}\epsilonxt=αtˉx0+1−αtˉϵ可以求出x0x_0x0的表达式为x0=xt−1−αˉtϵαˉtx_0=\frac{x_t-\sqrt{1-\bar \alpha_t}\epsilon}{\sqrt{\bar \alpha_t}}x0=αˉtxt−1−αˉtϵ
公式化简后发现xtx_txt只和x0x_0x0及α\alphaα有关,不需要进行多次迭代。
由于βt\beta_tβt一直在变大,则αt\alpha_tαt一直在变小,则当t→T,αˉT→0t\rightarrow T,\bar \alpha_T\rightarrow 0t→T,αˉT→0,则xT→ϵx_T\rightarrow \epsilonxT→ϵ
在前向加噪的过程,进行非常多的步骤的时候(例如T=1000),最终产生的图片xTx_TxT接近于高斯分布
2.2反向去噪
最后的噪声图片xTx_TxT来自高斯分布
去噪过程中不知道上一时刻xt−1x_{t-1}xt−1的值,是需要用xtx_txt进行预测,所以只能用概率的形式,采用贝叶斯公式取尖酸后验概率P(xt−1∣xt)P(x_{t-1}|x_t)P(xt−1∣xt)
P(xt−1∣xt)=P(xt−1xt)P(xt)=P(xt∣xt−1)P(xt−1)P(xt)P(x_{t-1}|x_t) = \frac{P(x_{t-1}x_t)}{P(x_t)} = \frac{P(x_t|x_{t-1})P(x_{t-1})}{P(x_t)}P(xt−1∣xt)=P(xt)P(xt−1xt)=P(xt)P(xt∣xt−1)P(xt−1)
在已知原图x0x_0x0的情况下,进行公式改写
$P(x_{t-1}|x_t,x_0) = \frac{P(x_t|x_{t-1},x_0)P(x_{t-1}|x_0)}{P(x_t|x_0)} \$
等式右边部分都变成先验概率,由xt=αtˉx0+1−αtˉϵx_t = \sqrt{\bar{\alpha_t}}x_0 + \sqrt{1-\bar{\alpha_t}}\epsilonxt=αtˉx0+1−αtˉϵ和xt=1−βtxt−1+βtϵx_t = \sqrt{1-\beta_t}x_{t-1} + \sqrt{\beta_t}\epsilonxt=1−βtxt−1+βtϵ
P(xt−1∣xt,x0)=N(αtxt−1,1−αt)N(αt−1ˉx0,1−αt−1ˉ)N(αtˉx0,1−αtˉ)P(x_{t-1}|x_t,x_0) = \frac{N(\sqrt{\alpha_t}x_{t-1},1-\alpha_t) N(\sqrt{\bar{\alpha_{t-1}}}x_0,1-\bar{\alpha_{t-1}})}{N(\sqrt{\bar{\alpha_{t}}}x_0,1-\bar{\alpha_{t}})}P(xt−1∣xt,x0)=N(αtˉx0,1−αtˉ)N(αtxt−1,1−αt)N(αt−1ˉx0,1−αt−1ˉ)
展开
P(xt−1∣xt,x0)∝exp−12[(xt−αtxt−1)21−αt+(xt−1−αt−1ˉx0)21−αt−1ˉ−(xt−αtˉx0)21−αtˉ]P(x_{t-1}|x_t,x_0) \propto exp -\frac{1}{2}[\frac{(x_t-\sqrt{\alpha_t}x_{t-1})^2}{1-\alpha_t} + \frac{(x_{t-1}-\sqrt{\bar{\alpha_{t-1}}}x_0)^2}{1-\bar{\alpha_{t-1}}} - \frac{(x_t-\sqrt{\bar{\alpha_t}}x_0)^2}{1-\bar{\alpha_t}}]P(xt−1∣xt,x0)∝exp−21[1−αt(xt−αtxt−1)2+1−αt−1ˉ(xt−1−αt−1ˉx0)2−1−αtˉ(xt−αtˉx0)2]
此时由于xt−1x_{t-1}xt−1是关注的变量,所以整理成关于xt−1x_{t-1}xt−1的形式
P(xt−1∣xt,x0)∝exp−12[(αt1−αt+11−αt−1ˉ)xt−12−(2αt1−αtxt+2αt−1ˉ1−αt−1ˉx0)xt−1+C(xt,x0)]P(x_{t-1}|x_t,x_0) \propto exp -\frac{1}{2}[(\frac{\alpha_t}{1-\alpha_t}+\frac{1}{1-\bar{\alpha_{t-1}}})x_{t-1}^2 - (\frac{2\sqrt{\alpha_t}}{1-\alpha_t}x_t+\frac{2\sqrt{\bar{\alpha_{t-1}}}}{1-\bar{\alpha_{t-1}}}x_0)x_{t-1} + C(x_t,x_0)]P(xt−1∣xt,x0)∝exp−21[(1−αtαt+1−αt−1ˉ1)xt−12−(1−αt2αtxt+1−αt−1ˉ2αt−1ˉx0)xt−1+C(xt,x0)]
其中C(xt,x0)C(x_t,x_0)C(xt,x0)与xt−1x_{t-1}xt−1无关,只影响前面的系数
标准正态分布满足∝exp−x2+μ2−2xμ2σ2\propto exp -\frac{x^2+\mu^2-2x\mu}{2\sigma^2}∝exp−2σ2x2+μ2−2xμ,则
1σ2=αt1−αt+11−αt−1ˉ=1−αtˉ(1−αt)(1−αt−1ˉ)σ2=βt(1−αt−1ˉ)1−αtˉμ=12σ2(2αt1−αtxt+2αt−1ˉ1−αt−1ˉx0)=αt−1ˉ(1−αt)1−αtˉx0+(1−αt−1ˉ)αt1−αtˉxt\begin{aligned}\frac{1}{\sigma^2} &= \frac{\alpha_t}{1-\alpha_t} + \frac{1}{1-\bar{\alpha_{t-1}}} = \frac{1-\bar{\alpha_t}}{(1-\alpha_t)(1-\bar{\alpha_{t-1}})} \\ \sigma^2 &= \frac{\beta_t(1-\bar{\alpha_{t-1}})}{1-\bar{\alpha_t}} \\ \mu &= \frac{1}{2}\sigma^2(\frac{2\sqrt{\alpha_t}}{1-\alpha_t}x_t+\frac{2\sqrt{\bar{\alpha_{t-1}}}}{1-\bar{\alpha_{t-1}}}x_0) = \frac{\sqrt{\bar{\alpha_{t-1}}}(1-\alpha_t)}{1-\bar{\alpha_t}}x_0 + \frac{(1-\bar{\alpha_{t-1}})\sqrt{\alpha_t}}{1-\bar{\alpha_{t}}}x_t \\ \end{aligned}σ21σ2μ=1−αtαt+1−αt−1ˉ1=(1−αt)(1−αt−1ˉ)1−αtˉ=1−αtˉβt(1−αt−1ˉ)=21σ2(1−αt2αtxt+1−αt−1ˉ2αt−1ˉx0)=1−αtˉαt−1ˉ(1−αt)x0+1−αtˉ(1−αt−1ˉ)αtxt
又因为xt=αtˉx0+1−αtˉϵx_t = \sqrt{\bar{\alpha_t}}x_0 + \sqrt{1-\bar{\alpha_t}}\epsilonxt=αtˉx0+1−αtˉϵ,则可以将上式的x0x_0x0全部换掉
μ=1αt(αt−αtˉ1−αtˉxt+αtˉ(1−αt)1−αtˉ∗xt−1−αtˉϵαtˉ)=1αt[αt−αtˉ1−αtˉxt+1−αt1−αtˉ∗(xt−1−αtˉϵ)]=1αt(xt−1−αt1−αtˉ1−αtˉϵ)=1αt(xt−1−αt1−αtˉϵ)\begin{aligned}\mu &= \frac{1}{\sqrt{\alpha_t}}(\frac{\alpha_t-\bar{\alpha_t}}{1-\bar{\alpha_t}}x_t + \frac{\sqrt{\bar{\alpha_t}}(1-\alpha_t)}{1-\bar{\alpha_t}}*\frac{x_t-\sqrt{1-\bar{\alpha_t}}\epsilon}{\sqrt{\bar{\alpha_t}}}) \\ &= \frac{1}{\sqrt{\alpha_t}}[\frac{\alpha_t-\bar{\alpha_t}}{1-\bar{\alpha_t}}x_t + \frac{1-\alpha_t}{1-\bar{\alpha_t}}*(x_t-\sqrt{1-\bar{\alpha_t}}\epsilon)] \\ &= \frac{1}{\sqrt{{\alpha_t}}}(x_t - \frac{1-\alpha_t}{1-\bar{\alpha_t}}\sqrt{1-\bar{\alpha_t}}\epsilon) \\ &= \frac{1}{\sqrt{\alpha_t}}(x_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha_t}}}\epsilon)\end{aligned}μ=αt1(1−αtˉαt−αtˉxt+1−αtˉαtˉ(1−αt)∗αtˉxt−1−αtˉϵ)=αt1[1−αtˉαt−αtˉxt+1−αtˉ1−αt∗(xt−1−αtˉϵ)]=αt1(xt−1−αtˉ1−αt1−αtˉϵ)=αt1(xt−1−αtˉ1−αtϵ)
P(xt−1∣xt)=N(1αt(xt−1−αt1−αtˉϵ),(1−αt)(1−αt−1ˉ)1−αtˉ)P(x_{t-1}|x_t) = N(\frac{1}{\sqrt{\alpha_t}}(x_t - \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha_t}}}\epsilon),\frac{(1-\alpha_t)(1-\bar{\alpha_{t-1}})}{1-\bar{\alpha_t}})P(xt−1∣xt)=N(αt1(xt−1−αtˉ1−αtϵ),1−αtˉ(1−αt)(1−αt−1ˉ))
以上只是简单的前向和反向的介绍,还有ϵ\epsilonϵ是未知的。
总结
本周对unet和DDPM的概念进行了学习,DDPM还有训练、推理等过程没有学习,下周将会对这些内容进行补充。