DCGAN 浅析与实现
DCGAN1 主要提出了一种基于卷积网络的结构,使GAN的训练更为稳定高效。
结构简述
- 将卷积网络中的所有pooling层替换为微步卷积层,其优势在于让机器学习下采样的方式。
- 在初生成器output layer和鉴别器input layer以外都应用Batch Normalization来保持每层拥有一定的梯度。
- 取消全链接层,将生成器的输入reshape称 4 × 4 4\times4 4×4的张量输入卷积网络。
- 在生成器除最后一层外使用ReLU,最后一层使用Tanh。
- 在鉴别器中每一层使用LeakyReLU。
训练细节
- 将图像预处理为 [ − 1 , 1 ] [-1,1] [−1,1]的标量
- mini-bath size为128
- 所有的权重初始化为均值为0,标准差为0.02的正态分布
- LeakyReLU α = 0.2 \alpha=0.2 α=0.2
- learning rate为0.0002
- Adam β = ( 0.5 , 0.99 ) \beta=(0.5,0.99) β=(0.5,0.99)
实现方式
想用复杂一点的数据集,但colab的磁盘太小了…
代码参考DCGAN原理分析与pytorch实现与DCGAN Demo。
生成器与鉴别器的结构实际为DCGAN。
生成器
class Generator(nn.Module):
def __init__(self, z_dim):
super().__init__()
self.z_dim = z_dim
net = []
channels_in = [self.z_dim, 512, 256, 128, 64]
channels_out = [512, 256, 128, 64, 1]
active = ["R", "R", "R", "R", "tanh"]
stride = [1, 2, 2, 2, 2]
padding = [0, 1, 1, 1, 1]
for i in range(len(channels_in)):
net.append(nn.ConvTranspose2d(in_channels=channels_in[i], out_channels=channels_out[i],
kernel_size=4, stride=stride[i], padding=padding[i], bias=False))
if active[i] == "R":
net.append(nn.BatchNorm2d(num_features=channels_out[i]))
net.append(nn.ReLU())
elif active[i] == "tanh":
net.append(nn.Tanh())
self.generator = nn.Sequential(*net)
def forward(self, x):
out = self.generator(x)
return out
由于训练MNIST,输出的通道数改为1。
鉴别器
class Discriminator(nn.Module):
def __init__(self):
super().__init__()
net = []
channels_in = [1, 64, 128, 256, 512]
channels_out = [64, 128, 256, 512, 1]
padding = [1, 1, 1, 1, 0]
active = ["LR", "LR", "LR", "LR", "sigmoid"]
for i in range(len(channels_in)):
net.append(nn.Conv2d(in_channels=channels_in[i], out_channels=channels_out[i],
kernel_size=4, stride=2, padding=padding[i], bias=False))
if i == 0:
net.append(nn.LeakyReLU(0.2))
elif active[i] == "LR":
net.append(nn.BatchNorm2d(num_features=channels_out[i]))
net.append(nn.LeakyReLU(0.2))
elif active[i] == "sigmoid":
net.append(nn.Sigmoid())
self.discriminator = nn.Sequential(*net)
def forward(self, x):
data = x
out = self.discriminator(data)
out = out.view(data.size(0), -1)
return out
效果![效果](https://i-blog.csdnimg.cn/blog_migrate/ae142270d822c7f291f7c703ad26bf0d.png#pic_center)
经过30了个epoch,但由于训练集本身简单,并不能看出与其他模型的区别。