欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > DeepSeek基于注意力模型的可控图像生成

DeepSeek基于注意力模型的可控图像生成

2025/5/12 9:51:29 来源:https://blog.csdn.net/brucexia/article/details/147816296  浏览:    关键词:DeepSeek基于注意力模型的可控图像生成

DeepSeek大模型高性能核心技术与多模态融合开发 - 商品搜索 - 京东

图像的加噪与模型训练

在扩散模型的训练过程中,首先需要对输入的信号进行加噪处理,经典的加噪过程是在图像进行向量化处理后在其中添加正态分布,而正态分布的值也是与时间步相关的。这样逐步向图像中添加噪声,直到图像变得完全噪声化。

import torch   T = 1000  # Diffusion过程的总步数  # 前向diffusion计算参数
# (T,) 生成一个线性间隔的tensor,用于计算每一步的噪声水平  
betas = torch.linspace(0.0001, 0.02, T)    
alphas = 1 - betas  # (T,) 计算每一步的保留率  
# alpha_t累乘 (T,),计算每一步累积的保留率 
alphas_cumprod = torch.cumprod(alphas, dim=-1)   
# alpha_t-1累乘(T,),为计算方差做准备
alphas_cumprod_prev = torch.cat((torch.tensor([1.0]), alphas_cumprod[:-1]), dim=-1)    
# denoise用的方差(T,),计算每一步的去噪方差 
variance = (1 - alphas) * (1 - alphas_cumprod_prev) / (1 - alphas_cumprod)   # 执行前向加噪  
def forward_add_noise(x, t):  # batch_x: (batch,channel,height,width), batch_t: (batch_size,)  noise = torch.randn_like(x)  # 为每幅图片生成第t步的高斯噪声   (batch,channel,height,width)  # 根据当前步数t,获取对应的累积保留率,并调整其形状以匹配输入x的形状    batch_alphas_cumprod = alphas_cumprod[t].view(x.size(0), 1, 1, 1)    # 基于公式直接生成第t步加噪后的图片    x = torch.sqrt(batch_alphas_cumprod) * x + torch.sqrt(1 - batch_alphas_cumprod) * noise    return x, noise  # 返回加噪后的图片和生成的噪声

上面这段代码首先定义了扩散模型的前向过程中需要的参数,包括每一步的噪声水平betas、保留率alphas、累积保留率alphas_cumprod以及用于去噪的方差variance。然后定义了一个函数forward_add_noise,该函数接受一个图像x和步数t作为输入。根据扩散模型的前向过程,向图像中添加噪声,并返回加噪后的图像和生成的噪声。

读者可以采用以下代码尝试完成为图像添加噪声的演示:

import matplotlib.pyplot as plt 
from dataset import MNISTdataset=MNIST()
# 两幅图片拼batch, (2,1,48,48)    
x=torch.stack((dataset[0][0],dataset[1][0]),dim=0) # 原图
plt.figure(figsize=(10,10))
plt.subplot(1,2,1)
plt.imshow(x[0].permute(1,2,0))
plt.subplot(1,2,2)
plt.imshow(x[1].permute(1,2,0))
plt.show()# 随机时间步
t=torch.randint(0,T,size=(x.size(0),))
print('t:',t)# 加噪
x=x*2-1 # [0,1]像素值调整到[-1,1]之间,以便与高斯噪声值范围匹配
x,noise=forward_add_noise(x,t)
print('x:',x.size())
print('noise:',noise.size())# 加噪图
plt.figure(figsize=(10,10))
plt.subplot(1,2,1)
plt.imshow(((x[0]+1)/2).permute(1,2,0))   
plt.subplot(1,2,2)
plt.imshow(((x[0]+1)/2).permute(1,2,0))
plt.show()

运行结果如图9-13所示。

在此基础上,我们可以完成对Dit模型的训练,代码如下:

