PaddlePaddle 飞桨实现GAN生成对抗网络生成MINIST手写数字图像
1 | import paddle |
1 | train_reader = paddle.vision.datasets.MNIST(mode='train') |
1 | 训练集样本数: 60000 |
1 | # 噪声维度 |
1 | image,label =next(mnist_generator()) |

测试一下噪声
1 | z_tmp = next(z_generator()) |
1 | 一个batch噪声z的形状: [128, 100, 1, 1] |
GAN 网络
GAN 性能的提升从生成器 G 和判别器 D 进行左右互搏、交替完善的过程得到的。所以其 G 网络和 D 网络的能力应该设计得相近,复杂度也差不多。这个项目中的生成器,采用了两个全链接层接两组上采样和转置卷积层,将输入的噪声 Z 逐渐转化为 1×28×28 的单通道图片输出。
生成器结构:
判别器的结构正好相反,先通过两组卷积和池化层将输入的图片转化为越来越小的特征图,再经过两层全链接层,输出图片是真是假的二分类结果。
判别器结构:
1 | import paddle |
1 | paddle.Model(G('G')).summary((-1,100)) |
1 | --------------------------------------------------------------------------- |
1 | paddle.Model(D('D')).summary((-1,1,28,28)) |
1 | --------------------------------------------------------------------------- |
1 | z_tmp = next(z_generator()) |
1 | 生成器G生成图片数据的形状: (128, 1, 28, 28) |

1 | import matplotlib.pyplot as plt |

网络训练
网络的训练优化目标就是如下公式:
公式出自 Goodfellow 在 2014 年发表的论文 Generative Adversarial Nets。
上式中等号左边的部分:
等式的右边其实就是将等号左边的交叉商损失公式展开,并写成概率分布的期望形式。详细的推导请参见原论文《Generative Adversarial Nets》。
下面是训练模型的代码,有详细的注释。大致过程是:先用真图片训练一次判别器 d 的参数,再用生成器 g 生成的假图片训练一次判别器 d 的参数,最后用判别器 d 判断生成器 g 生成的假图片的概率值更新一次生成器 g 的参数,即每轮训练先训练两次判别器 d,再训练一次生成器 g,使得判别器 d 的能力始终稍稍高于生成器 g 一些。
1 | for i, real_image in enumerate(mnist_generator()): |
1 | [128, 28, 28] 128 |
训练代码
1 | import paddle.nn.functional as F |
训练输出:
1 | epoch = 0 , batch = 99 , real_d_loss = [0.63881606] , fake_d_loss = [0.43077955] g_loss = [1.1314435] |
训练过程中的生成图片(每100步保存一次):























生成测试
1 | z = next(z_generator()) |

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 龙火火的个人博客!