《深度学习实战》第5集:生成对抗网络(GAN)与图像生成

《深度学习实战》第5集:生成对抗网络(GAN)与图像生成

生成对抗网络(GAN,Generative Adversarial Network)是深度学习领域的一项革命性技术,它通过生成器和判别器的对抗过程,能够生成逼真的图像、音频甚至视频。本集将带你深入了解 GAN 的基本原理,并通过实战项目使用 DCGAN 生成手写数字图像。我们还将探讨改进版 GAN 和前沿技术 Diffusion Models。


1. GAN 的基本原理

1.1 生成器与判别器的对抗过程

GAN 的核心思想是"对抗训练"。它由两个神经网络组成:

  • 生成器(Generator):负责生成假数据,试图欺骗判别器。
  • 判别器(Discriminator):负责区分真实数据和生成器生成的假数据。
训练流程
  1. 生成器生成假数据
    • 生成器从随机噪声中生成假数据。
  2. 判别器评估数据
    • 判别器接收真实数据和生成器生成的假数据,输出一个概率值,表示数据的真实性。
  3. 更新模型参数
    • 判别器的目标是提高识别能力,生成器的目标是让判别器无法区分真假数据。
    • 通过交替优化生成器和判别器的损失函数,完成对抗训练。

1.2 数学表达

GAN 的目标是最小化生成器的损失,同时最大化判别器的损失:
min ⁡ G max ⁡ D V ( D , G ) = E x ∼ p data ( x ) [ log ⁡ D ( x ) ] + E z ∼ p z ( z ) [ log ⁡ ( 1 − D ( G ( z ) ) ) ] \min_G \max_D V(D, G) = \mathbb{E}{x \sim p{\text{data}}(x)}[\log D(x)] + \mathbb{E}_{z \sim p_z(z)}[\log(1 - D(G(z)))] GminDmaxV(D,G)=Ex∼pdata(x)[logD(x)]+Ez∼pz(z)[log(1−D(G(z)))]

  • (D(x)):判别器对真实数据的判断。
  • (G(z)):生成器从噪声 (z) 生成的数据。

2. 改进版 GAN

虽然原始 GAN 的思想非常强大,但在实际应用中存在训练不稳定的问题。以下是一些改进版 GAN:

2.1 DCGAN(Deep Convolutional GAN)

  • 特点
    • 使用卷积神经网络(CNN)替代全连接层。
    • 引入批量归一化(Batch Normalization)和 Leaky ReLU 激活函数。
  • 应用场景
    • 图像生成、超分辨率重建。

2.2 CycleGAN

  • 特点
    • 实现无配对数据的图像到图像翻译。
    • 例如:将马变成斑马、将照片变成油画。
  • 应用场景
    • 风格迁移、跨域图像转换。

2.3 StyleGAN

  • 特点
    • 提供对生成图像的细粒度控制(如风格、细节)。
    • 能够生成高分辨率、逼真的人脸图像。
  • 应用场景
    • 游戏角色设计、虚拟形象生成。

3. 实战项目:使用 DCGAN 生成手写数字图像

我们将使用 DCGAN 生成 MNIST 数据集中的手写数字图像。

以下3.1到3.4代码可分段按顺序在jupyter notebook中运行,也可以拼成一个文件运行。

Python程序环境 python3.11.5。

torch GPU版本(CPU也可运行,训练实践较长些):

bash 复制代码
Name: torch
Version: 2.5.1+cu121
Summary: Tensors and Dynamic neural networks in Python with strong GPU acceleration
Home-page: https://pytorch.org/
Author: PyTorch Team
Author-email: packages@pytorch.org
License: BSD-3-Clause
Location: d:\python_projects\jupyter_demo\lib\site-packages
Requires: filelock, fsspec, jinja2, networkx, sympy, typing-extensions
Required-by: torchaudio, torchvision

3.1 数据准备

python 复制代码
import torch
from torchvision import datasets, transforms

# 加载 MNIST 数据集
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize([0.5], [0.5])  # 归一化到 [-1, 1]
])
train_data = datasets.MNIST(root="./data", train=True, transform=transform, download=True)
train_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)

3.2 定义生成器和判别器

python 复制代码
import torch.nn as nn

# 生成器
class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()
        self.model = nn.Sequential(
            nn.ConvTranspose2d(100, 256, 4, 1, 0), nn.BatchNorm2d(256), nn.ReLU(),
            nn.ConvTranspose2d(256, 128, 4, 2, 1), nn.BatchNorm2d(128), nn.ReLU(),
            nn.ConvTranspose2d(128, 1, 4, 2, 1), nn.Tanh()
        )
    def forward(self, x):
        return self.model(x)

# 判别器
class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.model = nn.Sequential(
            nn.Conv2d(1, 128, 4, 2, 1), nn.LeakyReLU(0.2),
            nn.Conv2d(128, 256, 4, 2, 1), nn.BatchNorm2d(256), nn.LeakyReLU(0.2),
            nn.Conv2d(256, 1, 4, 1, 0), nn.Sigmoid()
        )
    def forward(self, x):
        output = self.model(x)
        # 正确地将输出展平为 [batch_size, 1]
        return output.view(x.size(0), -1).mean(dim=1, keepdim=True)

3.3 训练模型

python 复制代码
import torch.optim as optim

# 初始化模型
generator = Generator()
discriminator = Discriminator()

# 将模型移动到GPU(如果可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
generator = generator.to(device)
discriminator = discriminator.to(device)

# 定义优化器
g_optimizer = optim.Adam(generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
d_optimizer = optim.Adam(discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))