from torch.utils.data import DataLoader  # 导入PyTorch的数据加载工具  
from dataset import MNIST  # 从dataset模块导入MNIST数据集类  
from diffusion import forward_add_noise  # 从diffusion模块导入forward_add_noise函数,用于向图像添加噪声  
import torch  # 导入PyTorch库  
from torch import nn  # 从PyTorch导入nn模块,包含构建神经网络所需的工具  
import os  # 导入os模块,用于处理文件和目录路径  
from dit import DiT  # 从dit模块导入DiT模型  
# 判断是否有可用的CUDA设备,如果有则使用GPU,否则使用CPU  
DEVICE='cuda' if torch.cuda.is_available() else 'cpu'    dataset=MNIST()  # 实例化MNIST数据集对象  T = 1000  # 设置扩散过程中的总时间步数  
model=DiT(img_size=28,patch_size=4,channel=1,emb_size=64,label_num=10,dit_num=3,head=4).to(DEVICE)  # 实例化DiT模型并移至指定设备  
#model.load_state_dict(torch.load('./saver/model.pth'))  # 可选:加载预训练模型参数  # 使用Adam优化器,学习率设置为0.001
optimzer=torch.optim.Adam(model.parameters(),lr=1e-3)   
loss_fn=nn.L1Loss()  # 使用L1损失函数(即绝对值误差均值)  '''训练模型'''  
EPOCH=300  # 设置训练的总轮次  
BATCH_SIZE=300  # 设置每个批次的大小  if __name__ == '__main__':  from tqdm import tqdm  # 导入tqdm库,用于在训练过程中显示进度条  dataloader=DataLoader(dataset,batch_size=BATCH_SIZE,shuffle=True,num_workers=10,persistent_workers=True)  # 创建数据加载器  iter_count=0  for epoch in range(EPOCH):  # 遍历每个训练轮次  pbar = tqdm(dataloader, total=len(dataloader))  # 初始化进度条  for imgs,labels in pbar:  # 遍历每个批次的数据  x=imgs*2-1  # 将图像的像素范围从[0,1]转换到[-1,1],与噪声高斯分布的范围对应  t=torch.randint(0,T,(imgs.size(0),))  # 为每幅图片生成一个随机的t时刻  y=labels  # 向图像添加噪声,返回加噪后的图像和添加的噪声x,noise=forward_add_noise(x,t)    # 模型预测添加的噪声pred_noise=model(x.to(DEVICE),t.to(DEVICE),y.to(DEVICE))    # 计算预测噪声和实际噪声之间的L1损失loss=loss_fn(pred_noise,noise.to(DEVICE))    optimzer.zero_grad()  # 清除之前的梯度  loss.backward()  # 反向传播,计算梯度  optimzer.step()  # 更新模型参数  # 更新进度条描述pbar.set_description(f"epoch:{epoch + 1}, train_loss:{loss.item():.5f}")    if epoch % 20 == 0:  # 每20轮保存一次模型  torch.save(model.state_dict(),'./saver/model.pth')  print("base diffusion saved")

 读者自行查看代码运行结果。

基于注意力模型的可控图像生成

DiT模型的可控图像生成是在我们训练的基础上,逐渐对正态分布的噪声图像进行按步骤的脱噪过程。这一过程不仅要求模型具备精准的噪声预测能力,还需确保脱噪步骤的细腻与连贯,从而最终实现从纯粹噪声到目标图像的华丽蜕变。

完整的可控图像生成代码如下:

