【GAN 图像生成】

embedded/2024/10/18 14:23:06/

理论知识学习:

PART 1:

生成对抗网络GAN 深度学习模型,用于生成数据

对抗式训练,生成器v判别器

DCGAN>WGAN>StyleGAN技术不断进化

GAN在艺术创作。数据增强领域应用越来越广泛

应用:

GAN在图像合成,数据增强,虚拟现实等领域有着广泛的应用。

StyleGAN2能够生成逼真的人脸图像,推动了计算机视觉和图形学的发展。

GAN也被用于生成式医学图像,帮助医生进行更准确的诊断。

PART2:

生成器Generator:生成数据

判别器Discriminator:负责区分数据和生成的数据

两者在训练中互相竞争,生成器努力生成愈来愈真实的数据,判别器不断提高其分辨能力。

损失函数&训练过程:

GAN:训练过程涉及到最小化的一个特定的损失函数,生成器和判别器的组合。

生成器的损失函数:生成的数据被判别器错误分类的概率

判别器的损失函数:正确分类真实和生成数据的概率

网络架构优化:

GAN的网络架构非常复杂,包括卷积神经网络,循环神经网络

网络优化:

训练GAN要仔细选择优化算法和学习率,以避免模式崩溃等问题。

PART3:GAN的高级概念

cGAN;

允许生成过程加入变量条件,是的生成的数据具有特定的属性。

可以生成特定风格的图像或者具有特定特征的人脸。

CycleGAN:循环对抗网络

CycleGAN能够在没有成对训练数据的情况下,实现不同域之间的图像转换。

通过循环一致性来保持转换过程中的原始结构信息。

变分自编码器VAE与GAN

VAE是一种生成模型,它通过编码器和解码器生成数据

GAN与VAE在生成质量和多样性上有所不同,两者可以互相补充。

PART4:

GAN在训练过程中容易出现不稳定,导致生成器和判别器之间的不平衡。

通过改进的优化算法和正则化技术,可以提高训练的稳定性。

问题:

模式崩溃,生成器开始生成非常相似或者重复的数据。

解决方案:

通过引入多样化和正则化和改进的网络架构来解决这样一问题。

PART5实操:MindSpore实现GAN图像生成

操作步骤:

实操

代码:

