深度学习:DCGAN

目录

什么是DCGAN

DCGAN与GAN的区别

DCGAN生成器

DCGAN判别器

基于MindSpore框架实现DCGAN

数据集:

变量定义:

数据预处理:

生成器:

 判别器:

损失函数与优化器

训练模型

 模型推理


什么是DCGAN

CDGAN(Deep Convolutional Generative Adversarial Networks),是GAN(Generative Adversarial Networks)的一种变体,它特别使用了卷积神经网络(CNNs)作为生成器和判别器的构建模块。

DCGAN使用全卷积网络结构代替传统的池化层和全连接层。在生成器中采用转置卷积(也称为分数步长卷积或反卷积)来逐步增加图像的空间维度。

在判别器中使用卷积层来逐步减少空间维度并提取特征。

ReLU激活函数用于生成器的所有层(除输出层使用Tanh激活函数外),LeakyReLU激活函数用于判别器的所有层。

DCGAN与GAN的区别

  • 基础架构:传统GAN没有对生成器和判别器的具体结构做出严格规定;而DCGAN明确指定了使用深度卷积网络。
  • 稳定性:由于采用了上述改进措施,DCGAN相比原始GAN在训练过程中表现得更为稳定。
  • 应用领域:虽然两者都可以应用于多种类型的数据生成任务,但DCGAN因其特殊的网络结构,在处理图像数据方面尤为有效。

关于GAN网络,可参考:深度学习:GAN图像生成-CSDN博客

DCGAN生成器

按照DCGAN论文中的描述,所有模型权重均应从mean为0,sigma为0.02的正态分布中随机初始化。

生成器G的功能是将隐向量z映射到数据空间。由于数据是图像,这一过程也会创建与真实图像大小相同的 RGB 图像。在实践场景中,该功能是通过一系列Conv2dTranspose转置卷积层来完成的,每个层都与BatchNorm2d层和ReLu激活层配对,输出数据会经过tanh函数,使其返回[-1,1]的数据范围内。

DCGAN判别器

判别器D是一个二分类网络模型,输出判定该图像为真实图的概率。通过一系列的Conv2dBatchNorm2dLeakyReLU层对其进行处理,最后通过Sigmoid激活函数得到最终概率。

DCGAN论文提到,使用卷积而不是通过池化来进行下采样是一个好方法,因为它可以让网络学习自己的池化特征。

基于MindSpore框架实现DCGAN

数据集:

# 记载数据集
from download import downloadurl = "https://download.mindspore.cn/dataset/Faces/faces.zip"path = download(url, "./faces", kind="zip", replace=True)

变量定义:

# 变量定义
batch_size = 128 # 批量大小
image_size = 64 # 训练图像的空间大小
num_channels = 3 # 彩色图片的通道数
latent_size = 100 # 输入生成器的隐向量长度
generator_feature_size = 64 # 特征图在生成器中的大小
discriminator_feature_size = 64 # 特征图在判别器中的大小
num_epochs = 10 # 训练轮次
lr = 0.0002 # 学习率
beta1 = 0.5 # Adam优化器的beta1超参数

数据预处理:

