做淘宝客个人网站,谁有推荐的网址,wordpress news主题,网站建设公司圣辉友联Pytorch从零开始实战——生成对抗网络入门
本系列来源于365天深度学习训练营
原作者K同学 文章目录 Pytorch从零开始实战——生成对抗网络入门环境准备模型定义开始训练总结 环境准备
本文基于Jupyter notebook#xff0c;使用Python3.8#xff0c;Pytorch1.8cpu#xf…Pytorch从零开始实战——生成对抗网络入门
本系列来源于365天深度学习训练营
原作者K同学 文章目录 Pytorch从零开始实战——生成对抗网络入门环境准备模型定义开始训练总结 环境准备
本文基于Jupyter notebook使用Python3.8Pytorch1.8cpu本次实验目的是了解生成对抗网络。
生成对抗网络GAN是一种深度学习模型。GAN由两个主要组成部分组成生成器和判别器。这两个部分通过对抗的方式共同学习使得生成器能够生成逼真的数据而判别器能够区分真实数据和生成的数据。
生成器的任务是生成与真实数据相似的样本。它接收一个随机噪声向量然后通过深度神经网络将这个随机噪声转换为具体的数据样本。在图像生成的场景中生成器通常将随机噪声映射为图像。生成器的目标是欺骗判别器使其无法区分生成的样本和真实的样本。生成器的训练目标是最小化生成的样本与真实样本之间的差异。
判别器的任务是对给定的样本进行分类判断它是来自真实数据集还是由生成器生成的。它接收真实样本和生成样本然后通过深度神经网络输出一个概率表示输入样本是真实样本的概率。判别器的目标是准确地分类样本使其能够正确地区分真实数据和生成的数据。判别器的训练目标是最大化正确分类的概率。
导入相关包。
import torch
import torch.nn as nn
import argparse
import os
import numpy as np
import torchvision.transforms as transforms
from torchvision.utils import save_image
from torch.utils.data import DataLoader
from torchvision import datasets
from torch.autograd import Variable创建文件夹分别保存训练过程中的图像、模型参数和数据集。
os.makedirs(./images/, exist_okTrue) # 训练过程中图片效果
os.makedirs(./save/, exist_okTrue) # 训练完成时模型保存位置
os.makedirs(./datasets/, exist_okTrue) # 数据集位置设置超参数。 b1、b2为Adam优化算法的参数其中b1是梯度的一阶矩估计的衰减系数b2是梯度的二阶矩估计的衰减系数。 latent_dim表示生成器输入的随机噪声向量的维度。这个噪声向量用于生成器产生新样本。 sample_interval表示在训练过程中每隔多少个batch保存一次生成器生成的样本图像以便观察生成效果。
epochs 20
batch_size 64
lr 0.0002
b1 0.5
b2 0.999
latent_dim100
img_size28
channels1
sample_interval500设定图像尺寸并检查cuda本次使用的设备没有cuda。
img_shape (channels, img_size, img_size) # (1, 28, 28)
img_area np.prod(img_shape) # 784## 设置cuda
cuda True if torch.cuda.is_available() else False
print(cuda) # False本次使用GAN来生成手写数字首先下载mnist数据集。
mnist datasets.MNIST(root./datasets/, trainTrue, downloadTrue,transformtransforms.Compose([transforms.Resize(img_size),transforms.ToTensor(), transforms.Normalize([0.5], [0.5])]))使用dataloader划分批次与打乱。
dataloader DataLoader(mnist,batch_sizebatch_size,shuffleTrue,
)len(dataloader) # 938模型定义
首先定义鉴别器模型代码中LeakyReLU是ReLU激活函数的变体它引入了一个小的负斜率在负输入值范围内而不是将它们直接置零。这个斜率通常是一个小的正数例如0.01。
class Discriminator(nn.Module):def __init__(self):super(Discriminator, self).__init__()self.model nn.Sequential(nn.Linear(img_area, 512), nn.LeakyReLU(0.2, inplaceTrue), nn.Linear(512, 256), nn.LeakyReLU(0.2, inplaceTrue), nn.Linear(256, 1), nn.Sigmoid(), )def forward(self, img):img_flat img.view(img.size(0), -1) validity self.model(img_flat) return validity # 返回的是一个[0, 1]间的概率定义生成器模型用于输出图像。
class Generator(nn.Module):def __init__(self):super(Generator, self).__init__()def block(in_feat, out_feat, normalizeTrue): layers [nn.Linear(in_feat, out_feat)] if normalize:layers.append(nn.BatchNorm1d(out_feat, 0.8)) layers.append(nn.LeakyReLU(0.2, inplaceTrue)) return layersself.model nn.Sequential(*block(latent_dim, 128, normalizeFalse), *block(128, 256), *block(256, 512), *block(512, 1024), nn.Linear(1024, img_area), nn.Tanh() )def forward(self, z): imgs self.model(z) imgs imgs.view(imgs.size(0), *img_shape) # reshape成(64, 1, 28, 28)return imgs # 输出为64张大小为(1, 28, 28)的图像开始训练
创建生成器、判别器对象。
generator Generator()
discriminator Discriminator()定义损失函数。这个其实就是二分类的交叉熵损失。
criterion torch.nn.BCELoss()定义优化函数。
optimizer_G torch.optim.Adam(generator.parameters(), lrlr, betas(b1, b2))
optimizer_D torch.optim.Adam(discriminator.parameters(), lrlr, betas(b1, b2))开始训练实现GAN训练过程其中生成器和判别器交替训练通过对抗过程使得生成器生成逼真的图像而判别器不断提高对真实和生成图像的判别能力。
for epoch in range(epochs): # epoch:50for i, (imgs, _) in enumerate(dataloader): # imgs:(64, 1, 28, 28) _:label(64)imgs imgs.view(imgs.size(0), -1) # 将图片展开为28*28784 imgs:(64, 784)real_img Variable(imgs) # 将tensor变成Variable放入计算图中tensor变成variable之后才能进行反向传播求梯度real_label Variable(torch.ones(imgs.size(0), 1)) ## 定义真实的图片label为1fake_label Variable(torch.zeros(imgs.size(0), 1)) ## 定义假的图片的label为0real_out discriminator(real_img) # 将真实图片放入判别器中loss_real_D criterion(real_out, real_label) # 得到真实图片的lossreal_scores real_out # 得到真实图片的判别值输出的值越接近1越好## 计算假的图片的损失## detach(): 从当前计算图中分离下来避免梯度传到G因为G不用更新z Variable(torch.randn(imgs.size(0), latent_dim)) ## 随机生成一些噪声, 大小为(128, 100)fake_img generator(z).detach() ## 随机噪声放入生成网络中生成一张假的图片。fake_out discriminator(fake_img) ## 判别器判断假的图片loss_fake_D criterion(fake_out, fake_label) ## 得到假的图片的lossfake_scores fake_out## 损失函数和优化loss_D loss_real_D loss_fake_D # 损失包括判真损失和判假损失optimizer_D.zero_grad() # 在反向传播之前先将梯度归0loss_D.backward() # 将误差反向传播optimizer_D.step() # 更新参数z Variable(torch.randn(imgs.size(0), latent_dim)) ## 得到随机噪声fake_img generator(z) ## 随机噪声输入到生成器中得到一副假的图片output discriminator(fake_img) ## 经过判别器得到的结果## 损失函数和优化loss_G criterion(output, real_label) ## 得到的假的图片与真实的图片的label的lossoptimizer_G.zero_grad() ## 梯度归0loss_G.backward() ## 进行反向传播optimizer_G.step() ## step()一般用在反向传播后面,用于更新生成网络的参数## 打印训练过程中的日志## item():取出单元素张量的元素值并返回该值保持原元素类型不变if (i 1) % 100 0:print([Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f] [D real: %f] [D fake: %f]% (epoch, epochs, i, len(dataloader), loss_D.item(), loss_G.item(), real_scores.data.mean(), fake_scores.data.mean()))## 保存训练过程中的图像batches_done epoch * len(dataloader) iif batches_done % sample_interval 0:save_image(fake_img.data[:25], ./images/%d.png % batches_done, nrow5, normalizeTrue) 保存模型。
torch.save(generator.state_dict(), ./save/generator.pth)
torch.save(discriminator.state_dict(), ./save/discriminator.pth)查看最初的噪声图像。 查看后面生成的图像。
总结
对于GAN生成器的任务是从随机噪声生成逼真的数据样本判别器的任务是对给定的数据样本进行分类判断其是真实数据还是由生成器生成的。生成器和判别器通过对抗的方式进行训练。在每个训练迭代中生成器试图生成逼真的样本以欺骗判别器而判别器努力提高自己的能力以正确地区分真实和生成的样本。这种对抗训练的动态平衡最终导致生成器生成高质量、逼真的样本。
总之GAN实现了在无监督情况下学习数据分布的能力被广泛用于生成逼真图像、视频等数据。