Train post-processing with GAN | 使用生成对抗网络训练后处理

1 Post-Processing To Image to Image Translation 后处理到图片翻译

这次想做的是如何用神经网络来后处理。后处理是游戏中常见的一种图像效果,核心任务也就是把原始图片通过一些图片处理的手段,转化成另一种更好看的效果,常见的比如Bloom, LUT等等。而深度学习界最近出现的一个很热的话题就是图片翻译,如何从一张图片转化成另一张图片?
其实两者都是图片到图片的任务,但也有很大不同
  • 通用性,后处理一般是精心设计的工程方法,适用于特定的任务;但是神经网络基本可以算是通用方法了,就目前来看几乎可以做任意domain图片的转化
  • 性能,后处理对实时性要求很高,内存占用也不能太大。而神经网络没有个几GB的显存或者TPU就别想训练了。
本文这里是希望能否让通用性的神经网络以实时性能运行起来?
下图是训练的效果

可以看演示的效果,在网络比较浅的情况下,30fps完全可以保证,不过可以接近目标效果的色调,但是很难重现其笔触。
本例笔者制作了监督学习的训练集,制作方法是:
  • 截取原始场景大量截图
  • 使用Photoshop动作批量进行风格化处理
  • 使用这些成对数据训练pix2pix
  • 训练好的模型在Unity中作为后处理实时运算。

笔者将代码放在Github上:NeuralNetworkPostProcessing

2 Image to Image Translation 图片翻译

近年来深度学习的一个常见问题,如何从一张图片生成另一张图片?

NST

比较早相关的是一篇Neural Style Transfer的文章(Gatys, 2016),核心原理可以理解成,找到原始图片与目标图片的平均值,这个距离值用神经网络激活层的一个函数定义,并通过神经网络反向传播梯度求解,
下图是其基本原理,风格图片与生成图片的激活层的格拉姆矩阵即L-style,目标图片与生成图片某个激活层的方差,即L-content,目的是用L-style + L-content作为目标函数梯度下降求解

GAN

15年Goodfellow提出的Generative Adversarial Network(GAN)这几年的影响爆炸式增长,他是一个类似左右互搏的神经网络,Generator,Discriminator两个神经网络分别用于造假和鉴别假货,共同进步。具体原理不再细讲,推荐台湾大学李宏毅老师的lecture

Pix2Pix

GAN最开始被用来从随机向量(latent space vector)生成图片,它衍生出了一个叫Pix2Pix的东西。
与原始GAN不同主要在于Generator变成了张量到张量。它是监督学习的方法,需要提供一些成对数据的训练集,训练之后就可以进行图像翻译的任务了。
之后衍生出了Pix2PixHD。要点在于Pix2Pix可以生成的图片很小,一般是256*256的,而Pix2PixHD可以生成2048*1024的街景图片。
keijiro把Pix2Pix的sketch2cat模型搬到了Unity,可以实时画猫
另外一个Pix2PixCity的项目,程序式生成城市简模,利用pix2pix街景的训练模型生成城市的视频

CycleGan/DualGan/DiscoGan

后来又衍生出了CycleGan/DualGan/DiscoGan,与PIX2PIX不同的是,这三个非常相似的结构都是非监督学习的,也就是给它非成对的图片数据,它也可以进行图片翻译的任务。
核心思路是通过两个成对的Generator/Discriminator进行训练,从图片域A到图片域B,从图片域B到图片域A
可以将图片理解为一个数据概率分布,这就比较好理解NST和GAN的区别。NST目的是寻找两个数据分布之间的中间值,而GAN的目标是实现两个数据分布之间的转化。在NST中,目标数据分布之间的距离是一个人工构造的函数,即激活层的一些方差格拉姆矩阵等运算。而GAN中,数据分布的距离是Discriminator拟合出来的,理论上讲可以到达一些理论距离比如JSDivergence等等。

3 Implementation 实现

模型的训练直接使用了KerasGAN中pix2pix的源码,不同的是原始pix2pix的Generator非常复杂,为了提高运行时性能,训练时减少了网络的深度,比如这样一个网络在运行时是基本没问题的,但是效果只能说勉强可以接受。
训练数据生成时考虑了深度通道,因此与keras-GAN上不太一样,笔者这里一个成对数据长成
运行时为了减少依赖,完全采用ComputeShader实现神经网络卷积等运算。参考了keijiro的实现,比如卷积运算,强调memory coalesce的思想,每个threadgroup读取数据到cache中,同步数据后再下一步运算

也进行了一些改进,keijiro实现中在线程数很少的情况下表现比较差,因为一个warp就32个线程没法再少了,只能多用点cache,多几个texel同时做卷积了。

4 Future 未来

当前来看硬件还是不太足以支持任意的实时图像翻译,理想中未来的风格化渲染工作流程完全可以是:
  • 标准光照模型进行渲染
  • 使用目标风格的图片进行非监督训练(Cycle Gan) 或者 原画在标准光照模型上进行绘制,制作训练集
  • 通过训练集训练神经网络
  • 客户端部署训练好的神经网络
甚至有可能完全使用神经网络做渲染,目前pix2pix的输入标记图片很像材质id图,但是实时渲染不仅有这个信息,还有深度法线等很多数据。因此有可能
  • 通过游戏中的画面训练一个模型,输入材质id,法线等,生成渲染效果
  • 游戏制作中只需要制作简模即可
  • 运行时只渲染建模的id,法线等,直接通过神经网络生成渲染效果。
这样的话实时渲染的光照模型hack也就一点用没有了,毕竟训练集可以完全离线渲染,只要有神经网络就好了。
但是前提是显卡的计算量极端充裕,因为这相比于后处理可能需要更加复杂的模型。想要实时运行起来就目前来看还很遥远。

参考资料

Neural Style Tranfer有很多文章,这是其中之一
Cousera上AndrewNg讲的ConvoluitonNeuralNetwork,浅显易懂非常适合入门

发表评论

电子邮件地址不会被公开。 必填项已用*标注