当前位置: 首页 > news >正文

CVAE——生成0-9数字图像(Pytorch+mnist)

1、简介

  • CVAE(Conditional Variational Autoencoder,条件变分自编码器)是一种变分自编码器(VAE)的变体,用于生成有条件的数据。在传统的变分自编码器中,生成的数据是完全由潜在变量决定的,而CVAE允许在生成过程中引入外部条件信息。
  • 具体来说,CVAE在生成数据时,除了使用随机采样的潜在变量外,还会接收一个额外的条件信息。这个条件信息可以是类别标签、属性信息、或者其他形式的上下文信息,取决于具体的任务。通过将条件信息作为输入提供给编码器和解码器,CVAE能够生成与条件信息相关的数据。
  • CVAE在许多任务中都很有用,例如图像生成中的类别条件生成、属性编辑、生成特定风格的图像等。通过引入条件信息,CVAE使得生成的数据更具有控制性和可解释性。
  • 本文利用CVAE,输入数字图像和对应的标签。训练后,生成0-9数字图像。
    • (epoch=10)
    • (epoch=20)
    • (epoch=30)

2、代码

  • import torch
    import torch.nn as nn
    import torch.optim as optim
    import torchvision
    import torch.nn.functional as F
    from torchvision.utils import save_image# 变分自编码器
    class CVAE(nn.Module):def __init__(self):super(CVAE, self).__init__()self.labels = 10  # 标签数量# 编码器层self.fc1 = nn.Linear(input_size + self.labels, 512)  # 编码器输入层self.fc2 = nn.Linear(512, latent_size)self.fc3 = nn.Linear(512, latent_size)# 解码器层self.fc4 = nn.Linear(latent_size + self.labels, 512)  # 解码器输入层self.fc5 = nn.Linear(512, input_size)  # 解码器输出层# 编码器部分def encode(self, x):x = F.relu(self.fc1(x))  # 编码器的隐藏表示mu = self.fc2(x)  # 潜在空间均值log_var = self.fc3(x)  # 潜在空间对数方差return mu, log_var# 重参数化技巧def reparameterize(self, mu, log_var):  # 从编码器输出的均值和对数方差中采样得到潜在变量zstd = torch.exp(0.5 * log_var)  # 计算标准差eps = torch.randn_like(std)  # 从标准正态分布中采样得到随机噪声return mu + eps * std  # 根据重参数化公式计算潜在变量z# 解码器部分def decode(self, z):z = F.relu(self.fc4(z))  # 将潜在变量 z 解码为重构图像return torch.sigmoid(self.fc5(z))  # 将隐藏表示映射回输入图像大小,并应用 sigmoid 激活函数,以产生重构图像# 前向传播def forward(self, x, y):  # 输入图像 x,标签 y 通过编码器和解码器,得到重构图像和潜在变量的均值和对数方差x = torch.cat([x, y], dim=1)mu, log_var = self.encode(x)z = self.reparameterize(mu, log_var)z = torch.cat([z, y], dim=1)return self.decode(z), mu, log_var# 使用重构损失和 KL 散度作为损失函数
    def loss_function(recon_x, x, mu, log_var):  # 参数:重构的图像、原始图像、潜在变量的均值、潜在变量的对数方差MSE = F.mse_loss(recon_x, x.view(-1, input_size), reduction='sum')  # 计算重构图像 recon_x 和原始图像 x 之间的均方误差KLD = -0.5 * torch.sum(1 + log_var - mu.pow(2) - log_var.exp())  # 计算潜在变量的KL散度return MSE + KLD  # 返回二进制交叉熵损失和 KLD 损失的总和作为最终的损失值def sample_images(epoch):with torch.no_grad():  # 上下文管理器,确保在该上下文中不会进行梯度计算。因为在这里只是生成样本而不需要梯度number = 10# 生成标签sample_labels = torch.arange(10).long().to(device)  # 0-9的标签sample_labels_onehot = F.one_hot(sample_labels, num_classes=10).float()# 生成随机噪声sample = torch.randn(number, latent_size).to(device)  # 生成一个形状为 (64, latent_size) 的张量,其中包含从标准正态分布中采样的随机数sample = torch.cat([sample, sample_labels_onehot], dim=1)  # 连接图片和标签sample = model.decode(sample).cpu()  # 将随机样本输入到解码器中,解码器将其映射为图像save_image(sample.view(number, 1, 28, 28), f'sample{epoch}.png', nrow=int(number / 2))  # 将生成的图像保存为文件if __name__ == '__main__':batch_size = 512  # 批次大小epochs = 30  # 学习周期sample_interval = 10  # 保存结果的周期learning_rate = 0.001  # 学习率input_size = 784  # 输入大小latent_size = 64  # 潜在变量大小# 载入 MNIST 数据集中的图片进行训练transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor()])  # 将图像转换为张量train_dataset = torchvision.datasets.MNIST(root="~/torch_datasets", train=True, transform=transform, download=True)  # 加载 MNIST 数据集的训练集,设置路径、转换和下载为 Truetrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True)  # 创建一个数据加载器,用于加载训练数据,设置批处理大小和是否随机打乱数据# 在使用定义的 AE 类之前,有以下事情要做:# 配置要在哪个设备上运行device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 建立 CVAE 模型并载入到 CPU 设备model = CVAE().to(device)# Adam 优化器,学习率optimizer = optim.Adam(model.parameters(), lr=learning_rate)# 训练for epoch in range(epochs):train_loss = 0for batch_idx, (data, labels) in enumerate(train_loader):data = data.to(device)  # 将输入数据移动到设备(GPU 或 CPU)上data = data.view(-1, input_size)  # 重塑维度labels = F.one_hot(labels, num_classes=10).float().to(device)  # 转换为独热编码# print(labels[1])optimizer.zero_grad()  # 进行反向传播之前,需要将优化器中的梯度清零,以避免梯度的累积# 重构图像 recon_batch、潜在变量的均值 mu 和对数方差 log_varrecon_batch, mu, log_var = model(data, labels)loss = loss_function(recon_batch, data, mu, log_var)  # 计算损失loss.backward()  # 计算损失相对于模型参数的梯度train_loss += loss.item()optimizer.step()  # 更新模型参数train_loss = train_loss / len(train_loader)  # # 计算每个周期的训练损失print('Epoch [{}/{}], Loss: {:.3f}'.format(epoch + 1, epochs, train_loss))# 每10次保存图像if (epoch + 1) % sample_interval == 0:sample_images(epoch + 1)# 每训练10次保存模型if (epoch + 1) % sample_interval == 0:torch.save(model.state_dict(), f'vae{epoch + 1}.pth')