# 对数据进行预处理并增强
import numpy as np
import mindspore as ms
import mindspore.dataset as ds
import mindspore.dataset.vision as vision
import timedef create_dataset_imagenet(dataset_path):dataset = ds.ImageFolderDataset(dataset_path, # 指定数据集所在的文件夹路径num_parallel_workers=4, # 并行工作线程为4shuffle=True, # 打乱数据集decode=True # 解码图片)# 数据增持transforms = [vision.Resize(image_size), # 将图像大小调整到指定的image_sizevision.CenterCrop(image_size),  # 从中心裁剪出指定大小的image_size的图像vision.HWC2CHW(), # 将图像的通道顺序从HWC(高宽通道)转换为CHW(通道高宽)lambda x:((x / 255).astype("float32"))  # 将像素值归一化到[0,1]区间,并转换为float32类型]# 数据映射操作dataset = dataset.project("image")dataset = dataset.map(transforms, "image") # 对'image'列应用上面定义的transforms变换# 批量操作dataset = dataset.batch(batch_size)return datasetdataset = create_dataset_imagenet('./faces')

 

生成器:

from mindspore import nn, ops
from mindspore.common.initializer import Normal
# 初始化权重
weight_init = Normal(mean=0, sigma=0.02)
gamma_init = Normal(mean=1, sigma=0.02)class Generator(nn.Cell):def __init__(self):super(Generator, self).__init__()self.generator = nn.SequentialCell(# (in_channels, out_channels, kernel_size, stride, pad_mode, padding)# pad_mode='valid':不对输入进行填充,返回输出可能的最大长度。nn.Conv2dTranspose(latent_size, generator_feature_size * 8, 4, 1, 'valid', weight_init=weight_init),nn.BatchNorm2d(generator_feature_size * 8, gamma_init=gamma_init),nn.ReLU(),# pad_mode='pad':对输入填充指定的量。nn.Conv2dTranspose(generator_feature_size * 8, generator_feature_size * 4, 4, 2, 'pad', 1, weight_init=weight_init),nn.BatchNorm2d(generator_feature_size * 4, gamma_init=gamma_init),nn.ReLU(),nn.Conv2dTranspose(generator_feature_size * 4, generator_feature_size * 2, 4, 2, 'pad', 1, weight_init=weight_init),nn.BatchNorm2d(generator_feature_size * 2, gamma_init=gamma_init),nn.ReLU(),nn.Conv2dTranspose(generator_feature_size * 2, generator_feature_size, 4, 2, 'pad', 1, weight_init=weight_init),nn.BatchNorm2d(generator_feature_size, gamma_init=gamma_init),nn.ReLU(),nn.Conv2dTranspose(generator_feature_size, num_channels, 4, 2, 'pad', 1, weight_init=weight_init),nn.Tanh())def construct(self, x):return self.generator(x)generator = Generator()

 判别器:

# 判别器
class Discriminator(nn.Cell):def __init__(self):super(Discriminator, self).__init__()self.discriminator = nn.SequentialCell(nn.Conv2d(num_channels, discriminator_feature_size, 4, 2, 'pad', 1, weight_init=weight_init),nn.LeakyReLU(0.2),nn.Conv2d(discriminator_feature_size, discriminator_feature_size * 2, 4, 2, 'pad', 1, weight_init=weight_init),# gamma_init: 参数的初始化方法nn.BatchNorm2d(discriminator_feature_size * 2, gamma_init=gamma_init),nn.LeakyReLU(0.2),nn.Conv2d(discriminator_feature_size * 2, discriminator_feature_size * 4, 4, 2, 'pad', 1, weight_init=weight_init),nn.BatchNorm2d(discriminator_feature_size * 4, gamma_init=gamma_init),nn.LeakyReLU(0.2),nn.Conv2d(discriminator_feature_size * 4, discriminator_feature_size * 8, 4, 2, 'pad', 1, weight_init=weight_init),nn.BatchNorm2d(discriminator_feature_size * 8, gamma_init=gamma_init),nn.LeakyReLU(0.2),nn.Conv2d(discriminator_feature_size * 8, 1, 4, 1, 'valid', weight_init=weight_init))self.adv_layer = nn.Sigmoid()def construct(self, X):out = self.discriminator(X)out = out.reshape(out.shape[0], -1)return self.adv_layer(out)discriminator = Discriminator()

损失函数与优化器

loss = nn.BCELoss(reduction='mean')# beta1: 第一个动量矩阵的指数衰减率
optimizer_D = nn.Adam(discriminator.trainable_params(), learning_rate=lr, beta1=beta1)
optimizer_G = nn.Adam(generator.trainable_params(), learning_rate=lr, beta1=beta1)
'''
optimizer.update_parameters_name() 
方法用于更新优化器参数的名称前缀。
这通常在你想要为优化器中的参数添加一个特定的命名空间或前缀时使用,
这样可以更容易地管理和区分不同的优化器参数
'''
optimizer_G.update_parameters_name('optim_g.')
optimizer_D.update_parameters_name('optim_d.')

训练模型

# 生成器forward函数
def generator_forward(real_imgs, valid):# 这里使用标准正态分布来生成噪声z,其形状为(batch_size, latent_size, 1, 1)。z = ops.standard_normal((real_imgs.shape[0], latent_size, 1, 1))gen_imgs = generator(z)# valid是目标标签,通常是一批全1的张量,表示这些图像是真实的。# loss计算判别器输出与目标标签之间的差异,这个差异就是生成器试图最小化的损失。g_loss = loss(discriminator(gen_imgs), valid)return g_loss, gen_imgs# 判别器forward函数
def discriminator_forward(real_imgs, gen_imgs, valid, fake):real_loss = loss(discriminator(real_imgs), valid)fake_loss = loss(discriminator(gen_imgs), fake)d_loss = (real_loss + fake_loss) / 2return d_loss# 计算梯度
'''
has_aux (bool) - 是否返回辅助参数的标志。
若为 True , fn 输出数量必须超过一个,其中只有 fn 第一个输出参与求导,
其他输出值将直接返回。
'''
grad_generator_fn = ms.value_and_grad(generator_forward, None,optimizer_G.parameters,has_aux=True)grad_discriminator_fn = ms.value_and_grad(discriminator_forward, None,optimizer_D.parameters)def train_step(imgs):# 为真实的图像创建全1的有效标签valid = ops.ones((imgs.shape[0], 1), ms.float32)# 为假的图像创建全0的无效标签fake = ops.zeros((imgs.shape[0], 1), ms.float32)# 训练生成器(g_loss, gen_imgs), g_grads = grad_generator_fn(imgs, valid)optimizer_G(g_grads)# 训练判别器d_loss, d_grads = grad_discriminator_fn(imgs, gen_imgs, valid, fake)optimizer_D(d_grads)# 返回loss值和生成结果return g_loss, d_loss, gen_imgs# 生成器损失集合
G_losses = []
# 判别器损失集合
D_losses = []
# 生成图像集合
image_list = []total = dataset.get_dataset_size()for epoch in range(num_epochs):start = time.time()# 没轮训练前,将模型设为训练状态generator.set_train()discriminator.set_train()for i, (imgs, ) in enumerate(dataset.create_tuple_iterator()):g_loss, d_loss, gen_imgs = train_step(imgs)if i % 100 == 0 or i == total - 1:# 输出训练记录print('[%2d/%d][%3d/%d]   Loss_D:%7.4f  Loss_G:%7.4f' % (epoch + 1, num_epochs, i + 1, total, d_loss.asnumpy(), g_loss.asnumpy()))D_losses.append(d_loss.asnumpy())G_losses.append(g_loss.asnumpy())# 每个epoch结束后,使用生成器生成一组图片generator.set_train(False)fixed_noise = ops.standard_normal((batch_size, latent_size, 1, 1))img = generator(fixed_noise)image_list.append(img.transpose(0, 2, 3, 1).asnumpy())# 保存网络模型参数为ckpt文件ms.save_checkpoint(generator, "./generator.ckpt")ms.save_checkpoint(discriminator, "./discriminator.ckpt")end = time.time()print('time:',(start-end))

 模型推理

# 模型推理
ms.load_checkpoint("./generator.ckpt", generator)# 测试噪音数据
fixed_noise = ops.standard_normal((batch_size, latent_size, 1, 1))
img64 = generator(fixed_noise).transpose(0, 2, 3, 1).asnumpy()fig = plt.figure(figsize=(8, 3), dpi=120)
images = []
for i in range(3):images.append(np.concatenate((img64[i * 8:(i + 1) * 8]), axis=1))
img = np.clip(np.concatenate((images[:]), axis=0), 0, 1)
plt.axis("off")
plt.imshow(img)
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55382.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java使用RabbitMQ的详细教程(原生框架)

RabbitMQ是一个实现了高级消息队列协议(AMQP)的开源消息代理软件,它使用Erlang编程语言编写,具有高并发、分布式、可靠性强等特点,非常适合用于构建分布式消息中间件。Java可以通过RabbitMQ的客户端库与其进行通信&…

从密码学看盲拍合约:智能合约的隐私与安全新革命!

文章目录 前言一、什么是盲拍合约?二、盲拍合约的优势1.时间压力的缓解2.绑定与秘密的挑战 三、盲拍合约的工作原理1.提交盲出价2.披露出价3.结束拍卖4.退款机制 四、代码示例总结 前言 随着区块链技术的发展,智能合约在各种场景中的应用越来越广泛。盲…

芝法酱学习笔记(0.5)——使用jenkins做自动打包

前言 上节讲了SpringBoot上的打包。但这些过程都是手动的,在实际的开发测试时,自动化的打包部署,可以大大提升团队开发的效率 一、去官网下载 1.1 官网安装命令 对于如何安装的问题,我向来推荐官网 wget -O /usr/share/keyri…

针对考研的C语言学习(定制化快速掌握重点2)

1.C语言中字符与字符串的比较方法 在C语言中&#xff0c;单字符可以用进行比较也可以用 > , < ,但是字符串却不能用直接比较&#xff0c;需要用strcmp函数。 strcmp 函数的原型定义在 <string.h> 头文件中&#xff0c;其定义如下&#xff1a; int strcmp(const …

ubuntu server 常用配置

这里写目录标题 0001 虚拟机静态IP0002 vim tab 4个空格0003 设置时区0004 网络端口查看端口开放端口 0005 修噶机主机名 0001 虚拟机静态IP win网络链接&#xff0c;IP地址&#xff1a;192.168.220.1 - NAT网关&#xff1a;192.168.220.2 - ubuntu静态IP设置&#xff1a; ca…

前端——Ajax和jQuery

一、Ajax Ajax即“Asynchronous Javascript And XML”&#xff08;异步 JavaScript 和 XML&#xff09;&#xff0c; 通过 JS 异步的向服务器发送请 求并接收响应数据。 同步访问&#xff1a;当客户端向服务器发送请求时&#xff0c;服务器在处理的过程中&#xff0c;浏览器…

使用JavaScript实现动态表格

一、引言 JavaScript是一种功能强大的脚本语言&#xff0c;可以用于实现各种交互式网页效果。在本文中&#xff0c;我们将介绍如何使用JavaScript实现动态表格的功能。动态表格是指在网页上显示的数据表格&#xff0c;可以根据用户输入或页面元素的变化动态更新内容。 二、实…

C++第3课——保留小数点、比较运算符、逻辑运算符、布尔类型以及if-else分支语句(含视频讲解)

文章目录 1、课程笔记2、课程视频 1、课程笔记 #include<iostream>//头文件 input output #include<cmath> //sqrt()所需的头文件 #include<iomanip>//setprecision(1)保留小数点位数所需的头文件 using namespace std; int main(){/*复习上节课内容1、…

【韩顺平Java笔记】第5章:程序控制结构

文章目录 102. 回顾上一章节103. 顺序控制103.1 顺序控制 104. 单分支使用104.1 分支控制 if-else 介绍104.2 单分支 105. 单分支流程图106. 双分支使用107. 双分支流程图108. 双分支练习题109. 多分支使用109.1 多分支的流程图 110. 多分支练习1111. 多分支练习2112. 嵌套分支…

最大正方形 Python题解

最大正方形 题目描述 在一个 n m n\times m nm 的只包含 0 0 0 和 1 1 1 的矩阵里找出一个不包含 0 0 0 的最大正方形&#xff0c;输出边长。 输入格式 输入文件第一行为两个整数 n , m ( 1 ≤ n , m ≤ 100 ) n,m(1\leq n,m\leq 100) n,m(1≤n,m≤100)&#xff0c;接…

ubuntu 开启root

sudo passwd root#输入以下命令来给root账户设置密码 sudo passwd -u root#启用root账户 su - root#要登录root账户 root 开启远程访问&#xff1a; 小心不要改到这里了&#xff1a;sudo nano /etc/ssh/ssh_config 而是&#xff1a;/etc/ssh/sshd_config sudo nano /etc/ssh…

828华为云征文|部署去中心化网络的 AI 照片管理应用 PhotoPrism

828华为云征文&#xff5c;部署去中心化网络的 AI 照片管理应用 PhotoPrism 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 PhotoPrism3.1 PhotoPrism 介绍3.2 PhotoPrism…

【Redis】如何在 Ubuntu 上安装 Redis 5

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 本期内容主要介绍如何在 Ubuntu 上安装 Redis5 一些碎碎念&#xff1a; 本来这期内容介绍如何在 Centos 安装 Redis …

MySQL 8.0 为 Java 开发者提供的强大新特性:深度解析与实战演示

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云/阿里云/华为云/51CTO&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互…

基于ScriptableObject设计游戏数据表

前言 本篇文章是针对之前对于ScriptableObject概念讲解的实际应用之一&#xff0c;在游戏开发中&#xff0c;我们可以使用该类来设计编辑器时的可读写数据表或者运行时的只读数据表。本文将针对运行时的只读数据表的应用进行探索&#xff0c;并且结合自定义的本地持久化存储方式…

cheese安卓版纯本地离线文字识别插件

目的 cheese自动化平台是一款可以模拟鼠标和键盘操作的自动化工具。它可以帮助用户自动完成一些重复的、繁琐的任务&#xff0c;节省大量人工操作的时间。可以采用Vscode、IDEA编写&#xff0c;支持Java、Python、nodejs、GO、Rust、Lua。cheese也包含图色功能&#xff0c;识别…

SpringBoot——基础配置

但是还需要删除pom.xml中的标签——模板的文件也同样操作 banner的选项——关闭 控制台 日志 banner图片的位置——还会分辨颜色 在 Java 的日志框架&#xff08;如 Logback、Log4j2 等&#xff09;中&#xff0c;logging.level.root主要用于设置根日志记录器的日志级别…

css的盒模型

什么是盒模型&#xff1f; CSS盒模型&#xff08;CSS Box Model&#xff09;是CSS布局的基础&#xff0c;是CSS中用于设计和布局网页的一个核心概念。它定义了HTML元素的表现形式&#xff0c;包括元素的内部空间&#xff08;内容、内边距、边框&#xff09;和外部空间&#xf…

location指令

无前缀,必须以”/“开头 前缀""精准匹配。 前缀”^~“ 普通url匹配。 前缀”~“基于正则表达式的匹配&#xff0c; 区分大小写 前缀”~*“ 匹配优先级 locationlocation^~和无前缀/location ~或~* 1.无任何前缀 不加任何规则&#xff0c;默认大小写敏感&#x…

10.2 Linux_并发_进程相关函数

创建子进程 函数声明如下&#xff1a; pid_t fork(void); 返回值&#xff1a;失败返回-1&#xff0c;成功返回两次&#xff0c;子进程获得0(系统分配)&#xff0c;父进程获得子进程的pid 注意&#xff1a;fork创建子进程&#xff0c;实际上就是将父进程复制一遍作为子进程&…