# 损失函数
criterion = nn.BCELoss()

# 训练循环
for epoch in range(20):  # 训练 20 个 epoch
    for real_images, _ in train_loader:
        real_images = real_images.to(device)
        batch_size = real_images.size(0)

        # 真实标签和假标签
        real_labels = torch.ones(batch_size, 1).to(device)
        fake_labels = torch.zeros(batch_size, 1).to(device)

        # 训练判别器
        noise = torch.randn(batch_size, 100, 1, 1).to(device)
        fake_images = generator(noise)
        d_loss_real = criterion(discriminator(real_images), real_labels)
        d_loss_fake = criterion(discriminator(fake_images.detach()), fake_labels)
        d_loss = d_loss_real + d_loss_fake
        d_optimizer.zero_grad()
        d_loss.backward()
        d_optimizer.step()

        # 训练生成器
        g_loss = criterion(discriminator(fake_images), real_labels)
        g_optimizer.zero_grad()
        g_loss.backward()
        g_optimizer.step()

    print(f"Epoch [{epoch+1}/20], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}")

3.4 生成图像样本

训练完成后,我们可以用生成器生成手写数字图像:

python 复制代码
import matplotlib.pyplot as plt

# 生成图像
noise = torch.randn(16, 100, 1, 1).to(device)
fake_images = generator(noise).detach().cpu()

# 可视化生成图像
fig, axes = plt.subplots(4, 4, figsize=(8, 8))
for i, ax in enumerate(axes.flat):
    ax.imshow(fake_images[i].squeeze(), cmap="gray")
    ax.axis("off")
plt.show()

程序运行输出结果:

bash 复制代码
Epoch [1/20], d_loss: 0.0006, g_loss: 8.2671
Epoch [2/20], d_loss: 0.0002, g_loss: 9.6156
Epoch [3/20], d_loss: 0.0001, g_loss: 10.3770
Epoch [4/20], d_loss: 0.0000, g_loss: 11.2099
Epoch [5/20], d_loss: 0.0000, g_loss: 11.6237
Epoch [6/20], d_loss: 0.0000, g_loss: 12.3599
Epoch [7/20], d_loss: 0.0000, g_loss: 12.9177
Epoch [8/20], d_loss: 0.0000, g_loss: 13.5181
Epoch [9/20], d_loss: 0.0000, g_loss: 13.8931
Epoch [10/20], d_loss: 0.0000, g_loss: 14.1882
Epoch [11/20], d_loss: 0.0000, g_loss: 14.8480
Epoch [12/20], d_loss: 0.0000, g_loss: 15.3970
Epoch [13/20], d_loss: 0.0000, g_loss: 15.7757
Epoch [14/20], d_loss: 0.0000, g_loss: 16.6581
Epoch [15/20], d_loss: 0.0000, g_loss: 17.0566
Epoch [16/20], d_loss: 0.0000, g_loss: 17.4911
Epoch [17/20], d_loss: 0.0000, g_loss: 18.0315
Epoch [18/20], d_loss: 0.0000, g_loss: 18.5592
Epoch [19/20], d_loss: 0.0000, g_loss: 19.1872
Epoch [20/20], d_loss: 0.0000, g_loss: 19.6127

4. 前沿关联:Diffusion Models 的兴起

近年来,扩散模型(Diffusion Models)在图像生成领域表现出色,逐渐取代了 GAN 的地位。

4.1 Diffusion Models 的优势

  • 高质量生成:生成的图像更加逼真。
  • 训练稳定性:相比 GAN 更容易训练。
  • 多样性:支持更广泛的生成任务(如文本到图像、图像修复)。

4.2 典型模型

  • DALL·E 2:文本到图像生成。
  • Stable Diffusion:开源扩散模型,广泛应用于艺术创作。

总结

GAN 是生成模型的重要里程碑,而改进版 GAN(如 DCGAN、CycleGAN、StyleGAN)进一步拓展了其应用范围。通过实战项目,我们学会了如何使用 DCGAN 生成手写数字图像。同时,我们也探讨了扩散模型的兴起及其在图像生成中的优势。

希望这篇博客能帮助你更好地理解 GAN 的原理与应用!如果需要进一步扩展或优化,请随时告诉我! 😊

相关推荐
arbboter1 小时前
【AI深度学习基础】NumPy完全指南入门篇:核心功能与工程实践(含完整代码)
人工智能·深度学习·性能优化·数据分析·numpy·多维数组·科学计算
有Li1 小时前
将空间信息融入深度学习参数估计中及其在扩散加权磁共振成像(MRI)体素内不相干运动模型中的应用|文献速递-医学影像人工智能进展
人工智能·深度学习
liruiqiang053 小时前
神经网络 - 激活函数(Maxout 单元)
人工智能·深度学习·神经网络·机器学习
HXQ_晴天3 小时前
神经网络中感受野的概念和作用
深度学习·神经网络·计算机视觉
化作星辰4 小时前
神经网络中的Adam
人工智能·深度学习·神经网络
做怪小疯子4 小时前
论文阅读:A comprehensive survey on model compression and acceleration
论文阅读·人工智能·深度学习
PeterClerk6 小时前
深度学习-自监督学习总结
图像处理·人工智能·pytorch·python·深度学习·aigc·自监督学习
snowful world7 小时前
动手学深度学习:多层感知机
人工智能·深度学习
不懂就要问8 小时前
GPT1 与 GPT2 的异同
人工智能·深度学习·自然语言处理·nlp·transformer