%%capture captured_output
# 实验环境已经预装了mindspore==2.3.0,如需更换mindspore版本,可更改下面 MINDSPORE_VERSION 变量
!pip uninstall mindspore -y
%env MINDSPORE_VERSION=2.3.0
!pip install https://ms-release.obs.cn-north-4.myhuaweicloud.com/${MINDSPORE_VERSION}/MindSpore/unified/aarch64/mindspore-${MINDSPORE_VERSION}-cp39-cp39-linux_aarch64.whl --trusted-host ms-release.obs.cn-north-4.myhuaweicloud.com -i https://pypi.mirrors.ustc.edu.cn/simple# 查看当前 mindspore 版本
!pip show mindspore# 数据下载
from download import downloadurl = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/MNIST_Data.zip"
download(url, ".", kind="zip", replace=True)import numpy as np
import mindspore.dataset as dsbatch_size = 64
latent_size = 100  # 隐码的长度train_dataset = ds.MnistDataset(dataset_dir='./MNIST_Data/train')
test_dataset = ds.MnistDataset(dataset_dir='./MNIST_Data/test')def data_load(dataset):dataset1 = ds.GeneratorDataset(dataset, ["image", "label"], shuffle=True, python_multiprocessing=False, num_samples=10000)# 数据增强mnist_ds = dataset1.map(operations=lambda x: (x.astype("float32"), np.random.normal(size=latent_size).astype("float32")),output_columns=["image", "latent_code"])mnist_ds = mnist_ds.project(["image", "latent_code"])# 批量操作mnist_ds = mnist_ds.batch(batch_size, True)return mnist_dsmnist_ds = data_load(train_dataset)iter_size = mnist_ds.get_dataset_size()
print('Iter size: %d' % iter_size)import matplotlib.pyplot as pltdata_iter = next(mnist_ds.create_dict_iterator(output_numpy=True))
figure = plt.figure(figsize=(3, 3))
cols, rows = 5, 5
for idx in range(1, cols * rows + 1):image = data_iter['image'][idx]figure.add_subplot(rows, cols, idx)plt.axis("off")plt.imshow(image.squeeze(), cmap="gray")
plt.show()import random
import numpy as np
from mindspore import Tensor
from mindspore.common import dtype# 利用随机种子创建一批隐码
np.random.seed(2323)
test_noise = Tensor(np.random.normal(size=(25, 100)), dtype.float32)
random.shuffle(test_noise)from mindspore import nn
import mindspore.ops as opsimg_size = 28  # 训练图像长(宽)class Generator(nn.Cell):def __init__(self, latent_size, auto_prefix=True):super(Generator, self).__init__(auto_prefix=auto_prefix)self.model = nn.SequentialCell()# [N, 100] -> [N, 128]# 输入一个100维的0~1之间的高斯分布,然后通过第一层线性变换将其映射到256维self.model.append(nn.Dense(latent_size, 128))self.model.append(nn.ReLU())# [N, 128] -> [N, 256]self.model.append(nn.Dense(128, 256))self.model.append(nn.BatchNorm1d(256))self.model.append(nn.ReLU())# [N, 256] -> [N, 512]self.model.append(nn.Dense(256, 512))self.model.append(nn.BatchNorm1d(512))self.model.append(nn.ReLU())# [N, 512] -> [N, 1024]self.model.append(nn.Dense(512, 1024))self.model.append(nn.BatchNorm1d(1024))self.model.append(nn.ReLU())# [N, 1024] -> [N, 784]# 经过线性变换将其变成784维self.model.append(nn.Dense(1024, img_size * img_size))# 经过Tanh激活函数是希望生成的假的图片数据分布能够在-1~1之间self.model.append(nn.Tanh())def construct(self, x):img = self.model(x)return ops.reshape(img, (-1, 1, 28, 28))net_g = Generator(latent_size)
net_g.update_parameters_name('generator')# 判别器
class Discriminator(nn.Cell):def __init__(self, auto_prefix=True):super().__init__(auto_prefix=auto_prefix)self.model = nn.SequentialCell()# [N, 784] -> [N, 512]self.model.append(nn.Dense(img_size * img_size, 512))  # 输入特征数为784,输出为512self.model.append(nn.LeakyReLU())  # 默认斜率为0.2的非线性映射激活函数# [N, 512] -> [N, 256]self.model.append(nn.Dense(512, 256))  # 进行一个线性映射self.model.append(nn.LeakyReLU())# [N, 256] -> [N, 1]self.model.append(nn.Dense(256, 1))self.model.append(nn.Sigmoid())  # 二分类激活函数,将实数映射到[0,1]def construct(self, x):x_flat = ops.reshape(x, (-1, img_size * img_size))return self.model(x_flat)net_d = Discriminator()
net_d.update_parameters_name('discriminator')lr = 0.0002  # 学习率# 损失函数
adversarial_loss = nn.BCELoss(reduction='mean')# 优化器
optimizer_d = nn.Adam(net_d.trainable_params(), learning_rate=lr, beta1=0.5, beta2=0.999)
optimizer_g = nn.Adam(net_g.trainable_params(), learning_rate=lr, beta1=0.5, beta2=0.999)
optimizer_g.update_parameters_name('optim_g')
optimizer_d.update_parameters_name('optim_d')import os
import time
import matplotlib.pyplot as plt
import mindspore as ms
from mindspore import Tensor, save_checkpointtotal_epoch = 12  # 训练周期数
batch_size = 64  # 用于训练的训练集批量大小# 加载预训练模型的参数
pred_trained = False
pred_trained_g = './result/checkpoints/Generator99.ckpt'
pred_trained_d = './result/checkpoints/Discriminator99.ckpt'checkpoints_path = "./result/checkpoints"  # 结果保存路径
image_path = "./result/images"  # 测试结果保存路径%%time
# 生成器计算损失过程
def generator_forward(test_noises):fake_data = net_g(test_noises)fake_out = net_d(fake_data)loss_g = adversarial_loss(fake_out, ops.ones_like(fake_out))return loss_g# 判别器计算损失过程
def discriminator_forward(real_data, test_noises):fake_data = net_g(test_noises)fake_out = net_d(fake_data)real_out = net_d(real_data)real_loss = adversarial_loss(real_out, ops.ones_like(real_out))fake_loss = adversarial_loss(fake_out, ops.zeros_like(fake_out))loss_d = real_loss + fake_lossreturn loss_d# 梯度方法
grad_g = ms.value_and_grad(generator_forward, None, net_g.trainable_params())
grad_d = ms.value_and_grad(discriminator_forward, None, net_d.trainable_params())def train_step(real_data, latent_code):# 计算判别器损失和梯度loss_d, grads_d = grad_d(real_data, latent_code)optimizer_d(grads_d)loss_g, grads_g = grad_g(latent_code)optimizer_g(grads_g)return loss_d, loss_g# 保存生成的test图像
def save_imgs(gen_imgs1, idx):for i3 in range(gen_imgs1.shape[0]):plt.subplot(5, 5, i3 + 1)plt.imshow(gen_imgs1[i3, 0, :, :] / 2 + 0.5, cmap="gray")plt.axis("off")plt.savefig(image_path + "/test_{}.png".format(idx))# 设置参数保存路径
os.makedirs(checkpoints_path, exist_ok=True)
# 设置中间过程生成图片保存路径
os.makedirs(image_path, exist_ok=True)net_g.set_train()
net_d.set_train()# 储存生成器和判别器loss
losses_g, losses_d = [], []for epoch in range(total_epoch):start = time.time()for (iter, data) in enumerate(mnist_ds):start1 = time.time()image, latent_code = dataimage = (image - 127.5) / 127.5  # [0, 255] -> [-1, 1]image = image.reshape(image.shape[0], 1, image.shape[1], image.shape[2])d_loss, g_loss = train_step(image, latent_code)end1 = time.time()if iter % 10 == 10:print(f"Epoch:[{int(epoch):>3d}/{int(total_epoch):>3d}], "f"step:[{int(iter):>4d}/{int(iter_size):>4d}], "f"loss_d:{d_loss.asnumpy():>4f} , "f"loss_g:{g_loss.asnumpy():>4f} , "f"time:{(end1 - start1):>3f}s, "f"lr:{lr:>6f}")end = time.time()print("time of epoch {} is {:.2f}s".format(epoch + 1, end - start))losses_d.append(d_loss.asnumpy())losses_g.append(g_loss.asnumpy())# 每个epoch结束后,使用生成器生成一组图片gen_imgs = net_g(test_noise)save_imgs(gen_imgs.asnumpy(), epoch)# 根据epoch保存模型权重文件if epoch % 1 == 0:save_checkpoint(net_g, checkpoints_path + "/Generator%d.ckpt" % (epoch))save_checkpoint(net_d, checkpoints_path + "/Discriminator%d.ckpt" % (epoch))plt.figure(figsize=(6, 4))
plt.title("Generator and Discriminator Loss During Training")
plt.plot(losses_g, label="G", color='blue')
plt.plot(losses_d, label="D", color='orange')
plt.xlim(-5,15)
plt.ylim(0, 3.5)
plt.xlabel("iterations")
plt.ylabel("Loss")
plt.legend()
plt.show()import cv2
import matplotlib.animation as animation# 将训练过程中生成的测试图转为动态图
image_list = []
for i in range(total_epoch):image_list.append(cv2.imread(image_path + "/test_{}.png".format(i), cv2.IMREAD_GRAYSCALE))
show_list = []
fig = plt.figure(dpi=70)
for epoch in range(0, len(image_list), 5):plt.axis("off")show_list.append([plt.imshow(image_list[epoch], cmap='gray')])ani = animation.ArtistAnimation(fig, show_list, interval=1000, repeat_delay=1000, blit=True)
ani.save('train_test.gif', writer='pillow', fps=1)import mindspore as mstest_ckpt = './result/checkpoints/Generator11.ckpt'parameter = ms.load_checkpoint(test_ckpt)
ms.load_param_into_net(net_g, parameter)
# 模型生成结果
test_data = Tensor(np.random.normal(0, 1, (25, 100)).astype(np.float32))
images = net_g(test_data).transpose(0, 2, 3, 1).asnumpy()
# 结果展示
fig = plt.figure(figsize=(3, 3), dpi=120)
for i in range(25):fig.add_subplot(5, 5, i + 1)plt.axis("off")plt.imshow(images[i].squeeze(), cmap="gray")
plt.show()from datetime import datetime
import pytz
beijing_tz=pytz.timezone('Asia/Shanghai')
current_beijing_time=datetime.now(beijing_tz)
formatted_time=current_beijing_time.strftime('%Y-%m-%d %H:%M:%S')
print("当前北京时间:",formatted_time,'name')

 


