how-diffusion-models-work课程学习

sampling

推理过程

  • 输入噪声sample,
  • 模型预测噪声
  • 获取新sample。模型减去预测的噪声+新噪声(DDPM sampling)包含3个系数
  • 如此循环很多次,即可获取高质量的sampling
    在这里插入图片描述

ddpm sample代码

# sample using standard algorithm
@torch.no_grad()
def sample_ddpm(n_sample, save_rate=20):
    # x_T ~ N(0, 1), sample initial noise
    samples = torch.randn(n_sample, 3, height, height).to(device)  

    # array to keep track of generated steps for plotting
    intermediate = [] 
    for i in range(timesteps, 0, -1):
        print(f'sampling timestep {i:3d}', end='\r')

        # reshape time tensor
        t = torch.tensor([i / timesteps])[:, None, None, None].to(device)

        # sample some random noise to inject back in. For i = 1, don't add back in noise
        z = torch.randn_like(samples) if i > 1 else 0

        eps = nn_model(samples, t)    # predict noise e_(x_t,t)
        samples = denoise_add_noise(samples, i, eps, z)
        if i % save_rate ==0 or i==timesteps or i<8:
            intermediate.append(samples.detach().cpu().numpy())

    intermediate = np.stack(intermediate)
    return samples, intermediate
# helper function; removes the predicted noise (but adds some noise back in to avoid collapse)
def denoise_add_noise(x, t, pred_noise, z=None):
    if z is None:
        z = torch.randn_like(x)
    noise = b_t.sqrt()[t] * z
    mean = (x - pred_noise * ((1 - a_t[t]) / (1 - ab_t[t]).sqrt())) / a_t[t].sqrt()
    return mean + noise

问题1、不加入新噪声结果如何?结果会很差

unet

先下采样,再上采样。模型预测噪声。
关键需要引入两个embed。上下文embed和时间embed

  • 上下文embed用于控制模型生产的内容
  • 时间embed和步长以及噪声级别相关
    在这里插入图片描述
        # embed context and timestep
        cemb1 = self.contextembed1(c).view(-1, self.n_feat * 2, 1, 1)     # (batch, 2*n_feat, 1,1)
        temb1 = self.timeembed1(t).view(-1, self.n_feat * 2, 1, 1)

        up2 = self.up1(cemb1*up1 + temb1, down2)

训练

在这里插入图片描述
对原始sample加入噪声,然后模型预测噪声,再求loss。每次只随机加一个噪声即可(随机的过程与t时间步长相关)

# training without context code

# set into train mode
nn_model.train()

for ep in range(n_epoch):
    print(f'epoch {ep}')
    
    # linearly decay learning rate
    optim.param_groups[0]['lr'] = lrate*(1-ep/n_epoch)
    
    pbar = tqdm(dataloader, mininterval=2 )
    for x, _ in pbar:   # x: images
        optim.zero_grad()
        x = x.to(device)
        
        # perturb data
        noise = torch.randn_like(x)
        t = torch.randint(1, timesteps + 1, (x.shape[0],)).to(device) 
        x_pert = perturb_input(x, t, noise)
        
        # use network to recover noise
        pred_noise = nn_model(x_pert, t / timesteps)
        
        # loss is mean squared error between the predicted and true noise
        loss = F.mse_loss(pred_noise, noise)
        loss.backward()
        
        optim.step()

控制生成

在这里插入图片描述
通过在模型中加入embedding即可控制生成。训练的时候给图片语言描述,通过embedding网络生成vector输入到网络。在推理的时候给不同的embedding即可输出不同的结果。
控制embed*, 时间embed是+。理解为控制相当于softmax()或者mask

  • embedding可以是语言的embed。长度为1000等
  • embedding可以是简单的类别,如长度为5的5个类别。

加速sampling——DDIM

原始的DDPM是一个隐马尔可夫过程,采样需要一步一步,500多步才能获取很好的结果,过程很慢。
DDIM跳过了一些时间步长,先预测一个粗糙的结果,然后在逐步的refine。
在这里插入图片描述

总结

扩散模型可以用于图像生成、图像编辑、音乐生成等领域。
后续学习更好的sampling、stable diffusion

参考:https://learn.deeplearning.ai/courses/diffusion-models/
https://www.bilibili.com/video/BV1R14y1D7kx?p=1

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yang_daxia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值