- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
- 🚀 参考文章:GAN入门|第二篇:人脸图像生成(DCGAN)
目录
一、课题背景和开发环境
深度卷积对抗网络(Deep Convolutional Generative Adversarial Networks,简称DCGAN)是一种深度学习模型,由生成器(Generator)和判别器(Discriminator)两个神经网络组成。DCGAN结合了卷积神经网络(Convolutional Neural Networks,简称CNN)和生成对抗网络(Generative Adversarial Networks,简称GAN)的思想,用于生成逼真的图像。
📌第G2周:人脸图像生成(DCGAN)📌
- Python 3.8.12
- numpy==1.21.5 -> 1.24.3
- pytorch==1.8.1+cu111
📌 基础任务:
- 深度卷积对抗网络(DCGAN)的基本原理
- 学习本文DCGAN代码,并跑通代码
- 了解DCGAN与GAN的区别
🎈进阶任务:
- 调用训练好的模型生成新图像
二、理论基础
1. DCGAN原理
深度卷积对抗网络(Deep Convolutional Generative Adversarial Networks, DCGAN)是生成对抗网络的一种模型改进,其将卷积运算的思想引入到生成式模型当中来做无监督的训练,利用卷积网络强大的特征提取能力来提高生成网络的学习效果。DCGAN模型有以下特点:
-
- 判别器模型使用卷积步长取代了空间池化,生成器模型中使用反卷积操作扩大数据维度。
-
- 除了生成器模型的输出层和判别器模型的输入层,在整个对抗网络的其它层上都使用了Batch Normalization,原因是Batch Normalization可以稳定学习,有助于优化初始化参数值不良而导致的训练问题。
-
- 整个网络去除了全连接层,直接使用卷积层连接生成器和判别器的输入层以及输出层。
-
- 在生成器的输出层使用Tanh激活函数以控制输出范围,而在其它层中均使用了ReLU激活函数;在判别器上使用Leaky ReLU激活函数。
上图所示了一种常见的 DCGAN 结构。主要包含了左边生成网络(Generator)和右边判别网络(Discriminator),其各有四个转置卷积层(DeConv)和四个卷积层(Conv)。其中 4 ∗ 4 ∗ 512 4*4*512 4∗4∗512 代表这一层共有512个大小为 4 ∗ 4 4*4 4∗4 的特征图,括号内的BN和ReLU分别表示在卷积层之前和之后分别使用了批归一化和修正线性单元激活两种处理方法。Tanh 和 LeakyReLU 分别表示双切正切激活和弱修正线性激活。
- 在生成器的输出层使用Tanh激活函数以控制输出范围,而在其它层中均使用了ReLU激活函数;在判别器上使用Leaky ReLU激活函数。
2. 训练原理
如下图所示,DCGAN 模型主要包括了一个生成网络 G 和一个判别网络 D,生成网络 G 负责生成图像,它接受一个随机的噪声z,通过该噪声生成图像,将生成的图像记为 G ( z ) G(z) G(z) ,判别网络D负责判别一张图像是否为真实的,它的输入是x,代表一张图像,输出 D ( x ) D(x) D(x) 表示x为真实图像的概率。
实际上判别网络D是对数据的来源进行一个判别:究竟这个数据是来自真实的数据分布 P d ( x ) P_{d(x)} Pd(x) 判别为“1”),还是来自于一个生成网络G所产生的一个数据分布 P g ( z ) P_{g(z)} Pg(z) (判别为“0”)。所以在整个训练过程中,生成网络G的目标是生成可以以假乱真的图像 G ( z ) G(z) G(z) ,当判别网络D无法区分,即 D ( G ( z ) ) = 0.5 D(G(z)) = 0.5 D(G(z))=0.5 时,便得到了一个生成网络G用来生成图像扩充数据集。
三、前期准备
1. 导入第三方库
import os
import random
import argparse
import numpy as np
import torch
import torch.nn as nn
import torch.nn.parallel
import torch.optim as optim
import torch.utils.data
from torch.autograd import Variable
from torch.utils.data import DataLoader
from torchvision import datasets as dset
import torchvision.utils as vutils
from torchvision.utils import save_image
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from IPython.display import HTML
manualSeed = 999 # 随机种子
print("Random Seed: ", manualSeed)
random.seed(manualSeed)
torch.manual_seed(manualSeed)
torch.use_deterministic_algorithms(True) # Needed for reproducible results
2. 设置超参数
# 超参数配置
dataroot = "./data/FaceSample/" # 数据路径
batch_size = 128 # 训练过程中的批次大小
n_epochs = 5 # 训练的总轮数
img_size = 64 # 图像的尺寸(宽度和高度)
nz = 100 # z潜在向量的大小(生成器输入的尺寸)
ngf = 64 # 生成器中的特征图大小
ndf = 64 # 判别器中的特征图大小
beta1 = 0.5 # Adam优化器的Beta1超参数
lr = 0.0002 # 学习率
3. 导入数据
这段代码的作用是准备用于训练的图像数据。它首先使用 ImageFolder
类创建一个数据集对象,该对象表示从文件夹中加载的图像数据集。然后,通过 transforms.Compose
组合了一系列图像变换操作来对图像进行预处理,包括调整大小、中心裁剪、转换为张量以及标准化。接着,使用 DataLoader
类创建一个数据加载器对象,该对象可以在训练过程中按批次加载数据,并可以选择是否打乱数据集以及使用多线程加载数据。代码还选择设备(GPU或CPU)来运行代码,并打印所选择的设备。最后,代码通过数据加载器获取一批训练图像,并使用Matplotlib库绘制这些图像。
# 创建数据集
dataset = dset.ImageFolder(root=dataroot,
transform=transforms.Compose([
transforms.Resize(img_size), # 调整图像大小
transforms.CenterCrop(img_size