http://www.ppmy.cn/embedded/124223.html

相关文章

Prompt 模版解析:诗人角色的创意引导与实践

Prompt 模版解析:诗人角色的创意引导与实践 Prompt 模版作为一种结构化工具,旨在为特定角色——本例中的“诗人”——提供明确的指导和框架。这一模版详尽地描绘了诗人的职责、擅长的诗歌形式以及创作规则,使其能在自动化系统中更加精确地执…

x86 架构下一些常用的汇编指令英文全称与功能简述

汇编语言中的汇编指令众多,以下列举 x86 架构下一些常见的汇编指令: 指令类别指令英文全称功能简述数据传送MOVMove将源操作数复制到目标操作数LEALoad Effective Address加载有效地址到指定寄存器PUSHPush onto the stack将操作数压入堆栈POPPop from …

Win10之解决:设置静态IP后,为什么自动获取动态IP问题(七十八)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…

CUDA与TensorRT学习六:模型部署-CNN、模型部署-YOLOv8检测器、部署BEVFusion模型

文章目录 一、模型部署-CNN二、模型部署-YOLOv8检测器三、部署BEVFusion模型 一、模型部署-CNN 二、模型部署-YOLOv8检测器 三、部署BEVFusion模型

内存缓存和硬盘缓存

硬盘缓存 缓存内容: 静态资源:通常包括 CSS、JavaScript 文件、图像(如 PNG、JPEG)、字体文件等,这些文件在多个页面或会话中会被重复使用。API 响应:某些情况下,API 的响应内容也可能会被缓存&…

如何方便地打出「」和『』

比起英文中的引号 ‘’和 “”,我更喜欢使用中文直角引号:「」和 『』。 此外,在港澳台、日本这几个地区中,就经常使用『』和「」: ​ ‍ 注意:不同地区的习惯可能有所不同。在汉语中『』、「」分别为双…

【玩转 JS 函数式编程_008】3.1.2 JavaScript 函数式编程筑基之:箭头函数——一种更流行的写法

文章目录 3.1.2 箭头函数——更流行的方式 Arrow functions - the modern way1. 返回值 Returning values2. this 值的处理 Handling the this value3. arguments 的处理 Working with arguments4. 单参数还是多参数? One argument or many? 写在前面 故天将降大任…

基于SpringBoot+Vue+MySQL的在线学习交流平台

系统展示 用户前台界面 管理员后台界面 系统背景 随着互联网技术的飞速发展,在线学习已成为现代教育的重要组成部分。传统的面对面教学方式已无法满足广大学习者的需求,特别是在时间、地点上受限的学习者。因此,构建一个基于SpringBoot、Vue.…