深度卷积生成对抗网络(DCGAN)实战:从原理到代码实现
立即解锁
发布时间: 2025-09-05 01:57:06 阅读量: 2 订阅数: 23 AIGC 

### 深度卷积生成对抗网络(DCGAN)实战:从原理到代码实现
#### 1. GAN 原理概述
生成对抗网络(GAN)由判别器网络和生成器网络组成。判别器网络的优化方式与二元分类器类似,使用二元交叉熵函数。其目标是正确地将真实图像分类为真实,将虚假图像分类为虚假。而生成器网络的目标则与之相反,其损失函数在数学上表示为 -log(D(G(x))),其中 x 是输入到生成器模型 G 的随机噪声,G(x) 是生成器模型生成的虚假图像,D(G(x)) 是判别器模型 D 的输出概率,即图像为真实的概率。当判别器认为生成的虚假图像是真实的时,生成器的损失最小,本质上生成器是在尝试欺骗判别器。
在训练过程中,这两个损失函数会交替进行反向传播。在每次训练迭代中,首先冻结判别器,通过生成器损失的梯度反向传播来优化生成器网络的参数;然后冻结调整后的生成器,通过判别器损失的梯度反向传播来优化判别器。这就是所谓的联合优化,在原始的 GAN 论文中也被称为二人极小极大博弈。
#### 2. DCGAN 生成器和判别器架构
DCGAN 的生成器和判别器都是纯卷积模型。
- **生成器架构**:
1. 首先,将大小为 64 的随机噪声输入向量进行重塑,并通过线性层投影到 128 个大小为 16x16 的特征图。
2. 接着,使用最近邻上采样策略将 16x16 的特征图转换为 32x32 的特征图。
3. 之后是一个 3x3 核大小、输出 128 个特征图的 2D 卷积层。
4. 再将 128 个 32x32 的特征图进一步上采样到 64x64 大小的特征图,随后经过两个 2D 卷积层,最终生成大小为 64x64 的虚假 RGB 图像。
- **判别器架构**:
判别器架构中每个卷积层的步长为 2,有助于减小空间维度,同时深度(即特征图的数量)不断增加。这是一个基于经典 CNN 的二元分类架构,用于区分真实图像和生成的虚假图像。
#### 3. 使用 PyTorch 构建 DCGAN 模型
##### 3.1 定义生成器
以下是使用 PyTorch 定义生成器的步骤和代码:
1. **导入所需库**:
```python
import os
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torch.autograd import Variable
import torchvision.transforms as transforms
from torchvision.utils import save_image
from torchvision import datasets
```
2. **指定模型超参数**:
```python
num_eps=10
bsize=32
lrate=0.001
lat_dimension=64
image_sz=64
chnls=1
logging_intv=200
```
3. **定义生成器模型对象**:
```python
class GANGenerator(nn.Module):
def __init__(self):
super(GANGenerator, self).__init__()
self.inp_sz = image_sz // 4
self.lin = nn.Sequential(nn.Linear(
lat_dimension, 128 * self.inp_sz ** 2))
self.bn1 = nn.BatchNorm2d(128)
self.up1 = nn.Upsample(scale_factor=2)
self.cn1 = nn.Conv2d(128, 128, 3, stride=1, padding=1)
self.bn2 = nn.BatchNorm2d(128, 0.8)
self.rl1 = nn.LeakyReLU(0.2, inplace=True)
self.up2 = nn.Upsample(scale_factor=2)
self.cn2 = nn.Conv2d(128, 64, 3, stride=1, padding=1)
self.bn3 = nn.BatchNorm2d(64, 0.8)
self.rl2 = nn.LeakyReLU(0.2, inplace=True)
self.cn3 = nn.Conv2d(64, chnls, 3, stride=1, padding=1)
self.act = nn.Tanh()
def forward(self, x):
x = self.lin(x)
x = x.view(x.shape[0], 128, self.inp_sz, self.inp_sz)
x = self.bn1(x)
x = self.up1(x)
x = self.cn1(x)
x = self.bn2(x)
x = self.rl1(x)
x = self.up2(x)
x = self.cn2(x)
x = self.bn3(x)
x = self.rl2(x)
x = self.cn3(x)
out = self.act(x)
return out
```
这里使用逐层显式定义而不是 `nn.Sequential` 方法,是为了在出现问题时更易于调试模型。代码中还包含了图中未提及的批量归一化和 Leaky ReLU 层。
**FAQ**:
- **为什么使用批量归一化?**:批量归一化用于线性或卷积层之后,既可以加快训练过程,又可以降低对初始网络权重的敏感性。
- **为什么使用 Leaky ReLU?**:ReLU 对于负值输入可能会丢失所有信息,而斜率为 0.2 的 Leaky ReLU 会给输入的负信息赋予 20% 的权重,有助于防止 GAN 模型训练过程中出现梯度消失的问题。
##### 3.2 定义判别器
以下是使用 PyTorch 定义判别器的步骤和代码:
1. **定义判别器模型**:
```python
class GANDiscriminator(nn.Module):
def __init__(self):
super(GANDiscriminator, self).__init__()
def disc_module(ip_chnls, op_chnls, bnorm=True):
mod = [nn.Conv2d(ip_chnls, op_chnls
```
0
0
复制全文
相关推荐







