Progressive Growing GAN (PGGAN) 分阶段学习 - 生成模型 GAN 网络 | 莫烦Python

Progressive Growing GAN (PGGAN) 分阶段学习

作者: 莫烦 编辑: 莫烦 2021-04-01

学习资料:

怎么了

GAN 在小尺寸上图片(<60px)的生成任务已经可以达到相对比较好的效果了,但是继续扩大尺寸,比如到到1024px,生成的难度是指数型增加的, 因为可以尝试的排列组合数是指数型增高。训练难度的提高,将会出现几个问题:

  1. 训练时间的指数型加长
  2. 训练效果的降低
  3. 有可能压根训练不出来,或只能训练出模糊的图片

所以 Progressive Growing GAN (PGGAN) 打算从训练方法上革新。用一句话描述 PGGAN 的做法: 分阶段,从易到难,从简单的小任务到大任务过度型学习。

这次我在 mnist 上做实验后,明显可以看出有三个训练阶段。从低像素(7*7)开始训练,到 14*14, 最后到 28*28 的最终 mnist 尺寸。

progress mnist

如果从动态训练的角度来看,mnist 训练的整个过程也可以在下面的动图中看到,我训练了8个epoch,效果已经不错了。

results

怎么训练

思路其实很简单,就是分阶段训练。具体呢,也就是论文中这张截图显示的:

  1. Generator 生成 4*4 的图片,Discriminator 识别 4*4 的图片
  2. 生成 8*8, 识别 8*8
  3. 生成 16*16, 识别 16*16
  4. ...
  5. 生成 1024*1024, 识别 1024*1024

growing

让生成器和判别器的能力是逐层提升的,充分证明中国的依据俗话 一口吃不成一个胖子,所以我们小口小口来,一个阶梯一个阶梯上。这样拆解了任务, 单个的小任务更容易实现。但是在分阶段学习的时候还有一些细节要考虑。

fade

比如在上图中,就是针对每次增加难度,要进入下一阶段训练的时候,我们有些小动作可以帮我们无缝顺滑进入下一阶段。 这个小动作就是图上 (b) 这个阶段做的事情。本质上 (b) 阶段做的是一件润滑剂的事情。事情是这样的,进入下一阶段, 是一种硬切换好呢,还是一种软切换好,有点像是在对比阶梯还是残疾人坡的区别。

disables

在 (b) 这部分,生成器给出的图片,综合了

  1. 原本网络的图片
  2. 新添加层生成的图片

因为在一开始新增一层的阶段,这层新增的层因为随机初始化,效果肯定没有原始被训练的层好,所以我们给一个相对低的权重,不让训练突然话锋一转,转得过于厉害。 另外,我们再接一条管道直接连通原本的训练过的层和生成图片,并给一个稍微大点的权重。在训练过程中在缓慢调整这个权重,让权重分配越来越重视新增的层。 对于判别器,同理也是一样的处理过程。

这就是 PGGAN 最核心的工作了。

秀代码

如果想直接看全部代码, 请点击这里去往我的github.

PGGAN看似简单,但是在工程实践的时候还是挺纠结的,因为要涉及到网络结构的变化,而 Tensorflow 又是一种静态图计算,所以还有一些些兼容性问题。 代码量是偏多的。我在下面只会体现出 PGGAN 的最核心代码。def train(gan, ds, epoch): 的代码和 class PGGAN(keras.Model): 的代码并没有和其他GAN有太大的差别。 但是因为 Generator 和 Discriminator 变动比较大,我们就分开创建这两个类吧。

在 Generator 和 Discriminator 中,我们分别都要创建每个阶段要使用到的层,而有些层经历了训练阶段后,还要被丢弃,比如在上一节中提到的 (b) 部分的润滑剂

所以每个阶段都有它的配套服务员,中间有一些服务员我介绍一下:

  • self.b[x]_rgb 每个阶段,作为生成器的最后一层 rgb 颜色的转换
  • self.b[x] 卷积或者是反卷积
  • self.p[x] 润滑剂,原图的直接映射

我觉得最让我头疼的就是写 call() 这个功能了,因为每个阶段要运算的东西都不一样,写起来挺麻烦的,而且我也感觉这种写法一点都不优雅,应该还有更好的写法, 如果你想到更好的写法,请及时在后面留言讨论~

简单来说,我这里 call() 做前向后,会先判断目前进行到第几阶段了,然后根据不同阶段,有不同的输出策略。 比如要使用哪个阶段的配套服务员就由 current_layer 这个参数控制。有比如 inputs 中的 p 就来控制我的润滑剂力度。 相应的,Discriminator 的设计也是这样的,因为代码实在有点多,如果你想深入研究 PGGAN, 欢迎直接看我Github全部代码。

最后再来回顾一下分阶段的训练结果,有没有感觉这是一种简单,但是写起来很麻烦的方法呀~

res

总结

PGGAN 用一种我们人类常用的分阶段学习方法,来让GAN生成相对比较高清的图片。这是一种非常有效的方法,在后续有很多生成高清图片的论文中都沿用了这套理论。


降低知识传递的门槛

莫烦很常从互联网上学习知识,开源分享的人是我学习的榜样。 他们的行为也改变了我对教育的态度: 降低知识传递的门槛免费 奉献我的所学正是受这种态度的影响。 通过 【赞助莫烦】 能让我感到认同,我也更有理由坚持下去。