http://www.lryc.cn/news/329325.html

相关文章:

  • 【Linux】TCP网络套接字编程+守护进程
  • 【Qt 学习笔记】Day2 | 认识QtSDK中的重要工具
  • adc123456
  • YOLOV5训练自己的数据集教程(万字整理,实现0-1)
  • 精通Go语言文件上传:深入探讨r.FormFile函数的应用与优化
  • 【C语言】字符串
  • 云计算探索-DAS、NAS与SAN存储技术演进及其应用比较
  • 手机有线投屏到直播姬pc端教程
  • SOA、分布式、微服务之间的关系?
  • Java多线程学习(概念笔记)
  • 【C++】set和map
  • yolov5 v7.0打包exe文件,使用C++调用
  • 保研线性代数机器学习基础复习2
  • vultr ubuntu 服务器远程桌面安装及连接
  • 前端学习<二>CSS基础——12-CSS3属性详解:动画详解
  • Sqoop 的安装与配置
  • Mysql设置访问权限(docker配置)
  • 【Linux】详解软硬链接
  • 维修贝加莱4PP420.1043-B5触摸屏Power Panel 400工业电脑液晶
  • Java_21 完成一半题目
  • 【WPF应用21】WPF 中的 TextBox 控件详解与示例
  • 小程序页面传参?
  • C++list的模拟实现
  • Leetcode 187. 重复的DNA序列
  • 都江堰泛计算操作系统(多机)应用方向
  • 【第十二届“泰迪杯”数据挖掘挑战赛】【2024泰迪杯】B题基于多模态特征融合的图像文本检索—解题全流程(论文更新)
  • 蓝桥杯22年第十三届省赛-统计子矩阵|一维前缀和加双指针
  • SaaS 电商设计 (十) 记一次 5000kw 商品数据ES迁移 (详细的集群搭建以及线上灰度过程设计)
  • linux安装Tomcat
  • 【机器学习300问】57、机器是如何读得懂文本数据的呢?