import torch   from dit import DiT  
import matplotlib.pyplot as plt   
# 导入diffusion模块中的所有内容,这通常包含一些与扩散模型相关的预定义变量和函数
from diffusion import *    # 设置设备为GPU或CPU  
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'   
DEVICE = "cpu"  # 强制使用CPU  T = 1000  # 扩散步骤的总数  def backward_denoise(model,x,y):  steps=[x.clone(),]  # 初始化步骤列表,包含初始噪声图像  global alphas,alphas_cumprod,variance  # 这些是从diffusion模块导入的全局变量  x=x.to(DEVICE)  # 将输入x移动到指定的设备  alphas=alphas.to(DEVICE)  alphas_cumprod=alphas_cumprod.to(DEVICE)  variance=variance.to(DEVICE)  y=y.to(DEVICE)  # 将标签y移动到指定的设备  model.eval()  # 设置模型为评估模式  with torch.no_grad():  # 在不计算梯度的情况下运行,节省内存和计算资源  for time in range(T-1,-1,-1):  # 从T-1到0逆序迭代  t=torch.full((x.size(0),),time).to(DEVICE)  # 创建一个包含当前时间步的tensor  # 预测x_t时刻的噪声  noise=model(x,t,y)      # 生成t-1时刻的图像  shape=(x.size(0),1,1,1)  mean=1/torch.sqrt(alphas[t].view(*shape))*  \  (  x-   (1-alphas[t].view(*shape))/torch.sqrt(1-alphas_cumprod[t].view(*shape))*noise  )  if time!=0:  x=mean+ \  torch.randn_like(x)* \  torch.sqrt(variance[t].view(*shape))  else:  x=mean  x=torch.clamp(x, -1.0, 1.0).detach()  # 确保x的值在[-1,1]之间,并分离计算图  steps.append(x)  return steps  # 初始化DiT模型  
model=DiT(img_size=28,patch_size=4,channel=1,emb_size=64,label_num=10,dit_num=3,head=4).to(DEVICE)  
model.load_state_dict(torch.load('./saver/model.pth'))  # 加载模型权重  # 生成噪声图  
batch_size=10  
x=torch.randn(size=(batch_size,1,28,28))  # 生成随机噪声图像  
y=torch.arange(start=0,end=10,dtype=torch.long)   # 生成标签  # 逐步去噪得到原图  
steps=backward_denoise(model,x,y)  # 绘制数量  
num_imgs=20  # 绘制还原过程  
plt.figure(figsize=(15,15))  
for b in range(batch_size):  for i in range(0,num_imgs):  idx=int(T/num_imgs)*(i+1)  # 计算要绘制的步骤索引  # 像素值还原到[0,1]  final_img=(steps[idx][b].to('cpu')+1)/2  # tensor转回PIL图  final_img=final_img.permute(1,2,0)  # 调整通道顺序以匹配图像格式  plt.subplot(batch_size,num_imgs,b*num_imgs+i+1)plt.imshow(final_img)  
plt.show()  # 显示图像

上面的代码展示了使用DiT进行图像去噪的完整过程。首先,它导入了必要的库和模块,包括PyTorch、DiT模型、matplotlib绘图模块,以及从diffusion模块导入的一些预定义变量和函数,这些通常与扩散模型相关。然后,代码设置了计算设备为CPU(尽管提供了检测GPU可用性的选项),并定义了扩散步骤的总数。

backward_denoise函数是实现图像去噪的核心。它接受一个DiT模型、一批噪声图像以及对应的标签作为输入。在这个函数内部,它首先将输入移动到指定的计算设备,然后将模型设置为评估模式,并开始一个不计算梯度的循环,从最后一个扩散步骤开始逆向迭代至第一步。在每一步中,它使用模型预测当前步骤的噪声,然后根据扩散模型的公式计算上一步的图像。这个过程一直持续到生成原始图像。

接下来,代码初始化了DiT模型,并加载了预训练的权重。然后,它生成了一批随机噪声图像和对应的标签,并使用backward_denoise函数对这些噪声图像进行去噪,逐步还原出原始图像。运行结果如图9-14所示。

图9-14  基于DiT模型的可控图像生成

可见,我们使用生成代码绘制了去噪过程的图像,展示了从完全噪声的图像逐步还原为清晰图像的过程。通过调整通道顺序和像素值范围,它将tensor格式的图像转换为适合绘制的格式,并使用matplotlib库的subplot函数在一个大图中展示了所有步骤的图像。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词